mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-18 09:00:52 +02:00
Allow for preRoll in start-stream options
This commit is contained in:
parent
20f3f76e2f
commit
35c60ac96d
@ -1929,14 +1929,17 @@ int AudioIO::StartStream(const TransportTracks &tracks,
|
|||||||
mTimeTrack = options.timeTrack;
|
mTimeTrack = options.timeTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
mT0 = t0;
|
// Clamp pre-roll so we don't play before time 0
|
||||||
|
const auto preRoll = std::max(0.0, std::min(t0, options.preRoll));
|
||||||
|
mT0 = t0 - preRoll;
|
||||||
mT1 = t1;
|
mT1 = t1;
|
||||||
mRecordingSchedule = {};
|
mRecordingSchedule = {};
|
||||||
|
mRecordingSchedule.mPreRoll = preRoll;
|
||||||
mRecordingSchedule.mLatencyCorrection =
|
mRecordingSchedule.mLatencyCorrection =
|
||||||
(gPrefs->ReadDouble(wxT("/AudioIO/LatencyCorrection"),
|
(gPrefs->ReadDouble(wxT("/AudioIO/LatencyCorrection"),
|
||||||
DEFAULT_LATENCY_CORRECTION))
|
DEFAULT_LATENCY_CORRECTION))
|
||||||
/ 1000.0;
|
/ 1000.0;
|
||||||
mRecordingSchedule.mDuration = mT1 - mT0;
|
mRecordingSchedule.mDuration = t1 - t0;
|
||||||
if (tracks.captureTracks.size() > 0)
|
if (tracks.captureTracks.size() > 0)
|
||||||
// adjust mT1 so that we don't give paComplete too soon to fill up the
|
// adjust mT1 so that we don't give paComplete too soon to fill up the
|
||||||
// desired length of recording
|
// desired length of recording
|
||||||
@ -1944,7 +1947,7 @@ int AudioIO::StartStream(const TransportTracks &tracks,
|
|||||||
|
|
||||||
mListener = options.listener;
|
mListener = options.listener;
|
||||||
mRate = sampleRate;
|
mRate = sampleRate;
|
||||||
mTime = t0;
|
mTime = mT0;
|
||||||
mSeek = 0;
|
mSeek = 0;
|
||||||
mLastRecordingOffset = 0;
|
mLastRecordingOffset = 0;
|
||||||
mCaptureTracks = tracks.captureTracks;
|
mCaptureTracks = tracks.captureTracks;
|
||||||
@ -3997,12 +4000,12 @@ void AudioIO::FillBuffers()
|
|||||||
size_t discarded = 0;
|
size_t discarded = 0;
|
||||||
|
|
||||||
if (!mRecordingSchedule.mLatencyCorrected) {
|
if (!mRecordingSchedule.mLatencyCorrected) {
|
||||||
if(mRecordingSchedule.mLatencyCorrection >= 0) {
|
const auto correction = mRecordingSchedule.TotalCorrection();
|
||||||
|
if (correction >= 0) {
|
||||||
// Rightward shift
|
// Rightward shift
|
||||||
// Once only (per track per recording), insert some initial
|
// Once only (per track per recording), insert some initial
|
||||||
// silence.
|
// silence.
|
||||||
size_t size = floor(
|
size_t size = floor( correction * mRate * mFactor);
|
||||||
mRecordingSchedule.mLatencyCorrection * mRate * mFactor);
|
|
||||||
SampleBuffer temp(size, trackFormat);
|
SampleBuffer temp(size, trackFormat);
|
||||||
ClearSamples(temp.ptr(), trackFormat, 0, size);
|
ClearSamples(temp.ptr(), trackFormat, 0, size);
|
||||||
mCaptureTracks[i]->Append(temp.ptr(), trackFormat,
|
mCaptureTracks[i]->Append(temp.ptr(), trackFormat,
|
||||||
@ -5403,15 +5406,10 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
|
|||||||
|
|
||||||
double AudioIO::RecordingSchedule::ToConsume() const
|
double AudioIO::RecordingSchedule::ToConsume() const
|
||||||
{
|
{
|
||||||
return mDuration - mLatencyCorrection - mPosition;
|
return mDuration - TotalCorrection() - mPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AudioIO::RecordingSchedule::ToDiscard() const
|
double AudioIO::RecordingSchedule::ToDiscard() const
|
||||||
{
|
{
|
||||||
if (mLatencyCorrection >= 0)
|
return std::max(0.0, -( mPosition + TotalCorrection() ) );
|
||||||
return 0.0;
|
|
||||||
else if (mPosition >= -mLatencyCorrection)
|
|
||||||
return 0.0;
|
|
||||||
else
|
|
||||||
return (-mLatencyCorrection) - mPosition;
|
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,7 @@ struct AudioIOStartStreamOptions
|
|||||||
, cutPreviewGapStart(0.0)
|
, cutPreviewGapStart(0.0)
|
||||||
, cutPreviewGapLen(0.0)
|
, cutPreviewGapLen(0.0)
|
||||||
, pStartTime(NULL)
|
, pStartTime(NULL)
|
||||||
|
, preRoll(0.0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TimeTrack *timeTrack;
|
TimeTrack *timeTrack;
|
||||||
@ -132,6 +133,7 @@ struct AudioIOStartStreamOptions
|
|||||||
double cutPreviewGapStart;
|
double cutPreviewGapStart;
|
||||||
double cutPreviewGapLen;
|
double cutPreviewGapLen;
|
||||||
double * pStartTime;
|
double * pStartTime;
|
||||||
|
double preRoll;
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
|
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
|
||||||
// Non-null value indicates that scrubbing will happen
|
// Non-null value indicates that scrubbing will happen
|
||||||
@ -823,7 +825,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct RecordingSchedule {
|
struct RecordingSchedule {
|
||||||
double mLatencyCorrection{};
|
double mPreRoll{};
|
||||||
|
double mLatencyCorrection{}; // negative value usually
|
||||||
double mDuration{};
|
double mDuration{};
|
||||||
|
|
||||||
// These are initialized by the main thread, then updated
|
// These are initialized by the main thread, then updated
|
||||||
@ -831,6 +834,7 @@ private:
|
|||||||
double mPosition{};
|
double mPosition{};
|
||||||
bool mLatencyCorrected{};
|
bool mLatencyCorrected{};
|
||||||
|
|
||||||
|
double TotalCorrection() const { return mLatencyCorrection - mPreRoll; }
|
||||||
double ToConsume() const;
|
double ToConsume() const;
|
||||||
double ToDiscard() const;
|
double ToDiscard() const;
|
||||||
} mRecordingSchedule{};
|
} mRecordingSchedule{};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user