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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3054 - (hide annotations) (download) (as text)
Thu Dec 15 12:47:45 2016 UTC (7 years, 5 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 8388 byte(s)
* Fixed numerous compiler warnings.
* Bumped version (2.0.0.svn32).

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

  ViewVC Help
Powered by ViewVC