mirror of https://github.com/snes9xgit/snes9x.git
Gtk: Tweak sound drivers for better performance.
This commit is contained in:
parent
f2be0cc11d
commit
e55b13315b
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue