Gtk: Tweak sound drivers for better performance.

This commit is contained in:
BearOso 2023-04-02 12:46:49 -05:00
parent f2be0cc11d
commit e55b13315b
4 changed files with 51 additions and 28 deletions

View File

@ -161,12 +161,6 @@ void S9xAlsaSoundDriver::samples_available()
return; return;
} }
if (Settings.DynamicRateControl)
{
S9xUpdateDynamicRate(snd_pcm_frames_to_bytes(pcm, frames),
output_buffer_size);
}
int snes_frames_available = S9xGetSampleCount() >> 1; int snes_frames_available = S9xGetSampleCount() >> 1;
if (Settings.DynamicRateControl && !Settings.SoundSync) if (Settings.DynamicRateControl && !Settings.SoundSync)
@ -224,4 +218,11 @@ void S9xAlsaSoundDriver::samples_available()
frames_written += result; frames_written += result;
} }
} }
if (Settings.DynamicRateControl)
{
frames = snd_pcm_avail(pcm);
S9xUpdateDynamicRate(snd_pcm_frames_to_bytes(pcm, frames),
output_buffer_size);
}
} }

View File

@ -197,11 +197,6 @@ void S9xPortAudioSoundDriver::samples_available()
frames -= output_buffer_size >> 1; frames -= output_buffer_size >> 1;
} }
if (Settings.DynamicRateControl)
{
S9xUpdateDynamicRate(frames, output_buffer_size);
}
int snes_frames_available = S9xGetSampleCount() >> 1; int snes_frames_available = S9xGetSampleCount() >> 1;
if (Settings.DynamicRateControl && !Settings.SoundSync) if (Settings.DynamicRateControl && !Settings.SoundSync)
@ -224,4 +219,10 @@ void S9xPortAudioSoundDriver::samples_available()
set_buffer_min(frames); set_buffer_min(frames);
S9xMixSamples(sound_buffer, frames << 1); S9xMixSamples(sound_buffer, frames << 1);
Pa_WriteStream(audio_stream, sound_buffer, frames); Pa_WriteStream(audio_stream, sound_buffer, frames);
if (Settings.DynamicRateControl)
{
frames = Pa_GetStreamWriteAvailable(audio_stream);
S9xUpdateDynamicRate(frames, output_buffer_size);
}
} }

View File

@ -114,10 +114,9 @@ bool S9xPulseSoundDriver::open_device()
ss.rate = Settings.SoundPlaybackRate; ss.rate = Settings.SoundPlaybackRate;
pa_buffer_attr buffer_attr; pa_buffer_attr buffer_attr;
buffer_attr.fragsize = -1;
buffer_attr.tlength = pa_usec_to_bytes(gui_config->sound_buffer_size * 1000, &ss); buffer_attr.tlength = pa_usec_to_bytes(gui_config->sound_buffer_size * 1000, &ss);
buffer_attr.maxlength = buffer_attr.tlength * 2; buffer_attr.maxlength = buffer_attr.tlength * 2;
buffer_attr.minreq = -1; buffer_attr.minreq = pa_usec_to_bytes(3000, &ss);
buffer_attr.prebuf = -1; buffer_attr.prebuf = -1;
printf("PulseAudio sound driver initializing...\n"); printf("PulseAudio sound driver initializing...\n");
@ -146,7 +145,7 @@ bool S9xPulseSoundDriver::open_device()
if (pa_stream_connect_playback(stream, if (pa_stream_connect_playback(stream,
nullptr, nullptr,
&buffer_attr, &buffer_attr,
PA_STREAM_ADJUST_LATENCY, PA_STREAM_EARLY_REQUESTS,
nullptr, nullptr,
nullptr) < 0) nullptr) < 0)
{ {
@ -175,6 +174,8 @@ bool S9xPulseSoundDriver::open_device()
void S9xPulseSoundDriver::samples_available() void S9xPulseSoundDriver::samples_available()
{ {
bool clear_samples = false;
lock(); lock();
size_t bytes = pa_stream_writable_size(stream); size_t bytes = pa_stream_writable_size(stream);
auto buffer_attr = pa_stream_get_buffer_attr(stream); auto buffer_attr = pa_stream_get_buffer_attr(stream);
@ -182,11 +183,6 @@ void S9xPulseSoundDriver::samples_available()
buffer_size = buffer_attr->tlength; buffer_size = buffer_attr->tlength;
if (Settings.DynamicRateControl)
{
S9xUpdateDynamicRate(bytes, buffer_size);
}
size_t samples = S9xGetSampleCount(); size_t samples = S9xGetSampleCount();
int frames_available = samples / 2; int frames_available = samples / 2;
@ -194,27 +190,43 @@ void S9xPulseSoundDriver::samples_available()
if (frames_writable < frames_available) if (frames_writable < frames_available)
{ {
if (Settings.DynamicRateControl && !Settings.SoundSync) if (!Settings.SoundSync)
{ {
S9xClearSamples(); clear_samples = true;
return;
} }
if (Settings.SoundSync && !Settings.TurboMode && !Settings.Mute) if (Settings.SoundSync && !Settings.TurboMode && !Settings.Mute)
{ {
int usec_to_sleep = (frames_available - frames_writable) * 10000 /
(Settings.SoundPlaybackRate / 100);
usleep(usec_to_sleep > 0 ? usec_to_sleep : 0);
lock(); lock();
bytes = pa_stream_writable_size(stream); int i;
unlock(); for (i = 0; i < 500; i++)
{
bytes = pa_stream_writable_size(stream);
if (bytes / 2 < samples)
{
unlock();
usleep(50);
lock();
}
else
{
unlock();
break;
}
}
if (i == 500)
printf("PulseAudio: Timed out waiting for sound sync.\n");
} }
} }
bytes = MIN(bytes, samples * 2) & ~1; bytes = MIN(bytes, samples * 2) & ~1;
if (!bytes) if (!bytes)
{
S9xClearSamples();
return; return;
}
lock(); lock();
@ -235,5 +247,14 @@ void S9xPulseSoundDriver::samples_available()
S9xMixSamples((uint8_t *)output_buffer, bytes >> 1); S9xMixSamples((uint8_t *)output_buffer, bytes >> 1);
pa_stream_write(stream, output_buffer, bytes, nullptr, 0, PA_SEEK_RELATIVE); pa_stream_write(stream, output_buffer, bytes, nullptr, 0, PA_SEEK_RELATIVE);
if (Settings.DynamicRateControl)
{
bytes = pa_stream_writable_size(stream);
S9xUpdateDynamicRate(bytes, buffer_size);
}
unlock(); unlock();
if (clear_samples)
S9xClearSamples();
} }

View File

@ -81,7 +81,7 @@ bool S9xSDLSoundDriver::open_device()
audiospec.freq = Settings.SoundPlaybackRate; audiospec.freq = Settings.SoundPlaybackRate;
audiospec.channels = 2; audiospec.channels = 2;
audiospec.format = AUDIO_S16SYS; audiospec.format = AUDIO_S16SYS;
audiospec.samples = (gui_config->sound_buffer_size * audiospec.freq / 1000) >> 2; audiospec.samples = audiospec.freq * 4 / 1000; // 4ms per sampling
audiospec.callback = [](void *userdata, uint8_t *stream, int len) { audiospec.callback = [](void *userdata, uint8_t *stream, int len) {
((S9xSDLSoundDriver *)userdata)->mix((unsigned char *)stream, len); ((S9xSDLSoundDriver *)userdata)->mix((unsigned char *)stream, len);
}; };