audioProcessor.cpp (2501B)
1 #include "audioProcessor.h" 2 3 #include <vector> 4 5 #include "esaiListenerToFile.h" 6 #include "dsp56kEmu/types.h" 7 8 #include "synthLib/wavWriter.h" 9 10 #include "virusLib/dspSingle.h" 11 12 AudioProcessor::AudioProcessor(uint32_t _samplerate, std::string _outputFilename, bool _terminateOnSilence, uint32_t _maxSamplecount, virusLib::DspSingle* _dsp1, virusLib::DspSingle* _dsp2) 13 : m_samplerate(_samplerate) 14 , m_outputFilname(std::move(_outputFilename)) 15 , m_terminateOnSilence(_terminateOnSilence) 16 , m_maxSampleCount(_maxSamplecount) 17 , m_dsp1(_dsp1) 18 , m_dsp2(_dsp2) 19 , m_writer(m_outputFilname, _samplerate, _terminateOnSilence) 20 { 21 m_outputBuffers.resize(2); 22 m_inputBuffers.resize(2); 23 } 24 25 AudioProcessor::~AudioProcessor() = default; 26 27 void AudioProcessor::processBlock(const uint32_t _blockSize) 28 { 29 if(m_outputBuffers[0].size() < _blockSize) 30 { 31 for(size_t i=0; i<m_outputBuffers.size(); ++i) 32 { 33 m_outputBuffers[i].resize(_blockSize); 34 m_inputBuffers[i].resize(_blockSize); 35 36 m_inputs[i] = m_inputBuffers[i].data(); 37 m_outputs[i] = m_outputBuffers[i].data(); 38 } 39 40 m_stereoOutput.reserve(m_outputBuffers.size() * 2); 41 } 42 43 const bool terminateOnSilence = m_terminateOnSilence; 44 45 auto sampleCount = static_cast<uint32_t>(m_inputBuffers[0].size()); 46 47 if(terminateOnSilence && m_writer.getSilenceDuration() >= m_samplerate * 5) 48 { 49 m_writer.setFinished(); 50 return; 51 } 52 53 if(m_maxSampleCount && m_processedSampleCount >= m_maxSampleCount) 54 { 55 m_writer.setFinished(); 56 return; 57 } 58 59 if(m_maxSampleCount && m_maxSampleCount - m_processedSampleCount < sampleCount) 60 { 61 sampleCount = m_maxSampleCount - m_processedSampleCount; 62 } 63 64 // reduce thread contention by waiting for the DSP to do some work first. 65 // If we don't, the ESAI writeTX function will lock/unlock a mutex to inform the waiting thread (us) 66 // that there is new audio data available. This costs more than 5% of performance 67 /* const auto& esai = m_dsp1->getPeriphX().getEsai(); 68 69 while(esai.getAudioInputs().size() > (_blockSize>>1)) 70 std::this_thread::yield(); 71 */ 72 m_dsp1->processAudio(m_inputs, m_outputs, sampleCount, _blockSize); 73 74 m_processedSampleCount += sampleCount; 75 76 { 77 m_writer.append([&](std::vector<dsp56k::TWord>& _dst) 78 { 79 _dst.reserve(m_stereoOutput.size() + sampleCount * 2); 80 81 for(size_t iSrc=0; iSrc<sampleCount; ++iSrc) 82 { 83 _dst.push_back(m_outputs[0][iSrc]); 84 _dst.push_back(m_outputs[1][iSrc]); 85 } 86 }); 87 } 88 89 if(m_maxSampleCount && m_processedSampleCount >= m_maxSampleCount) 90 m_writer.setFinished(); 91 }