Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.h @ 6:f3d777b693f7
* Introduce potentially-separate read and write ring buffers, so we can swap
in a new set when something changes -- thus allowing us to respond quickly
when something changes during playback, without losing the long buffers
* Some fixes for display & editing
author | Chris Cannam |
---|---|
date | Fri, 27 Jan 2006 18:04:07 +0000 |
parents | 5865094175ea |
children | 3a41ba527b4a |
comparison
equal
deleted
inserted
replaced
5:2edc0757ca75 | 6:f3d777b693f7 |
---|---|
176 | 176 |
177 protected: | 177 protected: |
178 ViewManager *m_viewManager; | 178 ViewManager *m_viewManager; |
179 AudioGenerator *m_audioGenerator; | 179 AudioGenerator *m_audioGenerator; |
180 | 180 |
181 class RingBufferVector : public std::vector<RingBuffer<float> *> { | |
182 public: | |
183 virtual ~RingBufferVector() { | |
184 while (!empty()) { | |
185 delete *begin(); | |
186 erase(begin()); | |
187 } | |
188 } | |
189 }; | |
190 | |
181 std::set<Model *> m_models; | 191 std::set<Model *> m_models; |
182 std::vector<RingBuffer<float> *> m_buffers; | 192 RingBufferVector *m_readBuffers; |
183 size_t m_bufferCount; | 193 RingBufferVector *m_writeBuffers; |
194 Scavenger<RingBufferVector> m_bufferScavenger; | |
195 size_t m_sourceChannelCount; | |
184 size_t m_blockSize; | 196 size_t m_blockSize; |
185 size_t m_sourceSampleRate; | 197 size_t m_sourceSampleRate; |
186 size_t m_targetSampleRate; | 198 size_t m_targetSampleRate; |
187 size_t m_playLatency; | 199 size_t m_playLatency; |
188 bool m_playing; | 200 bool m_playing; |
191 size_t m_lastModelEndFrame; | 203 size_t m_lastModelEndFrame; |
192 static const size_t m_ringBufferSize; | 204 static const size_t m_ringBufferSize; |
193 float m_outputLeft; | 205 float m_outputLeft; |
194 float m_outputRight; | 206 float m_outputRight; |
195 | 207 |
196 RingBuffer<float> &getRingBuffer(size_t c) { | 208 RingBuffer<float> *getWriteRingBuffer(size_t c) { |
197 return *m_buffers[c]; | 209 if (m_writeBuffers && c < m_writeBuffers->size()) { |
210 return (*m_writeBuffers)[c]; | |
211 } else { | |
212 return 0; | |
213 } | |
198 } | 214 } |
215 | |
216 RingBuffer<float> *getReadRingBuffer(size_t c) { | |
217 RingBufferVector *rb = m_readBuffers; | |
218 if (rb && c < rb->size()) { | |
219 return (*rb)[c]; | |
220 } else { | |
221 return 0; | |
222 } | |
223 } | |
224 | |
225 void clearRingBuffers(bool haveLock = false, size_t count = 0); | |
199 | 226 |
200 class TimeStretcherData | 227 class TimeStretcherData |
201 { | 228 { |
202 public: | 229 public: |
203 TimeStretcherData(size_t channels, size_t factor, size_t blockSize); | 230 TimeStretcherData(size_t channels, size_t factor, size_t blockSize); |
226 Scavenger<TimeStretcherData> m_timeStretcherScavenger; | 253 Scavenger<TimeStretcherData> m_timeStretcherScavenger; |
227 | 254 |
228 // Called from fill thread, m_playing true, mutex held | 255 // Called from fill thread, m_playing true, mutex held |
229 void fillBuffers(); | 256 void fillBuffers(); |
230 | 257 |
231 // Called from fillBuffers | 258 // Called from fillBuffers. Return the number of frames written, |
232 bool mixModels(size_t &frame, size_t count, float **buffers); | 259 // which will be count or fewer. Return in the frame argument the |
260 // new buffered frame position (which may be earlier than the | |
261 // frame argument passed in, in the case of looping). | |
262 size_t mixModels(size_t &frame, size_t count, float **buffers); | |
233 | 263 |
234 class AudioCallbackPlaySourceFillThread : public QThread | 264 class AudioCallbackPlaySourceFillThread : public QThread |
235 { | 265 { |
236 public: | 266 public: |
237 AudioCallbackPlaySourceFillThread(AudioCallbackPlaySource &source) : | 267 AudioCallbackPlaySourceFillThread(AudioCallbackPlaySource &source) : |