/[svn]/linuxsampler/trunk/src/engines/gig/Stream.h
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/gig/Stream.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 385 - (hide annotations) (download) (as text)
Thu Feb 17 02:53:45 2005 UTC (19 years, 2 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 8162 byte(s)
* lscpserver: we now only use one instrument loader thread; commands for
  loading instruments in the background wait in a queue to be processed one
  by one to avoid possible race conditions and to improve I/O efficiency
* fixed possible race condition while streaming with multiple disk threads
  by using an own decompression buffer for each disk thread
* libgig: fixed some memory leaks caused by non virtual base constructors

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 385 * Copyright (C) 2005 Christian Schoenebeck *
7 schoenebeck 53 * *
8     * This program is free software; you can redistribute it and/or modify *
9     * it under the terms of the GNU General Public License as published by *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program is distributed in the hope that it will be useful, *
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16     * GNU General Public License for more details. *
17     * *
18     * You should have received a copy of the GNU General Public License *
19     * along with this program; if not, write to the Free Software *
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #ifndef __LS_GIG_STREAM_H__
25     #define __LS_GIG_STREAM_H__
26    
27     #include "../../common/global.h"
28    
29     #if DEBUG_HEADERS
30     # warning Stream.h included
31     #endif // DEBUG_HEADERS
32    
33     #include "../../common/RingBuffer.h"
34     #include "../../lib/fileloader/libgig/gig.h"
35    
36     namespace LinuxSampler { namespace gig {
37    
38     class Stream {
39     public:
40     // Member Types
41     typedef uint32_t OrderID_t;
42     typedef uint32_t Handle; ///< unique identifier of a relationship between one stream and a consumer (Voice)
43     enum state_t { ///< streams go through severe cyclic state transition (unused->active->end->unused->...)
44     state_unused, ///< stream is not in use, thus can still be launched
45     state_active, ///< stream provides data in it's buffer to be read and hasn't reached the end yet (this is the usual case)
46     state_end ///< stream end reached but still providing data in it's buffer to be read (after the client read all remaining data from the stream buffer, state will change automatically to state_unused)
47     };
48     struct reference_t { ///< Defines the current relationship between the stream and a client (voice).
49     OrderID_t OrderID; ///< Unique identifier that identifies the creation order of a stream requested by a voice.
50     Handle hStream; ///< Unique identifier of the relationship between stream and client.
51     state_t State; ///< Current state of the stream that will be pretended to the client (the actual state of the stream might differ though, because the stream might already be in use by another client).
52     Stream* pStream; ///< Points to the assigned and activated stream or is NULL if the disk thread hasn't launched a stream yet.
53     };
54    
55     // Methods
56 schoenebeck 385 Stream( ::gig::buffer_t* pDecompressionBuffer, uint BufferSize, uint BufferWrapElements);
57 schoenebeck 53 ~Stream();
58     int ReadAhead(unsigned long SampleCount);
59     void WriteSilence(unsigned long SilenceSampleWords);
60    
61     inline int GetReadSpace() {
62 schoenebeck 323 return (pRingBuffer && State != state_unused) ? pRingBuffer->read_space() : 0;
63 schoenebeck 53 }
64    
65     inline int GetWriteSpace() {
66     return (pRingBuffer && State == state_active) ? pRingBuffer->write_space() : 0;
67     }
68    
69     inline int GetWriteSpaceToEnd() {
70     return (pRingBuffer && State == state_active) ? pRingBuffer->write_space_to_end_with_wrap() : 0;
71     }
72    
73     // adjusts the write space to avoid buffer boundaries which would lead to the wrap space
74     // within the buffer (needed for interpolation) getting filled only partially
75     // for more infos see the docs in ringbuffer.h at adjust_write_space_to_avoid_boundary()
76     inline int AdjustWriteSpaceToAvoidBoundary(int cnt, int capped_cnt) {
77     return pRingBuffer->adjust_write_space_to_avoid_boundary(cnt, capped_cnt);
78     }
79    
80     inline sample_t* GetReadPointer() {
81     return pRingBuffer->get_read_ptr();
82     }
83    
84     // gets the current read_ptr within the ringbuffer
85     inline sample_t* GetReadPtr(void) {
86     return pRingBuffer->get_read_ptr();
87     }
88    
89     inline void IncrementReadPos(uint Count) {
90     uint leftspace = pRingBuffer->read_space();
91     pRingBuffer->increment_read_ptr(Min(Count, leftspace));
92     if (State == state_end && Count >= leftspace) {
93     Reset(); // quit relation between consumer (voice) and stream and reset stream right after
94     }
95     }
96    
97     // Static Method
98     inline static uint GetUnusedStreams() { return UnusedStreams; }
99     protected:
100     // Methods
101     void Launch(Stream::Handle hStream, reference_t* pExportReference, ::gig::Sample* pSample, unsigned long SampleOffset, bool DoLoop);
102     inline void Kill() { pExportReference = NULL; Reset(); } ///< Will be called by disk thread after a 'deletion' command from the audio thread (within the voice class)
103     inline Stream::Handle GetHandle() { return hThis; }
104     inline Stream::state_t GetState() { return State; }
105     friend class DiskThread; // only the disk thread should be able to launch and most important kill a disk stream to avoid race conditions
106     private:
107     // Attributes
108     reference_t* pExportReference;
109     state_t State;
110     Stream::Handle hThis;
111     unsigned long SampleOffset;
112     ::gig::Sample* pSample;
113     ::gig::playback_state_t PlaybackState;
114     RingBuffer<sample_t>* pRingBuffer;
115     bool DoLoop;
116 schoenebeck 385 ::gig::buffer_t* pDecompressionBuffer;
117 schoenebeck 53
118     // Static Attributes
119     static uint UnusedStreams; //< Reflects how many stream objects of all stream instances are currently not in use.
120 senkov 333 static uint TotalStreams; //< Reflects how many stream objects currently exist.
121 schoenebeck 53
122     // Methods
123     inline void Reset() {
124     SampleOffset = 0;
125     pSample = NULL;
126     PlaybackState.position = 0;
127     PlaybackState.reverse = false;
128     hThis = 0;
129     pRingBuffer->init(); // reset ringbuffer
130     if (State != state_unused) {
131     // we can't do 'SetPos(state_unused)' here, due to possible race conditions)
132     if (pExportReference) {
133     pExportReference->State = state_unused;
134     pExportReference = NULL;
135     }
136     State = state_unused;
137     UnusedStreams++;
138     }
139     }
140     inline void SetState(state_t State) {
141     if (pExportReference) pExportReference->State = State;
142     this->State = State;
143     }
144     inline long Min(long a, long b) { return (a < b) ? a : b; }
145     };
146    
147     }} // namespace LinuxSampler::gig
148    
149     #endif // __LS_GIG_STREAM_H__

  ViewVC Help
Powered by ViewVC