Mercurial > hg > svapp
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); |