void EngineMicrophone::process(CSAMPLE* pOut, const int iBufferSize) { // If talkover is enabled, then read into the output buffer. Otherwise, skip // the appropriate number of samples to throw them away. const CSAMPLE* sampleBuffer = m_sampleBuffer; // save pointer on stack double pregain = m_pPregain->get(); if (isTalkover() && sampleBuffer) { SampleUtil::copyWithGain(pOut, sampleBuffer, pregain, iBufferSize); m_sampleBuffer = NULL; } else { SampleUtil::clear(pOut, iBufferSize); } if (m_pEngineEffectsManager != NULL) { // Process effects enabled for this channel GroupFeatureState features; // This is out of date by a callback but some effects will want the RMS // volume. m_vuMeter.collectFeatures(&features); m_pEngineEffectsManager->process(getGroup(), pOut, iBufferSize, m_pSampleRate->get(), features); } // Update VU meter m_vuMeter.process(pOut, iBufferSize); }
void EngineMicrophone::process(const CSAMPLE* pInput, CSAMPLE* pOut, const int iBufferSize) { Q_UNUSED(pInput); // If talkover is enabled, then read into the output buffer. Otherwise, skip // the appropriate number of samples to throw them away. if (isTalkover()) { int samplesRead = m_sampleBuffer.read(pOut, iBufferSize); if (samplesRead < iBufferSize) { // Buffer underflow. There aren't getting samples fast enough. This // shouldn't happen since PortAudio should feed us samples just as fast // as we consume them, right? qWarning() << "ERROR: Buffer underflow in EngineMicrophone. Playing silence."; SampleUtil::clear(pOut + samplesRead, iBufferSize - samplesRead); } } else { SampleUtil::clear(pOut, iBufferSize); m_sampleBuffer.skip(iBufferSize); } if (m_pEngineEffectsManager != NULL) { // Process effects enabled for this channel GroupFeatureState features; // This is out of date by a callback but some effects will want the RMS // volume. m_vuMeter.collectFeatures(&features); m_pEngineEffectsManager->process(getGroup(), pOut, pOut, iBufferSize, features); } // Apply clipping m_clipping.process(pOut, pOut, iBufferSize); // Update VU meter m_vuMeter.process(pOut, pOut, iBufferSize); }
void EngineMicrophone::receiveBuffer(AudioInput input, const CSAMPLE* pBuffer, unsigned int nFrames) { Q_UNUSED(input); Q_UNUSED(nFrames); if (!isTalkover()) { m_sampleBuffer = NULL; return; } else { m_sampleBuffer = pBuffer; } }
void EngineMicrophone::receiveBuffer(AudioInput input, const CSAMPLE* pBuffer, unsigned int nFrames) { if (!isTalkover()) { return; } if (input.getType() != AudioPath::MICROPHONE) { // This is an error! qWarning() << "EngineMicrophone receieved an AudioInput for a non-Microphone type!"; return; } const unsigned int iChannels = input.getChannelGroup().getChannelCount(); // Check that the number of mono frames doesn't exceed MAX_BUFFER_LEN/2 // because thats our conversion buffer size. if (nFrames > MAX_BUFFER_LEN / iChannels) { qWarning() << "Dropping microphone samples because the input buffer is too large."; nFrames = MAX_BUFFER_LEN / iChannels; } const CSAMPLE* pWriteBuffer = NULL; unsigned int samplesToWrite = 0; if (iChannels == 1) { // Do mono -> stereo conversion. for (unsigned int i = 0; i < nFrames; ++i) { m_pConversionBuffer[i*2 + 0] = pBuffer[i]; m_pConversionBuffer[i*2 + 1] = pBuffer[i]; } pWriteBuffer = m_pConversionBuffer; samplesToWrite = nFrames * 2; } else if (iChannels == 2) { // Already in stereo. Use pBuffer as-is. pWriteBuffer = pBuffer; samplesToWrite = nFrames * iChannels; } else { qWarning() << "EngineMicrophone got greater than stereo input. Not currently handled."; } if (pWriteBuffer != NULL) { // TODO(rryan) do we need to verify the input is the one we asked for? // Oh well. unsigned int samplesWritten = m_sampleBuffer.write(pWriteBuffer, samplesToWrite); if (samplesWritten < samplesToWrite) { // Buffer overflow. We aren't processing samples fast enough. This // shouldn't happen since the mic spits out samples just as fast as they // come in, right? qWarning() << "ERROR: Buffer overflow in EngineMicrophone. Dropping samples on the floor."; } } }