comparison audioio/AudioGenerator.cpp @ 5:2edc0757ca75

* Fixes to playback of short looped files, of synthesised content within looped sections, and a few other fixes
author Chris Cannam
date Thu, 26 Jan 2006 11:56:09 +0000
parents 5865094175ea
children 24b500216029
comparison
equal deleted inserted replaced
4:5865094175ea 5:2edc0757ca75
23 #include <iostream> 23 #include <iostream>
24 24
25 const size_t 25 const size_t
26 AudioGenerator::m_pluginBlockSize = 2048; 26 AudioGenerator::m_pluginBlockSize = 2048;
27 27
28 // #define DEBUG_AUDIO_GENERATOR 1 28 //#define DEBUG_AUDIO_GENERATOR 1
29 29
30 AudioGenerator::AudioGenerator(ViewManager *manager) : 30 AudioGenerator::AudioGenerator(ViewManager *manager) :
31 m_viewManager(manager), 31 m_viewManager(manager),
32 m_sourceSampleRate(0), 32 m_sourceSampleRate(0),
33 m_targetChannelCount(1) 33 m_targetChannelCount(1)
188 float **buffer, float gain, float pan, 188 float **buffer, float gain, float pan,
189 size_t fadeIn, size_t fadeOut) 189 size_t fadeIn, size_t fadeOut)
190 { 190 {
191 static float *channelBuffer = 0; 191 static float *channelBuffer = 0;
192 static size_t channelBufSiz = 0; 192 static size_t channelBufSiz = 0;
193 193
194 size_t totalFrames = frames + fadeIn/2 + fadeOut/2; 194 size_t totalFrames = frames + fadeIn/2 + fadeOut/2;
195 195
196 if (channelBufSiz < totalFrames) { 196 if (channelBufSiz < totalFrames) {
197 delete[] channelBuffer; 197 delete[] channelBuffer;
198 channelBuffer = new float[totalFrames]; 198 channelBuffer = new float[totalFrames];
201 201
202 size_t got = 0; 202 size_t got = 0;
203 203
204 for (size_t c = 0; c < m_targetChannelCount && c < dtvm->getChannelCount(); ++c) { 204 for (size_t c = 0; c < m_targetChannelCount && c < dtvm->getChannelCount(); ++c) {
205 205
206 got = dtvm->getValues 206 if (startFrame >= fadeIn/2) {
207 (c, startFrame - fadeIn/2, startFrame + frames + fadeOut/2, 207 got = dtvm->getValues
208 channelBuffer); 208 (c, startFrame - fadeIn/2, startFrame + frames + fadeOut/2,
209 channelBuffer);
210 } else {
211 size_t missing = fadeIn/2 - startFrame;
212 got = dtvm->getValues
213 (c, 0, startFrame + frames + fadeOut/2,
214 channelBuffer + missing);
215 }
209 216
210 for (size_t i = 0; i < fadeIn/2; ++i) { 217 for (size_t i = 0; i < fadeIn/2; ++i) {
211 float *back = buffer[c]; 218 float *back = buffer[c];
212 back -= fadeIn/2; 219 back -= fadeIn/2;
213 back[i] += (gain * channelBuffer[i] * i) / fadeIn; 220 back[i] += (gain * channelBuffer[i] * i) / fadeIn;
274 for (size_t i = 0; i < blocks; ++i) { 281 for (size_t i = 0; i < blocks; ++i) {
275 282
276 size_t reqStart = startFrame + i * m_pluginBlockSize; 283 size_t reqStart = startFrame + i * m_pluginBlockSize;
277 284
278 SparseOneDimensionalModel::PointList points = 285 SparseOneDimensionalModel::PointList points =
279 sodm->getPoints(reqStart > 0 ? reqStart + latency : reqStart, 286 sodm->getPoints(reqStart + latency,
280 reqStart + latency + m_pluginBlockSize); 287 reqStart + latency + m_pluginBlockSize);
281 288
282 RealTime blockTime = RealTime::frame2RealTime 289 RealTime blockTime = RealTime::frame2RealTime
283 (startFrame + i * m_pluginBlockSize, m_sourceSampleRate); 290 (startFrame + i * m_pluginBlockSize, m_sourceSampleRate);
284 291
285 for (SparseOneDimensionalModel::PointList::iterator pli = 292 for (SparseOneDimensionalModel::PointList::iterator pli =
286 points.begin(); pli != points.end(); ++pli) { 293 points.begin(); pli != points.end(); ++pli) {
287 294
288 size_t pliFrame = pli->frame; 295 size_t pliFrame = pli->frame;
296
289 if (pliFrame >= latency) pliFrame -= latency; 297 if (pliFrame >= latency) pliFrame -= latency;
298
299 if (pliFrame < reqStart ||
300 pliFrame >= reqStart + m_pluginBlockSize) continue;
290 301
291 while (noteOffs.begin() != noteOffs.end() && 302 while (noteOffs.begin() != noteOffs.end() &&
292 noteOffs.begin()->frame <= pliFrame) { 303 noteOffs.begin()->frame <= pliFrame) {
293 304
294 RealTime eventTime = RealTime::frame2RealTime 305 RealTime eventTime = RealTime::frame2RealTime
295 (noteOffs.begin()->frame, m_sourceSampleRate); 306 (noteOffs.begin()->frame, m_sourceSampleRate);
296 307
297 offEv.data.note.note = noteOffs.begin()->pitch; 308 offEv.data.note.note = noteOffs.begin()->pitch;
309
310 #ifdef DEBUG_AUDIO_GENERATOR
311 std::cerr << "mixModel [sparse]: sending note-off event at time " << eventTime << " frame " << noteOffs.begin()->frame << std::endl;
312 #endif
313
298 plugin->sendEvent(eventTime, &offEv); 314 plugin->sendEvent(eventTime, &offEv);
299 noteOffs.erase(noteOffs.begin()); 315 noteOffs.erase(noteOffs.begin());
300 } 316 }
301 317
302 RealTime eventTime = RealTime::frame2RealTime 318 RealTime eventTime = RealTime::frame2RealTime
321 337
322 RealTime eventTime = RealTime::frame2RealTime 338 RealTime eventTime = RealTime::frame2RealTime
323 (noteOffs.begin()->frame, m_sourceSampleRate); 339 (noteOffs.begin()->frame, m_sourceSampleRate);
324 340
325 offEv.data.note.note = noteOffs.begin()->pitch; 341 offEv.data.note.note = noteOffs.begin()->pitch;
342
343 #ifdef DEBUG_AUDIO_GENERATOR
344 std::cerr << "mixModel [sparse]: sending leftover note-off event at time " << eventTime << " frame " << noteOffs.begin()->frame << std::endl;
345 #endif
346
326 plugin->sendEvent(eventTime, &offEv); 347 plugin->sendEvent(eventTime, &offEv);
327 noteOffs.erase(noteOffs.begin()); 348 noteOffs.erase(noteOffs.begin());
328 } 349 }
329 350
330 plugin->run(blockTime); 351 plugin->run(blockTime);