Skip to content

Commit

Permalink
Refactor latency settings
Browse files Browse the repository at this point in the history
- Perform limit handling in DevicePrefs rather than in AudioIO.
- Get converted preference in AudioIoCallback through
  GetConvertedLatencyPreference().
- Properly convert milliseconds to samples.

Aso fixes #281, where an incorrect latency preference was being saved.

Reference-to: https://codeberg.org/tenacityteam/tenacity/issues/281
Signed-off-by: Avery King <[email protected]>
  • Loading branch information
generic-pers0n committed Sep 6, 2023
1 parent a7dcad0 commit 02aa291
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 25 deletions.
31 changes: 7 additions & 24 deletions src/AudioIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,31 +586,18 @@ using std::min;

/// @brief Converts the latency preference to samples and updates the user's
/// preference.
void AudioIoCallback::ConvertLatencyPreference()
long AudioIoCallback::GetConvertedLatencyPreference()
{
// Find out frames per buffer
double latency = AudioIOLatencyDuration.Read();
long latency = AudioIOLatencyDuration.Read();
bool isMilliseconds = AudioIOLatencyUnit.Read() == L"milliseconds";

if (isMilliseconds)
{
// The minimum latency setting is limited to either 32 samples or an
// equivalent time in milliseconds at the current sample rate at minimum.
// If the preference is below this setting, automatically set it to
// either 32 samples or the equivalent sample rate based on mRate.
latency *= mRate;
if (latency < 32.0)
{
latency = 32.0;
}

// Save the new latency preference.
AudioIOLatencyDuration.Write(latency / (mRate/1000));
} else if (latency < 32)
{
latency = 32;
AudioIOLatencyDuration.Write(latency);
latency *= mRate / 1000;
}

return latency;
}

AudioIO *AudioIO::Get()
Expand Down Expand Up @@ -1335,11 +1322,9 @@ bool AudioIO::StartPortAudioStream(const AudioIOStartStreamOptions &options,
maxTries = 5;
#endif

ConvertLatencyPreference();

UpdateBuffers();

unsigned long latency = AudioIOLatencyDuration.Read();
unsigned long latency = GetConvertedLatencyPreference();

for (unsigned int tries = 0; tries < maxTries; tries++) {
mLastPaError = Pa_OpenStream( &mPortStreamV19,
Expand Down Expand Up @@ -3615,9 +3600,7 @@ void AudioIoCallback::UpdateBuffers()
return;
}

ConvertLatencyPreference();

unsigned long newBufferSize = AudioIOLatencyDuration.Read();
unsigned long newBufferSize = GetConvertedLatencyPreference();
auto& memoryManager = AudioMemoryManager::Get();

mTemporaryBuffer.reset();
Expand Down
10 changes: 9 additions & 1 deletion src/AudioIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,15 @@ class TENACITY_DLL_API AudioIoCallback /* not final */

protected:

void ConvertLatencyPreference();
/** @brief Convert's the user's latency preference to samples.
*
* Internally, we use number of samples instead of milliseconds as that's
* just a preference based on what unit the user wants shown.
*
* @return Returns the converted latency preference.
*
*/
long GetConvertedLatencyPreference();

bool mUpdateMeters;
volatile bool mUpdatingMeters;
Expand Down
28 changes: 28 additions & 0 deletions src/prefs/DevicePrefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,34 @@ bool DevicePrefs::Commit()
audioIO->StopStream();
}

double latency = AudioIOLatencyDuration.Read();
bool isMilliseconds = AudioIOLatencyUnit.Read() == "milliseconds";

// If in milliseconds, convert the latency to samples
if (isMilliseconds)
{
latency *= QualitySettings::DefaultSampleRate.Read() / 1000;
}

// The minimum latency setting is limited to either 32 samples or an
// equivalent time in milliseconds at the current sample rate. If the
// preference is below this setting, automatically set it to either 32
// samples or the equivalent time in milliseconds.
//
// Why limit the preference to 32 samples? No reason, except it's a pretty
// small value already :)
if (static_cast<int>(latency) < 32)
{
latency = 32.0;

if (isMilliseconds)
{
latency /= QualitySettings::DefaultSampleRate.Read() / 1000;
}

AudioIOLatencyDuration.Write(latency);
}

AudioIO::Get()->UpdateBuffers();

if (monitoring)
Expand Down

0 comments on commit 02aa291

Please sign in to comment.