1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-24 06:10:09 +01:00

Realtime preview round 2

This changes the realtime preview from using 1 effect for all tracks
to an effect per track (logical track).  This should clear up the 
bad audio when more than one track (or a stereo track) is present.

An unfortunate side effect is that meter effects no longer work since
the one presented to the user is not the one doing the actual work.
Suggestions on how to remedy this are welcome.
This commit is contained in:
lllucius
2014-10-30 14:04:48 +00:00
parent a94bfed0cc
commit d50e9fee52
8 changed files with 249 additions and 136 deletions

View File

@@ -1358,6 +1358,13 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
}
} while(!bDone);
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
if (mNumPlaybackChannels > 0)
{
EffectManager::Get().RealtimeInitialize(&mPlaybackTracks);
}
#endif
#ifdef AUTOMATED_INPUT_LEVEL_ADJUSTMENT
AILASetStartTime();
#endif
@@ -1371,13 +1378,6 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
while( mAudioThreadShouldCallFillBuffersOnce == true )
wxMilliSleep( 50 );
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
if (mNumPlaybackChannels > 0)
{
EffectManager::Get().RealtimeInitialize(1, sampleRate);
}
#endif
#ifdef EXPERIMENTAL_MIDI_OUT
// if no playback, reset the midi time to zero to roughly sync
// with recording (or if recording is not going to happen, just
@@ -3497,10 +3497,22 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() )
numSolo++;
#endif
for( t = 0; t < numPlaybackTracks; t++)
int logicalCnt = 0;
int chanCnt = 0;
WaveTrack **chans = (WaveTrack **) alloca(numPlaybackChannels * sizeof(WaveTrack *));
float **tempBufs = (float **) alloca(numPlaybackChannels * sizeof(float *));
for (int c = 0; c < numPlaybackChannels; c++)
{
tempBufs[c] = (float *) alloca(framesPerBuffer * sizeof(float));
}
for (t = 0; t < numPlaybackTracks; t++)
{
WaveTrack *vt = gAudioIO->mPlaybackTracks[t];
chans[chanCnt] = vt;
if (linkFlag)
linkFlag = false;
else {
@@ -3521,15 +3533,21 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
#ifdef ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
// this is original code prior to r10680 -RBD
if (cut)
{
gAudioIO->mPlaybackBuffers[t]->Discard(framesPerBuffer);
continue;
}
{
gAudioIO->mPlaybackBuffers[t]->Discard(framesPerBuffer);
continue;
}
unsigned int len = (unsigned int)
gAudioIO->mPlaybackBuffers[t]->Get((samplePtr)tempFloats,
floatSample,
(int)framesPerBuffer);
int len = gAudioIO->mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt],
floatSample,
(int)framesPerBuffer);
chanCnt++;
if (linkFlag)
{
continue;
}
#else
// This code was reorganized so that if all audio tracks
// are muted, we still return paComplete when the end of
@@ -3553,6 +3571,10 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
(int)framesPerBuffer);
}
#endif
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
len = EffectManager::Get().RealtimeProcess(logicalCnt++, tempBufs, len);
#endif
// If our buffer is empty and the time indicator is past
// the end, then we've actually finished playing the entire
// selection.
@@ -3566,47 +3588,49 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
if (cut) // no samples to process, they've been discarded
continue;
#endif
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
EffectManager::Get().RealtimeProcessMono(tempFloats, len);
#endif
if (vt->GetChannel() == Track::LeftChannel ||
vt->GetChannel() == Track::MonoChannel)
for (int c = 0; c < chanCnt; c++)
{
float gain = vt->GetChannelGain(0);
vt = chans[c];
// Output volume emulation: possibly copy meter samples, then
// apply volume, then copy to the output buffer
if (outputMeterFloats != outputFloats)
for (i = 0; i < len; ++i)
outputMeterFloats[numPlaybackChannels*i] +=
gain*tempFloats[i];
if (vt->GetChannel() == Track::LeftChannel ||
vt->GetChannel() == Track::MonoChannel)
{
float gain = vt->GetChannelGain(0);
if (gAudioIO->mEmulateMixerOutputVol)
gain *= gAudioIO->mMixerOutputVol;
// Output volume emulation: possibly copy meter samples, then
// apply volume, then copy to the output buffer
if (outputMeterFloats != outputFloats)
for (int i = 0; i < len; ++i)
outputMeterFloats[numPlaybackChannels*i] +=
gain*tempFloats[i];
for(i=0; i<len; i++)
outputFloats[numPlaybackChannels*i] += gain*tempFloats[i];
if (gAudioIO->mEmulateMixerOutputVol)
gain *= gAudioIO->mMixerOutputVol;
for(int i=0; i<len; i++)
outputFloats[numPlaybackChannels*i] += gain*tempBufs[c][i];
}
if (vt->GetChannel() == Track::RightChannel ||
vt->GetChannel() == Track::MonoChannel)
{
float gain = vt->GetChannelGain(1);
// Output volume emulation (as above)
if (outputMeterFloats != outputFloats)
for (int i = 0; i < len; ++i)
outputMeterFloats[numPlaybackChannels*i+1] +=
gain*tempFloats[i];
if (gAudioIO->mEmulateMixerOutputVol)
gain *= gAudioIO->mMixerOutputVol;
for(int i=0; i<len; i++)
outputFloats[numPlaybackChannels*i+1] += gain*tempBufs[c][i];
}
}
if (vt->GetChannel() == Track::RightChannel ||
vt->GetChannel() == Track::MonoChannel)
{
float gain = vt->GetChannelGain(1);
// Output volume emulation (as above)
if (outputMeterFloats != outputFloats)
for (i = 0; i < len; ++i)
outputMeterFloats[numPlaybackChannels*i+1] +=
gain*tempFloats[i];
if (gAudioIO->mEmulateMixerOutputVol)
gain *= gAudioIO->mMixerOutputVol;
for(i=0; i<len; i++)
outputFloats[numPlaybackChannels*i+1] += gain*tempFloats[i];
}
chanCnt = 0;
}
//