Mercurial > hg > svapp
comparison audio/AudioCallbackPlaySource.cpp @ 544:c4391f6c7484 bqresample
Start pruning other resampler logic than bqresample
author | Chris Cannam |
---|---|
date | Mon, 05 Dec 2016 16:56:36 +0000 |
parents | 167d37937436 |
children | c732251237b1 |
comparison
equal
deleted
inserted
replaced
542:167d37937436 | 544:c4391f6c7484 |
---|---|
76 m_stretchMono(false), | 76 m_stretchMono(false), |
77 m_stretcherInputCount(0), | 77 m_stretcherInputCount(0), |
78 m_stretcherInputs(0), | 78 m_stretcherInputs(0), |
79 m_stretcherInputSizes(0), | 79 m_stretcherInputSizes(0), |
80 m_fillThread(0), | 80 m_fillThread(0), |
81 m_converter(0) | 81 m_resampler(0) |
82 { | 82 { |
83 m_viewManager->setAudioPlaySource(this); | 83 m_viewManager->setAudioPlaySource(this); |
84 | 84 |
85 connect(m_viewManager, SIGNAL(selectionChanged()), | 85 connect(m_viewManager, SIGNAL(selectionChanged()), |
86 this, SLOT(selectionChanged())); | 86 this, SLOT(selectionChanged())); |
228 } else { | 228 } else { |
229 if (willPlay) clearRingBuffers(true); | 229 if (willPlay) clearRingBuffers(true); |
230 } | 230 } |
231 | 231 |
232 if (buffersChanged || srChanged) { | 232 if (buffersChanged || srChanged) { |
233 if (m_converter) { | 233 if (m_resampler) { |
234 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 234 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
235 cerr << "AudioCallbackPlaySource::addModel: Buffers or sample rate changed, deleting existing SR converter" << endl; | 235 cerr << "AudioCallbackPlaySource::addModel: Buffers or sample rate changed, deleting existing resampler" << endl; |
236 #endif | 236 #endif |
237 src_delete(m_converter); | 237 delete m_resampler; |
238 m_converter = 0; | 238 m_resampler = 0; |
239 } | 239 } |
240 } | 240 } |
241 | 241 |
242 rebuildRangeLists(); | 242 rebuildRangeLists(); |
243 | 243 |
244 m_mutex.unlock(); | 244 m_mutex.unlock(); |
245 | 245 |
246 initialiseConverter(); | 246 initialiseResampler(); |
247 | 247 |
248 m_audioGenerator->setTargetChannelCount(getTargetChannelCount()); | 248 m_audioGenerator->setTargetChannelCount(getTargetChannelCount()); |
249 | 249 |
250 if (!m_fillThread) { | 250 if (!m_fillThread) { |
251 m_fillThread = new FillThread(*this); | 251 m_fillThread = new FillThread(*this); |
299 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t))); | 299 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t))); |
300 | 300 |
301 m_models.erase(model); | 301 m_models.erase(model); |
302 | 302 |
303 if (m_models.empty()) { | 303 if (m_models.empty()) { |
304 if (m_converter) { | 304 if (m_resampler) { |
305 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 305 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
306 cerr << "AudioCallbackPlaySource::removeModel: No models left, deleting SR converter" << endl; | 306 cerr << "AudioCallbackPlaySource::removeModel: No models left, deleting resampler" << endl; |
307 #endif | 307 #endif |
308 src_delete(m_converter); | 308 delete m_resampler; |
309 m_converter = 0; | 309 m_resampler = 0; |
310 } | 310 } |
311 m_sourceSampleRate = 0; | 311 m_sourceSampleRate = 0; |
312 } | 312 } |
313 | 313 |
314 sv_frame_t lastEnd = 0; | 314 sv_frame_t lastEnd = 0; |
342 cout << "AudioCallbackPlaySource::clearModels()" << endl; | 342 cout << "AudioCallbackPlaySource::clearModels()" << endl; |
343 #endif | 343 #endif |
344 | 344 |
345 m_models.clear(); | 345 m_models.clear(); |
346 | 346 |
347 if (m_converter) { | 347 if (m_resampler) { |
348 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 348 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
349 cerr << "AudioCallbackPlaySource::clearModels: Deleting SR converter" << endl; | 349 cerr << "AudioCallbackPlaySource::clearModels: Deleting resampler" << endl; |
350 #endif | 350 #endif |
351 src_delete(m_converter); | 351 delete m_resampler; |
352 m_converter = 0; | 352 m_resampler = 0; |
353 } | 353 } |
354 | 354 |
355 m_lastModelEndFrame = 0; | 355 m_lastModelEndFrame = 0; |
356 | 356 |
357 m_sourceSampleRate = 0; | 357 m_sourceSampleRate = 0; |
470 cerr << "reset ring buffer for channel " << c << endl; | 470 cerr << "reset ring buffer for channel " << c << endl; |
471 #endif | 471 #endif |
472 if (rb) rb->reset(); | 472 if (rb) rb->reset(); |
473 } | 473 } |
474 } | 474 } |
475 if (m_converter) src_reset(m_converter); | 475 if (m_resampler) { |
476 m_resampler->reset(); | |
477 } | |
476 | 478 |
477 m_mutex.unlock(); | 479 m_mutex.unlock(); |
478 | 480 |
479 m_audioGenerator->reset(); | 481 m_audioGenerator->reset(); |
480 | 482 |
943 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr) | 945 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr) |
944 { | 946 { |
945 bool first = (m_targetSampleRate == 0); | 947 bool first = (m_targetSampleRate == 0); |
946 | 948 |
947 m_targetSampleRate = sr; | 949 m_targetSampleRate = sr; |
948 initialiseConverter(); | 950 initialiseResampler(); |
949 | 951 |
950 if (first && (m_stretchRatio != 1.f)) { | 952 if (first && (m_stretchRatio != 1.f)) { |
951 // couldn't create a stretcher before because we had no sample | 953 // couldn't create a stretcher before because we had no sample |
952 // rate: make one now | 954 // rate: make one now |
953 setTimeStretch(m_stretchRatio); | 955 setTimeStretch(m_stretchRatio); |
954 } | 956 } |
955 } | 957 } |
956 | 958 |
957 void | 959 void |
958 AudioCallbackPlaySource::initialiseConverter() | 960 AudioCallbackPlaySource::initialiseResampler() |
959 { | 961 { |
960 m_mutex.lock(); | 962 m_mutex.lock(); |
961 | 963 |
962 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 964 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
963 cerr << "AudioCallbackPlaySource::initialiseConverter(): from " | 965 cerr << "AudioCallbackPlaySource::initialiseResampler(): from " |
964 << getSourceSampleRate() << " to " << getTargetSampleRate() << endl; | 966 << getSourceSampleRate() << " to " << getTargetSampleRate() << endl; |
965 #endif | 967 #endif |
966 | 968 |
967 if (m_converter) { | 969 if (m_resampler) { |
968 src_delete(m_converter); | 970 delete m_resampler; |
969 m_converter = 0; | 971 m_resampler = 0; |
970 } | 972 } |
971 | 973 |
972 if (getSourceSampleRate() != getTargetSampleRate()) { | 974 if (getSourceSampleRate() != getTargetSampleRate()) { |
973 | 975 |
974 int err = 0; | 976 m_resampler = new breakfastquay::Resampler |
975 | 977 (breakfastquay::Resampler::FastestTolerable, |
976 m_converter = src_new(SRC_SINC_FASTEST, getTargetChannelCount(), &err); | 978 getTargetChannelCount()); |
977 | 979 |
978 if (!m_converter) { | 980 m_mutex.unlock(); |
979 cerr << "AudioCallbackPlaySource::setModel: ERROR in creating samplerate converter: " | 981 |
980 << src_strerror(err) << endl; | 982 emit sampleRateMismatch(getSourceSampleRate(), |
981 | 983 getTargetSampleRate(), |
982 m_mutex.unlock(); | 984 true); |
983 | |
984 emit sampleRateMismatch(getSourceSampleRate(), | |
985 getTargetSampleRate(), | |
986 false); | |
987 } else { | |
988 | |
989 m_mutex.unlock(); | |
990 | |
991 emit sampleRateMismatch(getSourceSampleRate(), | |
992 getTargetSampleRate(), | |
993 true); | |
994 } | |
995 } else { | 985 } else { |
996 m_mutex.unlock(); | 986 m_mutex.unlock(); |
997 } | 987 } |
998 } | 988 } |
999 | 989 |
1363 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; | 1353 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; |
1364 #endif | 1354 #endif |
1365 return false; | 1355 return false; |
1366 } | 1356 } |
1367 | 1357 |
1358 // space is now the number of samples that can be written on each | |
1359 // channel's write ringbuffer | |
1360 | |
1368 sv_frame_t f = m_writeBufferFill; | 1361 sv_frame_t f = m_writeBufferFill; |
1369 | 1362 |
1370 bool readWriteEqual = (m_readBuffers == m_writeBuffers); | 1363 bool readWriteEqual = (m_readBuffers == m_writeBuffers); |
1371 | 1364 |
1372 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1365 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1400 bufferPtrCount = channels; | 1393 bufferPtrCount = channels; |
1401 } | 1394 } |
1402 | 1395 |
1403 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize(); | 1396 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize(); |
1404 | 1397 |
1405 if (resample && !m_converter) { | 1398 if (resample && !m_resampler) { |
1406 throw std::logic_error("Sample rates differ, but no converter available!"); | 1399 throw std::logic_error("Sample rates differ, but no resampler available!"); |
1407 } | 1400 } |
1408 | 1401 |
1409 if (resample && m_converter) { | 1402 if (resample && m_resampler) { |
1410 | 1403 |
1411 double ratio = | 1404 double ratio = |
1412 double(getTargetSampleRate()) / double(getSourceSampleRate()); | 1405 double(getTargetSampleRate()) / double(getSourceSampleRate()); |
1413 orig = sv_frame_t(double(orig) / ratio + 0.1); | 1406 orig = sv_frame_t(double(orig) / ratio + 0.1); |
1414 | 1407 |
1456 for (int i = 0; i < got; ++i) { | 1449 for (int i = 0; i < got; ++i) { |
1457 float sample = nonintlv[c * got + i]; | 1450 float sample = nonintlv[c * got + i]; |
1458 intlv[channels * i + c] = sample; | 1451 intlv[channels * i + c] = sample; |
1459 } | 1452 } |
1460 } | 1453 } |
1461 | 1454 |
1455 sv_frame_t toCopy = m_resampler->resampleInterleaved | |
1456 (intlv, srcout, got, ratio, false); | |
1457 | |
1462 SRC_DATA data; | 1458 SRC_DATA data; |
1463 data.data_in = intlv; | 1459 data.data_in = intlv; |
1464 data.data_out = srcout; | 1460 data.data_out = srcout; |
1465 data.input_frames = long(got); | 1461 data.input_frames = long(got); |
1466 data.output_frames = long(work); | 1462 data.output_frames = long(work); |