/[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 53 - (hide annotations) (download) (as text)
Mon Apr 26 17:15:51 2004 UTC (20 years ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 7881 byte(s)
* completely restructured source tree
* implemented multi channel support
* implemented instrument manager, which controls sharing of instruments
  between multiple sampler engines / sampler channels
* created abstract classes 'AudioOutputDevice' and 'MidiInputDevice' for
  convenient implementation of further audio output driver and MIDI input
  driver for LinuxSampler
* implemented following LSCP commands: 'SET CHANNEL MIDI INPUT TYPE',
  'LOAD ENGINE', 'GET CHANNELS', 'ADD CHANNEL', 'REMOVE CHANNEL',
  'SET CHANNEL AUDIO OUTPUT TYPE'
* temporarily removed all command line options
* LSCP server is now launched by default

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

  ViewVC Help
Powered by ViewVC