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) :