1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-12 14:47:43 +02:00

Bugs 1592 and 2639

Sound activated record is now decoupled from the input meter.
This commit is contained in:
Leland Lucius 2021-01-22 23:43:01 -06:00
parent 50e803a974
commit f509d9c0bd
2 changed files with 51 additions and 42 deletions

View File

@ -1550,7 +1550,7 @@ int AudioIO::StartStream(const TransportTracks &tracks,
// gPrefs->Write(wxT("/AudioIO/SilenceLevel"), silenceLevelDB); // gPrefs->Write(wxT("/AudioIO/SilenceLevel"), silenceLevelDB);
// gPrefs->Flush(); // gPrefs->Flush();
} }
mSilenceLevel = (silenceLevelDB + dBRange)/(double)dBRange; // meter goes -dBRange dB -> 0dB mSilenceLevel = DB_TO_LINEAR(silenceLevelDB); // meter goes -dBRange dB -> 0dB
// Clamp pre-roll so we don't play before time 0 // Clamp pre-roll so we don't play before time 0
const auto preRoll = std::max(0.0, std::min(t0, options.preRoll)); const auto preRoll = std::max(0.0, std::min(t0, options.preRoll));
@ -3756,18 +3756,25 @@ void AudioIoCallback::ComputeMidiTimings(
// to run in the main GUI thread after the next event loop iteration. // to run in the main GUI thread after the next event loop iteration.
// That's important, because Pause() updates GUI, such as status bar, // That's important, because Pause() updates GUI, such as status bar,
// and that should NOT happen in this audio non-gui thread. // and that should NOT happen in this audio non-gui thread.
void AudioIoCallback::CheckSoundActivatedRecordingLevel( const void *inputBuffer ) void AudioIoCallback::CheckSoundActivatedRecordingLevel(
float *inputSamples,
unsigned long framesPerBuffer
)
{ {
if( !inputBuffer)
return;
// Quick returns if next to nothing to do. // Quick returns if next to nothing to do.
if( !mPauseRec ) if( !mPauseRec )
return; return;
if( !mInputMeter )
return; float maxPeak = 0.;
for( unsigned long i = 0, cnt = framesPerBuffer * mNumCaptureChannels; i < cnt; ++i ) {
bool bShouldBePaused = mInputMeter->GetMaxPeak() < mSilenceLevel; float sample = fabs(*(inputSamples++));
if( bShouldBePaused != IsPaused()) if (sample > maxPeak) {
maxPeak = sample;
}
}
bool bShouldBePaused = maxPeak < mSilenceLevel;
if( bShouldBePaused != IsPaused() )
{ {
auto pListener = GetListener(); auto pListener = GetListener();
if ( pListener ) if ( pListener )
@ -3775,7 +3782,6 @@ void AudioIoCallback::CheckSoundActivatedRecordingLevel( const void *inputBuffer
} }
} }
// A function to apply the requested gain, fading up or down from the // A function to apply the requested gain, fading up or down from the
// most recently applied gain. // most recently applied gain.
void AudioIoCallback::AddToOutputChannel( unsigned int chan, void AudioIoCallback::AddToOutputChannel( unsigned int chan,
@ -4234,8 +4240,7 @@ void AudioIoCallback::DoPlaythrough(
/* Send data to recording VU meter if applicable */ /* Send data to recording VU meter if applicable */
// Also computes rms // Also computes rms
void AudioIoCallback::SendVuInputMeterData( void AudioIoCallback::SendVuInputMeterData(
float *tempFloats, float *inputSamples,
const void *inputBuffer,
unsigned long framesPerBuffer unsigned long framesPerBuffer
) )
{ {
@ -4245,8 +4250,6 @@ void AudioIoCallback::SendVuInputMeterData(
return; return;
if( mInputMeter->IsMeterDisabled()) if( mInputMeter->IsMeterDisabled())
return; return;
if( !inputBuffer)
return;
// get here if meters are actually live , and being updated // get here if meters are actually live , and being updated
/* It's critical that we don't update the meters while StopStream is /* It's critical that we don't update the meters while StopStream is
@ -4261,18 +4264,9 @@ void AudioIoCallback::SendVuInputMeterData(
//TODO use atomics instead. //TODO use atomics instead.
mUpdatingMeters = true; mUpdatingMeters = true;
if (mUpdateMeters) { if (mUpdateMeters) {
if (mCaptureFormat == floatSample)
mInputMeter->UpdateDisplay(numCaptureChannels, mInputMeter->UpdateDisplay(numCaptureChannels,
framesPerBuffer, framesPerBuffer,
(float *)inputBuffer); inputSamples);
else {
CopySamples((samplePtr)inputBuffer, mCaptureFormat,
(samplePtr)tempFloats, floatSample,
framesPerBuffer * numCaptureChannels);
mInputMeter->UpdateDisplay(numCaptureChannels,
framesPerBuffer,
tempFloats);
}
} }
mUpdatingMeters = false; mUpdatingMeters = false;
} }
@ -4432,22 +4426,35 @@ int AudioIoCallback::AudioCallback(const void *inputBuffer, void *outputBuffer,
(float *)outputBuffer; (float *)outputBuffer;
// ----- END of MEMORY ALLOCATIONS ------------------------------------------ // ----- END of MEMORY ALLOCATIONS ------------------------------------------
if (inputBuffer && numCaptureChannels) {
float *inputSamples;
SendVuInputMeterData( if (mCaptureFormat == floatSample) {
tempFloats, inputSamples = (float *) inputBuffer;
inputBuffer, }
framesPerBuffer); else {
CopySamples((samplePtr)inputBuffer, mCaptureFormat,
(samplePtr)tempFloats, floatSample,
framesPerBuffer * numCaptureChannels);
inputSamples = tempFloats;
}
SendVuInputMeterData(
inputSamples,
framesPerBuffer);
// This function may queue up a pause or resume.
// TODO this is a bit dodgy as it toggles the Pause, and
// relies on an idle event to have handled that, so could
// queue up multiple toggle requests and so do nothing.
// Eventually it will sort itself out by random luck, but
// the net effect is a delay in starting/stopping sound activated
// recording.
CheckSoundActivatedRecordingLevel(
inputSamples,
framesPerBuffer);
}
// This function may queue up a pause or resume.
// TODO this is a bit dodgy as it toggles the Pause, and
// relies on an idle event to have handled that, so could
// queue up multiple toggle requests and so do nothing.
// Eventually it will sort itself out by random luck, but
// the net effect is a delay in starting/stopping sound activated
// recording.
CheckSoundActivatedRecordingLevel(
inputBuffer);
// Even when paused, we do playthrough. // Even when paused, we do playthrough.
// Initialise output buffer to zero or to playthrough data. // Initialise output buffer to zero or to playthrough data.
// Initialise output meter values. // Initialise output meter values.

View File

@ -308,7 +308,10 @@ public:
void ComputeMidiTimings( void ComputeMidiTimings(
const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackTimeInfo *timeInfo,
unsigned long framesPerBuffer); unsigned long framesPerBuffer);
void CheckSoundActivatedRecordingLevel(const void *inputBuffer); void CheckSoundActivatedRecordingLevel(
float *inputSamples,
unsigned long framesPerBuffer
);
void AddToOutputChannel( unsigned int chan, void AddToOutputChannel( unsigned int chan,
float * outputMeterFloats, float * outputMeterFloats,
float * outputFloats, float * outputFloats,
@ -339,8 +342,7 @@ public:
float *outputMeterFloats float *outputMeterFloats
); );
void SendVuInputMeterData( void SendVuInputMeterData(
float *tempFloats, float *inputSamples,
const void *inputBuffer,
unsigned long framesPerBuffer unsigned long framesPerBuffer
); );
void SendVuOutputMeterData( void SendVuOutputMeterData(