Skip to content

Commit

Permalink
Communicate data to per-track meters...
Browse files Browse the repository at this point in the history
.. To do this correctly, we must duplicate mono buffer in case of pan
differences, and modify each buffer exactly as for gain and pan and microfades
before communicating it
  • Loading branch information
Paul-Licameli committed Jan 11, 2024
1 parent 80f264f commit c6f81da
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
31 changes: 19 additions & 12 deletions libraries/lib-audio-io/AudioIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2355,7 +2355,7 @@ void AudioIoCallback::CheckSoundActivatedRecordingLevel(
void AudioIoCallback::AddToOutputChannel(unsigned int chan,
float * outputMeterFloats,
float * outputFloats,
const float * tempBuf,
float * tempBuf,
bool drop,
const unsigned long len,
const PlayableSequence &ps,
Expand Down Expand Up @@ -2390,8 +2390,11 @@ void AudioIoCallback::AddToOutputChannel(unsigned int chan,
// framesPerBuffer, which is influenced by the portAudio implementation in
// opaque ways
float deltaGain = (gain - oldGain) / len;
for (unsigned i = 0; i < len; i++)
outputFloats[numPlaybackChannels*i+chan] += (oldGain + deltaGain * i) *tempBuf[i];
for (unsigned i = 0; i < len; ++i) {
auto &value = tempBuf[i];
value *= (oldGain + deltaGain * i);
outputFloats[numPlaybackChannels * i + chan] += value;
}
};

// Limit values to -1.0..+1.0
Expand Down Expand Up @@ -2475,11 +2478,6 @@ bool AudioIoCallback::FillOutputBuffers(
auto vt = mPlaybackSequences[tt].first.get();
const auto width = vt->NChannels();

// IF mono THEN clear 'the other' channel.
if (width < numPlaybackChannels)
// TODO: more-than-two-channels
memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));

// Check for asynchronous user changes in mute, solo, pause status
discardable = drop = SequenceShouldBeSilent(*vt);

Expand Down Expand Up @@ -2516,6 +2514,13 @@ bool AudioIoCallback::FillOutputBuffers(
++iBuffer;
}

// IF mono THEN clear 'the other' channel.
if (width < numPlaybackChannels)
// TODO: more-than-two-channels
// Replicate left sample data for the right, before applying pan
// differences
memcpy(tempBufs[1], tempBufs[0], framesPerBuffer * sizeof(float));

// PRL: More recent rewrites of SequenceBufferExchange should guarantee a
// padding out of the ring buffers so that equal lengths are
// available, so maxLen ought to increase from 0 only once
Expand All @@ -2540,13 +2545,15 @@ bool AudioIoCallback::FillOutputBuffers(
AddToOutputChannel(0, outputMeterFloats, outputFloats,
tempBufs[0], drop, len, *vt, gains[0]);

// If one of mPlaybackSequences is mono, this replicates it in both
// device channels
const auto iBuffer = std::min<size_t>(1, width - 1);
AddToOutputChannel(1, outputMeterFloats, outputFloats,
tempBufs[iBuffer], drop, len, *vt, gains[1]);
tempBufs[1], drop, len, *vt, gains[1]);
}

for (const auto &wMeter : mPlaybackSequences[tt].second)
if (const auto pMeter = wMeter.lock(); pMeter && !pMeter->IsDisabled())
pMeter->Update(numPlaybackChannels,
framesPerBuffer, tempBuf, false); // non-interleaved

CallbackCheckCompletion(mCallbackReturn, len);
if (discardable) // no samples to process, they've been discarded
continue;
Expand Down
3 changes: 2 additions & 1 deletion libraries/lib-audio-io/AudioIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ class AUDIO_IO_API AudioIoCallback /* not final */
void AddToOutputChannel( unsigned int chan, // index into gains
float * outputMeterFloats,
float * outputFloats,
const float * tempBuf,
// This buffer is in/out. Pan, gain, and microfading will be applied
float * tempBuf,
bool drop,
unsigned long len,
const PlayableSequence &ps,
Expand Down

0 comments on commit c6f81da

Please sign in to comment.