GTK+: Strip out extra sound code.

No more Stereo, 16-bit or Reverse options.
This commit is contained in:
Brandon Wright 2019-02-06 19:41:33 -06:00
parent d8579ff9cb
commit 5b4ca50792
15 changed files with 320 additions and 380 deletions

View File

@ -285,9 +285,6 @@ int Snes9xConfig::save_config_file ()
outbool (cf, z"DynamicRateControl", Settings.DynamicRateControl); outbool (cf, z"DynamicRateControl", Settings.DynamicRateControl);
cf.SetInt (z"DynamicRateControlLimit", Settings.DynamicRateLimit); cf.SetInt (z"DynamicRateControlLimit", Settings.DynamicRateLimit);
outbool (cf, z"AutomaticInputRate", auto_input_rate, "Guess input rate by asking the monitor what its refresh rate is"); outbool (cf, z"AutomaticInputRate", auto_input_rate, "Guess input rate by asking the monitor what its refresh rate is");
outbool (cf, z"16bit", Settings.SixteenBitSound);
outbool (cf, z"Stereo", Settings.Stereo);
outbool (cf, z"ReverseStereo", Settings.ReverseStereo);
cf.SetInt (z"PlaybackRate", gui_config->sound_playback_rate, "1: 8000Hz, 2: 11025Hz, 3: 16000Hz, 4: 22050Hz, 5: 32000Hz, 6: 44100Hz, 7: 48000Hz"); cf.SetInt (z"PlaybackRate", gui_config->sound_playback_rate, "1: 8000Hz, 2: 11025Hz, 3: 16000Hz, 4: 22050Hz, 5: 32000Hz, 6: 44100Hz, 7: 48000Hz");
#undef z #undef z
@ -517,9 +514,6 @@ int Snes9xConfig::load_config_file ()
inbool (z"DynamicRateControl", Settings.DynamicRateControl); inbool (z"DynamicRateControl", Settings.DynamicRateControl);
inint (z"DynamicRateControlLimit", Settings.DynamicRateLimit); inint (z"DynamicRateControlLimit", Settings.DynamicRateLimit);
inbool (z"AutomaticInputRate", auto_input_rate); inbool (z"AutomaticInputRate", auto_input_rate);
inbool (z"16bit", Settings.SixteenBitSound);
inbool (z"Stereo", Settings.Stereo);
inbool (z"ReverseStereo", Settings.ReverseStereo);
inint (z"PlaybackRate", gui_config->sound_playback_rate); inint (z"PlaybackRate", gui_config->sound_playback_rate);
#undef z #undef z

View File

@ -633,7 +633,6 @@ Snes9xPreferences::move_settings_to_dialog ()
set_combo ("default_esc_behavior", config->default_esc_behavior); set_combo ("default_esc_behavior", config->default_esc_behavior);
set_check ("prevent_screensaver", config->prevent_screensaver); set_check ("prevent_screensaver", config->prevent_screensaver);
set_check ("force_inverted_byte_order", config->force_inverted_byte_order); set_check ("force_inverted_byte_order", config->force_inverted_byte_order);
set_check ("stereo_check", Settings.Stereo);
set_combo ("playback_combo", 7 - config->sound_playback_rate); set_combo ("playback_combo", 7 - config->sound_playback_rate);
set_combo ("hw_accel", combo_value (config->hw_accel)); set_combo ("hw_accel", combo_value (config->hw_accel));
set_check ("pause_emulation_on_switch", config->pause_emulation_on_switch); set_check ("pause_emulation_on_switch", config->pause_emulation_on_switch);
@ -748,7 +747,6 @@ Snes9xPreferences::get_settings_from_dialog ()
if ((config->sound_driver != get_combo ("sound_driver")) || if ((config->sound_driver != get_combo ("sound_driver")) ||
(config->mute_sound != get_check ("mute_sound_check")) || (config->mute_sound != get_check ("mute_sound_check")) ||
(config->sound_buffer_size != (int) get_spin ("sound_buffer_size")) || (config->sound_buffer_size != (int) get_spin ("sound_buffer_size")) ||
(Settings.Stereo != get_check ("stereo_check")) ||
(config->sound_playback_rate != (7 - (get_combo ("playback_combo")))) || (config->sound_playback_rate != (7 - (get_combo ("playback_combo")))) ||
(config->sound_input_rate != get_slider ("sound_input_rate")) || (config->sound_input_rate != get_slider ("sound_input_rate")) ||
(config->auto_input_rate != get_check ("auto_input_rate")) || (config->auto_input_rate != get_check ("auto_input_rate")) ||
@ -801,7 +799,6 @@ Snes9xPreferences::get_settings_from_dialog ()
Settings.UpAndDown = get_check ("upanddown"); Settings.UpAndDown = get_check ("upanddown");
Settings.SuperFXClockMultiplier = get_spin ("superfx_multiplier"); Settings.SuperFXClockMultiplier = get_spin ("superfx_multiplier");
config->sound_driver = get_combo ("sound_driver"); config->sound_driver = get_combo ("sound_driver");
Settings.Stereo = get_check ("stereo_check");
config->sound_playback_rate = 7 - (get_combo ("playback_combo")); config->sound_playback_rate = 7 - (get_combo ("playback_combo"));
config->sound_buffer_size = get_spin ("sound_buffer_size"); config->sound_buffer_size = get_spin ("sound_buffer_size");
config->sound_input_rate = get_slider ("sound_input_rate"); config->sound_input_rate = get_slider ("sound_input_rate");

View File

@ -7,13 +7,13 @@
#ifndef __GTK_SOUND_H #ifndef __GTK_SOUND_H
#define __GTK_SOUND_H #define __GTK_SOUND_H
void S9xPortSoundInit (); void S9xPortSoundInit();
void S9xPortSoundDeinit (); void S9xPortSoundDeinit();
void S9xPortSoundReinit (); void S9xPortSoundReinit();
void S9xSoundStart (); void S9xSoundStart();
void S9xSoundStop (); void S9xSoundStop();
int S9xSoundBase2log (int num); int S9xSoundBase2log(int num);
int S9xSoundPowerof2 (int num); int S9xSoundPowerof2(int num);
#endif /* __GTK_SOUND_H */ #endif /* __GTK_SOUND_H */

View File

@ -11,14 +11,15 @@
class S9xSoundDriver class S9xSoundDriver
{ {
public: public:
virtual ~S9xSoundDriver () {} virtual ~S9xSoundDriver()
virtual void init () = 0; {
virtual void terminate () = 0; }
virtual bool open_device () = 0; virtual void init() = 0;
virtual void start () = 0; virtual void terminate() = 0;
virtual void stop () = 0; virtual bool open_device() = 0;
virtual void start() = 0;
virtual void stop() = 0;
}; };
#endif /* __GTK_SOUND_DRIVER_H */ #endif /* __GTK_SOUND_DRIVER_H */

View File

@ -4,59 +4,54 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "gtk_s9x.h"
#include "gtk_sound_driver_alsa.h" #include "gtk_sound_driver_alsa.h"
#include "gtk_s9x.h"
#include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <fcntl.h>
static void static void alsa_samples_available(void *data)
alsa_samples_available (void *data)
{ {
((S9xAlsaSoundDriver *) data)->samples_available (); ((S9xAlsaSoundDriver *)data)->samples_available();
} }
S9xAlsaSoundDriver::S9xAlsaSoundDriver () S9xAlsaSoundDriver::S9xAlsaSoundDriver()
{ {
pcm = NULL; pcm = NULL;
sound_buffer = NULL; sound_buffer = NULL;
sound_buffer_size = 0; sound_buffer_size = 0;
} }
void void S9xAlsaSoundDriver::init()
S9xAlsaSoundDriver::init ()
{ {
} }
void void S9xAlsaSoundDriver::terminate()
S9xAlsaSoundDriver::terminate ()
{ {
stop (); stop();
S9xSetSamplesAvailableCallback (NULL, NULL); S9xSetSamplesAvailableCallback(NULL, NULL);
if (pcm) if (pcm)
{ {
snd_pcm_drain (pcm); snd_pcm_drain(pcm);
snd_pcm_close (pcm); snd_pcm_close(pcm);
pcm = NULL; pcm = NULL;
} }
if (sound_buffer) if (sound_buffer)
{ {
free (sound_buffer); free(sound_buffer);
sound_buffer = NULL; sound_buffer = NULL;
} }
} }
void void S9xAlsaSoundDriver::start()
S9xAlsaSoundDriver::start ()
{ {
} }
void void S9xAlsaSoundDriver::stop()
S9xAlsaSoundDriver::stop ()
{ {
} }
@ -71,135 +66,132 @@ bool S9xAlsaSoundDriver::open_device()
unsigned int min = 0; unsigned int min = 0;
unsigned int max = 0; unsigned int max = 0;
printf ("ALSA sound driver initializing...\n"); printf("ALSA sound driver initializing...\n");
printf (" --> (Device: default)...\n"); printf(" --> (Device: default)...\n");
err = snd_pcm_open (&pcm, err = snd_pcm_open(&pcm,
"default", "default",
SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK); SND_PCM_NONBLOCK);
if (err < 0) if (err < 0)
{ {
goto fail; goto fail;
} }
printf (" --> (%s, %s, %dhz, %d ms)...\n", printf(" --> (16-bit Stereo, %dhz, %d ms)...\n",
"16-bit", Settings.SoundPlaybackRate,
"Stereo", gui_config->sound_buffer_size);
Settings.SoundPlaybackRate,
gui_config->sound_buffer_size);
snd_pcm_hw_params_alloca (&hw_params); snd_pcm_hw_params_alloca(&hw_params);
snd_pcm_hw_params_any (pcm, hw_params); snd_pcm_hw_params_any(pcm, hw_params);
snd_pcm_hw_params_set_format (pcm, hw_params, SND_PCM_FORMAT_S16); snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16);
snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_rate_resample (pcm, hw_params, 0); snd_pcm_hw_params_set_rate_resample(pcm, hw_params, 0);
snd_pcm_hw_params_set_channels (pcm, hw_params, 2); snd_pcm_hw_params_set_channels(pcm, hw_params, 2);
snd_pcm_hw_params_get_rate_min (hw_params, &min, NULL); snd_pcm_hw_params_get_rate_min(hw_params, &min, NULL);
snd_pcm_hw_params_get_rate_max (hw_params, &max, NULL); snd_pcm_hw_params_get_rate_max(hw_params, &max, NULL);
printf (" --> Available rates: %d to %d\n", min, max); printf(" --> Available rates: %d to %d\n", min, max);
if (Settings.SoundPlaybackRate > max && Settings.SoundPlaybackRate < min) if (Settings.SoundPlaybackRate > max && Settings.SoundPlaybackRate < min)
{ {
printf (" Rate %d not available. Using %d instead.\n", Settings.SoundPlaybackRate, max); printf(" Rate %d not available. Using %d instead.\n", Settings.SoundPlaybackRate, max);
Settings.SoundPlaybackRate = max; Settings.SoundPlaybackRate = max;
} }
snd_pcm_hw_params_set_rate_near (pcm, hw_params, &Settings.SoundPlaybackRate, NULL); snd_pcm_hw_params_set_rate_near(pcm, hw_params, &Settings.SoundPlaybackRate, NULL);
snd_pcm_hw_params_get_buffer_time_min (hw_params, &min, NULL); snd_pcm_hw_params_get_buffer_time_min(hw_params, &min, NULL);
snd_pcm_hw_params_get_buffer_time_max (hw_params, &max, NULL); snd_pcm_hw_params_get_buffer_time_max(hw_params, &max, NULL);
printf (" --> Available buffer sizes: %dms to %dms\n", min / 1000, max / 1000); printf(" --> Available buffer sizes: %dms to %dms\n", min / 1000, max / 1000);
if (buffer_size < min && buffer_size > max) if (buffer_size < min && buffer_size > max)
{ {
printf (" Buffer size %dms not available. Using %d instead.\n", buffer_size / 1000, (min + max) / 2000); printf(" Buffer size %dms not available. Using %d instead.\n", buffer_size / 1000, (min + max) / 2000);
buffer_size = (min + max) / 2; buffer_size = (min + max) / 2;
} }
snd_pcm_hw_params_set_buffer_time_near (pcm, hw_params, &buffer_size, NULL); snd_pcm_hw_params_set_buffer_time_near(pcm, hw_params, &buffer_size, NULL);
snd_pcm_hw_params_get_periods_min (hw_params, &min, NULL); snd_pcm_hw_params_get_periods_min(hw_params, &min, NULL);
snd_pcm_hw_params_get_periods_max (hw_params, &max, NULL); snd_pcm_hw_params_get_periods_max(hw_params, &max, NULL);
printf (" --> Period ranges: %d to %d blocks\n", min, max); printf(" --> Period ranges: %d to %d blocks\n", min, max);
if (periods > max) if (periods > max)
{ {
periods = max; periods = max;
} }
snd_pcm_hw_params_set_periods_near (pcm, hw_params, &periods, NULL); snd_pcm_hw_params_set_periods_near(pcm, hw_params, &periods, NULL);
if ((err = snd_pcm_hw_params (pcm, hw_params)) < 0) if ((err = snd_pcm_hw_params(pcm, hw_params)) < 0)
{ {
printf (" Hardware parameter set failed.\n"); printf(" Hardware parameter set failed.\n");
goto close_fail; goto close_fail;
} }
snd_pcm_sw_params_alloca (&sw_params); snd_pcm_sw_params_alloca(&sw_params);
snd_pcm_sw_params_current (pcm, sw_params); snd_pcm_sw_params_current(pcm, sw_params);
snd_pcm_get_params (pcm, &alsa_buffer_size, &alsa_period_size); snd_pcm_get_params(pcm, &alsa_buffer_size, &alsa_period_size);
/* Don't start until we're [nearly] full */ /* Don't start until we're [nearly] full */
snd_pcm_sw_params_set_start_threshold (pcm, sw_params, (alsa_buffer_size / 2)); snd_pcm_sw_params_set_start_threshold(pcm, sw_params, (alsa_buffer_size / 2));
err = snd_pcm_sw_params (pcm, sw_params); err = snd_pcm_sw_params(pcm, sw_params);
output_buffer_size = snd_pcm_frames_to_bytes (pcm, alsa_buffer_size); output_buffer_size = snd_pcm_frames_to_bytes(pcm, alsa_buffer_size);
if (err < 0) if (err < 0)
{ {
printf (" Software parameter set failed.\n"); printf(" Software parameter set failed.\n");
goto close_fail; goto close_fail;
} }
printf ("OK\n"); printf("OK\n");
S9xSetSamplesAvailableCallback (alsa_samples_available, this); S9xSetSamplesAvailableCallback(alsa_samples_available, this);
return true; return true;
close_fail: close_fail:
snd_pcm_drain (pcm); snd_pcm_drain(pcm);
snd_pcm_close (pcm); snd_pcm_close(pcm);
pcm = NULL; pcm = NULL;
fail: fail:
printf ("Failed: %s\n", snd_strerror (err)); printf("Failed: %s\n", snd_strerror(err));
return false; return false;
} }
void void S9xAlsaSoundDriver::samples_available()
S9xAlsaSoundDriver::samples_available ()
{ {
snd_pcm_sframes_t frames_written, frames; snd_pcm_sframes_t frames_written, frames;
int bytes; int bytes;
frames = snd_pcm_avail (pcm); frames = snd_pcm_avail(pcm);
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
S9xUpdateDynamicRate (snd_pcm_frames_to_bytes (pcm, frames), S9xUpdateDynamicRate(snd_pcm_frames_to_bytes(pcm, frames),
output_buffer_size); output_buffer_size);
} }
if (frames < 0) if (frames < 0)
{ {
frames = snd_pcm_recover (pcm, frames, 1); frames = snd_pcm_recover(pcm, frames, 1);
return; return;
} }
S9xFinalizeSamples (); S9xFinalizeSamples();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
// Using rate control, we should always keep the emulator's sound buffers empty to // Using rate control, we should always keep the emulator's sound buffers empty to
// maintain an accurate measurement. // maintain an accurate measurement.
if (frames < (S9xGetSampleCount () >> 1)) if (frames < (S9xGetSampleCount() >> 1))
{ {
S9xClearSamples (); S9xClearSamples();
return; return;
} }
} }
frames = MIN (frames, S9xGetSampleCount () >> 1); frames = MIN(frames, S9xGetSampleCount() >> 1);
bytes = snd_pcm_frames_to_bytes (pcm, frames); bytes = snd_pcm_frames_to_bytes(pcm, frames);
if (bytes <= 0) if (bytes <= 0)
{ {
@ -208,11 +200,11 @@ S9xAlsaSoundDriver::samples_available ()
if (sound_buffer_size < bytes || sound_buffer == NULL) if (sound_buffer_size < bytes || sound_buffer == NULL)
{ {
sound_buffer = (uint8 *) realloc (sound_buffer, bytes); sound_buffer = (uint8 *)realloc(sound_buffer, bytes);
sound_buffer_size = bytes; sound_buffer_size = bytes;
} }
S9xMixSamples (sound_buffer, frames * 2); S9xMixSamples(sound_buffer, frames * 2);
frames_written = 0; frames_written = 0;
@ -220,14 +212,14 @@ S9xAlsaSoundDriver::samples_available ()
{ {
int result; int result;
result = snd_pcm_writei (pcm, result = snd_pcm_writei(pcm,
sound_buffer + sound_buffer +
snd_pcm_frames_to_bytes (pcm, frames_written), snd_pcm_frames_to_bytes(pcm, frames_written),
frames - frames_written); frames - frames_written);
if (result < 0) if (result < 0)
{ {
result = snd_pcm_recover (pcm, result, 1); result = snd_pcm_recover(pcm, result, 1);
if (result < 0) if (result < 0)
{ {

View File

@ -13,20 +13,20 @@
class S9xAlsaSoundDriver : public S9xSoundDriver class S9xAlsaSoundDriver : public S9xSoundDriver
{ {
public: public:
S9xAlsaSoundDriver (); S9xAlsaSoundDriver();
void init (); void init();
void terminate (); void terminate();
bool open_device (); bool open_device();
void start (); void start();
void stop (); void stop();
void samples_available (); void samples_available();
private: private:
snd_pcm_t *pcm; snd_pcm_t *pcm;
int sound_buffer_size; int sound_buffer_size;
uint8 *sound_buffer; uint8 *sound_buffer;
int output_buffer_size; int output_buffer_size;
}; };
#endif /* __GTK_SOUND_DRIVER_ALSA_H */ #endif /* __GTK_SOUND_DRIVER_ALSA_H */

View File

@ -4,58 +4,53 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "gtk_s9x.h"
#include "gtk_sound_driver_oss.h" #include "gtk_sound_driver_oss.h"
#include "gtk_s9x.h"
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <sys/time.h>
static void static void oss_samples_available(void *data)
oss_samples_available (void *data)
{ {
((S9xOSSSoundDriver *) data)->samples_available (); ((S9xOSSSoundDriver *)data)->samples_available();
} }
S9xOSSSoundDriver::S9xOSSSoundDriver () S9xOSSSoundDriver::S9xOSSSoundDriver()
{ {
filedes = -1; filedes = -1;
sound_buffer = NULL; sound_buffer = NULL;
sound_buffer_size = 0; sound_buffer_size = 0;
} }
void void S9xOSSSoundDriver::init()
S9xOSSSoundDriver::init ()
{ {
} }
void void S9xOSSSoundDriver::terminate()
S9xOSSSoundDriver::terminate ()
{ {
stop (); stop();
S9xSetSamplesAvailableCallback (NULL, NULL); S9xSetSamplesAvailableCallback(NULL, NULL);
if (filedes >= 0) if (filedes >= 0)
{ {
close (filedes); close(filedes);
} }
if (sound_buffer) if (sound_buffer)
{ {
free (sound_buffer); free(sound_buffer);
sound_buffer = NULL; sound_buffer = NULL;
} }
} }
void void S9xOSSSoundDriver::start()
S9xOSSSoundDriver::start ()
{ {
} }
void void S9xOSSSoundDriver::stop()
S9xOSSSoundDriver::stop ()
{ {
} }
@ -70,110 +65,108 @@ bool S9xOSSSoundDriver::open_device()
if (output_buffer_size < 256) if (output_buffer_size < 256)
output_buffer_size = 256; output_buffer_size = 256;
printf ("OSS sound driver initializing...\n"); printf("OSS sound driver initializing...\n");
printf ("Device: /dev/dsp: "); printf("Device: /dev/dsp: ");
filedes = open ("/dev/dsp", O_WRONLY | O_NONBLOCK); filedes = open("/dev/dsp", O_WRONLY | O_NONBLOCK);
if (filedes < 0) if (filedes < 0)
{ {
printf ("Failed.\n"); printf("Failed.\n");
char dspstring[16] = "/dev/dspX\0"; char dspstring[16] = "/dev/dspX\0";
for (int i = 1; i <= 9; i++) for (int i = 1; i <= 9; i++)
{ {
dspstring[8] = '0' + i; dspstring[8] = '0' + i;
printf ("Trying %s: ", dspstring); printf("Trying %s: ", dspstring);
filedes = open (dspstring, O_WRONLY | O_NONBLOCK); filedes = open(dspstring, O_WRONLY | O_NONBLOCK);
if (filedes < 0) if (filedes < 0)
{ {
if (i == 9) if (i == 9)
goto fail; goto fail;
printf ("Failed.\n"); printf("Failed.\n");
} }
else else
break; break;
} }
} }
printf ("OK\n"); printf("OK\n");
printf(" --> (Format: 16-bit)...");
printf (" --> (Format: 16-bit)...");
temp = AFMT_S16_LE; temp = AFMT_S16_LE;
if (ioctl (filedes, SNDCTL_DSP_SETFMT, &temp) < 0) if (ioctl(filedes, SNDCTL_DSP_SETFMT, &temp) < 0)
goto close_fail; goto close_fail;
printf ("OK\n"); printf("OK\n");
temp = 2; temp = 2;
printf (" --> (Stereo)..."); printf(" --> (Stereo)...");
if (ioctl (filedes, SNDCTL_DSP_CHANNELS, &temp) < 0) if (ioctl(filedes, SNDCTL_DSP_CHANNELS, &temp) < 0)
goto close_fail; goto close_fail;
printf ("OK\n"); printf("OK\n");
printf (" --> (Frequency: %d)...", Settings.SoundPlaybackRate); printf(" --> (Frequency: %d)...", Settings.SoundPlaybackRate);
if (ioctl (filedes, SNDCTL_DSP_SPEED, &Settings.SoundPlaybackRate) < 0) if (ioctl(filedes, SNDCTL_DSP_SPEED, &Settings.SoundPlaybackRate) < 0)
goto close_fail; goto close_fail;
printf ("OK\n"); printf("OK\n");
/* OSS requires a power-of-two buffer size, first 16 bits are the number /* OSS requires a power-of-two buffer size, first 16 bits are the number
* of fragments to generate, second 16 are the respective power-of-two. */ * of fragments to generate, second 16 are the respective power-of-two. */
temp = (4 << 16) | (S9xSoundBase2log (output_buffer_size / 4)); temp = (4 << 16) | (S9xSoundBase2log(output_buffer_size / 4));
if (ioctl (filedes, SNDCTL_DSP_SETFRAGMENT, &temp) < 0) if (ioctl(filedes, SNDCTL_DSP_SETFRAGMENT, &temp) < 0)
goto close_fail; goto close_fail;
ioctl (filedes, SNDCTL_DSP_GETOSPACE, &info); ioctl(filedes, SNDCTL_DSP_GETOSPACE, &info);
output_buffer_size = info.fragsize * info.fragstotal; output_buffer_size = info.fragsize * info.fragstotal;
printf (" --> (Buffer size: %d bytes, %dms latency)...", printf(" --> (Buffer size: %d bytes, %dms latency)...",
output_buffer_size, output_buffer_size,
(output_buffer_size * 250) / Settings.SoundPlaybackRate); (output_buffer_size * 250) / Settings.SoundPlaybackRate);
printf ("OK\n"); printf("OK\n");
S9xSetSamplesAvailableCallback (oss_samples_available, this); S9xSetSamplesAvailableCallback(oss_samples_available, this);
return true; return true;
close_fail: close_fail:
close (filedes); close(filedes);
fail: fail:
printf ("failed\n"); printf("failed\n");
return false; return false;
} }
void void S9xOSSSoundDriver::samples_available()
S9xOSSSoundDriver::samples_available ()
{ {
audio_buf_info info; audio_buf_info info;
int samples_to_write; int samples_to_write;
int bytes_to_write; int bytes_to_write;
int bytes_written; int bytes_written;
ioctl (filedes, SNDCTL_DSP_GETOSPACE, &info); ioctl(filedes, SNDCTL_DSP_GETOSPACE, &info);
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
S9xUpdateDynamicRate (info.bytes, output_buffer_size); S9xUpdateDynamicRate(info.bytes, output_buffer_size);
} }
S9xFinalizeSamples (); S9xFinalizeSamples();
samples_to_write = S9xGetSampleCount (); samples_to_write = S9xGetSampleCount();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
@ -181,23 +174,23 @@ S9xOSSSoundDriver::samples_available ()
// maintain an accurate measurement. // maintain an accurate measurement.
if (samples_to_write > (info.bytes >> 1)) if (samples_to_write > (info.bytes >> 1))
{ {
S9xClearSamples (); S9xClearSamples();
return; return;
} }
} }
samples_to_write = MIN (info.bytes >> 1, samples_to_write) & ~1; samples_to_write = MIN(info.bytes >> 1, samples_to_write) & ~1;
if (samples_to_write < 0) if (samples_to_write < 0)
return; return;
if (sound_buffer_size < samples_to_write * 2) if (sound_buffer_size < samples_to_write * 2)
{ {
sound_buffer = (uint8 *) realloc (sound_buffer, samples_to_write * 2); sound_buffer = (uint8 *)realloc(sound_buffer, samples_to_write * 2);
sound_buffer_size = samples_to_write * 2; sound_buffer_size = samples_to_write * 2;
} }
S9xMixSamples (sound_buffer, samples_to_write); S9xMixSamples(sound_buffer, samples_to_write);
bytes_written = 0; bytes_written = 0;
bytes_to_write = samples_to_write * 2; bytes_to_write = samples_to_write * 2;
@ -206,9 +199,9 @@ S9xOSSSoundDriver::samples_available ()
{ {
int result; int result;
result = write (filedes, result = write(filedes,
((char *) sound_buffer) + bytes_written, ((char *)sound_buffer) + bytes_written,
bytes_to_write - bytes_written); bytes_to_write - bytes_written);
if (result < 0) if (result < 0)
break; break;

View File

@ -12,22 +12,20 @@
class S9xOSSSoundDriver : public S9xSoundDriver class S9xOSSSoundDriver : public S9xSoundDriver
{ {
public: public:
S9xOSSSoundDriver (); S9xOSSSoundDriver();
void init (); void init();
void terminate (); void terminate();
bool open_device (); bool open_device();
void start (); void start();
void stop (); void stop();
void samples_available (); void samples_available();
private: private:
int filedes; int filedes;
uint8 *sound_buffer; uint8 *sound_buffer;
int sound_buffer_size; int sound_buffer_size;
int output_buffer_size; int output_buffer_size;
}; };
#endif /* __GTK_SOUND_DRIVER_OSS_H */ #endif /* __GTK_SOUND_DRIVER_OSS_H */

View File

@ -4,19 +4,17 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "gtk_s9x.h"
#include "gtk_sound_driver_portaudio.h" #include "gtk_sound_driver_portaudio.h"
#include "gtk_s9x.h"
static inline int static inline int frames_to_bytes(int frames)
frames_to_bytes (int frames)
{ {
return frames * 4; return frames * 4;
} }
static void static void port_audio_samples_available_callback(void *data)
port_audio_samples_available_callback (void *data)
{ {
((S9xPortAudioSoundDriver *) data)->samples_available (); ((S9xPortAudioSoundDriver *)data)->samples_available();
} }
S9xPortAudioSoundDriver::S9xPortAudioSoundDriver() S9xPortAudioSoundDriver::S9xPortAudioSoundDriver()
@ -26,80 +24,76 @@ S9xPortAudioSoundDriver::S9xPortAudioSoundDriver()
sound_buffer_size = 0; sound_buffer_size = 0;
} }
void void S9xPortAudioSoundDriver::init()
S9xPortAudioSoundDriver::init ()
{ {
PaError err; PaError err;
err = Pa_Initialize (); err = Pa_Initialize();
if (err != paNoError) if (err != paNoError)
fprintf (stderr, fprintf(stderr,
"Couldn't initialize PortAudio: %s\n", "Couldn't initialize PortAudio: %s\n",
Pa_GetErrorText (err)); Pa_GetErrorText(err));
} }
void void S9xPortAudioSoundDriver::terminate()
S9xPortAudioSoundDriver::terminate ()
{ {
stop (); stop();
S9xSetSamplesAvailableCallback (NULL, NULL); S9xSetSamplesAvailableCallback(NULL, NULL);
Pa_Terminate (); Pa_Terminate();
if (sound_buffer) if (sound_buffer)
{ {
free (sound_buffer); free(sound_buffer);
sound_buffer = NULL; sound_buffer = NULL;
} }
} }
void void S9xPortAudioSoundDriver::start()
S9xPortAudioSoundDriver::start ()
{ {
PaError err; PaError err;
if (audio_stream != NULL && !(gui_config->mute_sound)) if (audio_stream != NULL && !(gui_config->mute_sound))
{ {
if ((Pa_IsStreamActive (audio_stream))) if ((Pa_IsStreamActive(audio_stream)))
return; return;
err = Pa_StartStream (audio_stream); err = Pa_StartStream(audio_stream);
if (err != paNoError) if (err != paNoError)
{ {
fprintf (stderr, "Error: %s\n", Pa_GetErrorText (err)); fprintf(stderr, "Error: %s\n", Pa_GetErrorText(err));
} }
} }
} }
void void S9xPortAudioSoundDriver::stop()
S9xPortAudioSoundDriver::stop ()
{ {
if (audio_stream != NULL) if (audio_stream != NULL)
{ {
Pa_StopStream (audio_stream); Pa_StopStream(audio_stream);
} }
} }
bool S9xPortAudioSoundDriver::open_device() bool S9xPortAudioSoundDriver::open_device()
{ {
PaStreamParameters param; PaStreamParameters param;
const PaDeviceInfo *device_info; const PaDeviceInfo *device_info;
const PaHostApiInfo *hostapi_info; const PaHostApiInfo *hostapi_info;
PaError err = paNoError; PaError err = paNoError;
if (audio_stream != NULL) if (audio_stream != NULL)
{ {
printf ("Shutting down sound for reset\n"); printf("Shutting down sound for reset\n");
err = Pa_CloseStream (audio_stream); err = Pa_CloseStream(audio_stream);
if (err != paNoError) if (err != paNoError)
{ {
fprintf (stderr, fprintf(stderr,
"Couldn't reset audio stream.\nError: %s\n", "Couldn't reset audio stream.\nError: %s\n",
Pa_GetErrorText (err)); Pa_GetErrorText(err));
return true; return true;
} }
@ -110,24 +104,24 @@ bool S9xPortAudioSoundDriver::open_device()
param.sampleFormat = paInt16; param.sampleFormat = paInt16;
param.hostApiSpecificStreamInfo = NULL; param.hostApiSpecificStreamInfo = NULL;
printf ("PortAudio sound driver initializing...\n"); printf("PortAudio sound driver initializing...\n");
for (int i = 0; i < Pa_GetHostApiCount (); i++) for (int i = 0; i < Pa_GetHostApiCount(); i++)
{ {
printf (" --> "); printf(" --> ");
hostapi_info = Pa_GetHostApiInfo (i); hostapi_info = Pa_GetHostApiInfo(i);
if (!hostapi_info) if (!hostapi_info)
{ {
printf ("Host API #%d has no info\n", i); printf("Host API #%d has no info\n", i);
err = paNotInitialized; err = paNotInitialized;
continue; continue;
} }
device_info = Pa_GetDeviceInfo (hostapi_info->defaultOutputDevice); device_info = Pa_GetDeviceInfo(hostapi_info->defaultOutputDevice);
if (!device_info) if (!device_info)
{ {
printf ("(%s)...No device info available.\n", hostapi_info->name); printf("(%s)...No device info available.\n", hostapi_info->name);
err = paNotInitialized; err = paNotInitialized;
continue; continue;
} }
@ -135,88 +129,87 @@ bool S9xPortAudioSoundDriver::open_device()
param.device = hostapi_info->defaultOutputDevice; param.device = hostapi_info->defaultOutputDevice;
param.suggestedLatency = gui_config->sound_buffer_size * 0.001; param.suggestedLatency = gui_config->sound_buffer_size * 0.001;
printf ("(%s : %s, latency %dms)...", printf("(%s : %s, latency %dms)...",
hostapi_info->name, hostapi_info->name,
device_info->name, device_info->name,
(int) (param.suggestedLatency * 1000.0)); (int)(param.suggestedLatency * 1000.0));
fflush (stdout); fflush(stdout);
err = Pa_OpenStream (&audio_stream, err = Pa_OpenStream(&audio_stream,
NULL, NULL,
&param, &param,
Settings.SoundPlaybackRate, Settings.SoundPlaybackRate,
0, 0,
paNoFlag, paNoFlag,
NULL, NULL,
NULL); NULL);
int frames = Pa_GetStreamWriteAvailable (audio_stream); int frames = Pa_GetStreamWriteAvailable(audio_stream);
output_buffer_size = frames_to_bytes (frames); output_buffer_size = frames_to_bytes(frames);
if (err == paNoError) if (err == paNoError)
{ {
printf ("OK\n"); printf("OK\n");
break; break;
} }
else else
{ {
printf ("Failed (%s)\n", printf("Failed (%s)\n",
Pa_GetErrorText (err)); Pa_GetErrorText(err));
} }
} }
if (err != paNoError || Pa_GetHostApiCount () < 1) if (err != paNoError || Pa_GetHostApiCount() < 1)
{ {
fprintf (stderr, fprintf(stderr,
"Couldn't initialize sound\n"); "Couldn't initialize sound\n");
return false; return false;
} }
S9xSetSamplesAvailableCallback (port_audio_samples_available_callback, this); S9xSetSamplesAvailableCallback(port_audio_samples_available_callback, this);
fflush (stdout); fflush(stdout);
fflush (stderr); fflush(stderr);
return true; return true;
} }
void void S9xPortAudioSoundDriver::samples_available()
S9xPortAudioSoundDriver::samples_available ()
{ {
int frames; int frames;
int bytes; int bytes;
frames = Pa_GetStreamWriteAvailable (audio_stream); frames = Pa_GetStreamWriteAvailable(audio_stream);
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
S9xUpdateDynamicRate (frames_to_bytes (frames), output_buffer_size); S9xUpdateDynamicRate(frames_to_bytes(frames), output_buffer_size);
} }
S9xFinalizeSamples (); S9xFinalizeSamples();
if (Settings.DynamicRateControl) if (Settings.DynamicRateControl)
{ {
// Using rate control, we should always keep the emulator's sound buffers empty to // Using rate control, we should always keep the emulator's sound buffers empty to
// maintain an accurate measurement. // maintain an accurate measurement.
if (frames < (S9xGetSampleCount () >> 1)) if (frames < (S9xGetSampleCount() >> 1))
{ {
S9xClearSamples (); S9xClearSamples();
return; return;
} }
} }
frames = MIN (frames, S9xGetSampleCount () >> 1); frames = MIN(frames, S9xGetSampleCount() >> 1);
bytes = frames_to_bytes (frames); bytes = frames_to_bytes(frames);
if (sound_buffer_size < bytes || sound_buffer == NULL) if (sound_buffer_size < bytes || sound_buffer == NULL)
{ {
sound_buffer = (uint8 *) realloc (sound_buffer, bytes); sound_buffer = (uint8 *)realloc(sound_buffer, bytes);
sound_buffer_size = bytes; sound_buffer_size = bytes;
} }
S9xMixSamples (sound_buffer, frames << 1); S9xMixSamples(sound_buffer, frames << 1);
Pa_WriteStream (audio_stream, sound_buffer, frames); Pa_WriteStream(audio_stream, sound_buffer, frames);
} }

View File

@ -7,29 +7,28 @@
#ifndef __GTK_SOUND_DRIVER_PORTAUDIO_H #ifndef __GTK_SOUND_DRIVER_PORTAUDIO_H
#define __GTK_SOUND_DRIVER_PORTAUDIO_H #define __GTK_SOUND_DRIVER_PORTAUDIO_H
#include <portaudio.h>
#include <errno.h> #include <errno.h>
#include <portaudio.h>
#include "gtk_sound.h" #include "gtk_sound.h"
#include "gtk_sound_driver.h" #include "gtk_sound_driver.h"
class S9xPortAudioSoundDriver : public S9xSoundDriver class S9xPortAudioSoundDriver : public S9xSoundDriver
{ {
public: public:
S9xPortAudioSoundDriver (); S9xPortAudioSoundDriver();
void init (); void init();
void terminate (); void terminate();
bool open_device (); bool open_device();
void start (); void start();
void stop (); void stop();
void samples_available (); void samples_available();
private: private:
PaStream *audio_stream; PaStream *audio_stream;
int sound_buffer_size; int sound_buffer_size;
uint8 *sound_buffer; uint8 *sound_buffer;
int output_buffer_size; int output_buffer_size;
}; };
#endif /* __GTK_SOUND_DRIVER_PORTAUDIO_H */ #endif /* __GTK_SOUND_DRIVER_PORTAUDIO_H */

View File

@ -4,12 +4,12 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "gtk_s9x.h"
#include "gtk_sound_driver_pulse.h" #include "gtk_sound_driver_pulse.h"
#include "gtk_s9x.h"
#include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <fcntl.h>
static void pulse_samples_available(void *data) static void pulse_samples_available(void *data)
{ {
@ -125,10 +125,8 @@ bool S9xPulseSoundDriver::open_device()
printf("PulseAudio sound driver initializing...\n"); printf("PulseAudio sound driver initializing...\n");
printf(" --> (%dhz, %s %s, %dms)...", printf(" --> (%dhz, 16-bit Stereo, %dms)...",
Settings.SoundPlaybackRate, Settings.SoundPlaybackRate,
"16-bit",
"Stereo",
gui_config->sound_buffer_size); gui_config->sound_buffer_size);
fflush(stdout); fflush(stdout);

View File

@ -13,25 +13,24 @@
class S9xPulseSoundDriver : public S9xSoundDriver class S9xPulseSoundDriver : public S9xSoundDriver
{ {
public: public:
S9xPulseSoundDriver (); S9xPulseSoundDriver();
void init (); void init();
void terminate (); void terminate();
bool open_device (); bool open_device();
void start (); void start();
void stop (); void stop();
void samples_available (); void samples_available();
void lock (); void lock();
void unlock (); void unlock();
void wait (); void wait();
pa_threaded_mainloop *mainloop; pa_threaded_mainloop *mainloop;
pa_context *context; pa_context *context;
pa_stream *stream; pa_stream *stream;
private:
int buffer_size;
private:
int buffer_size;
}; };
#endif /* __GTK_SOUND_DRIVER_PULSE_H */ #endif /* __GTK_SOUND_DRIVER_PULSE_H */

View File

@ -4,108 +4,101 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "gtk_s9x.h"
#include "gtk_sound_driver_sdl.h" #include "gtk_sound_driver_sdl.h"
#include "gtk_s9x.h"
static void static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
sdl_audio_callback (void *userdata, Uint8 *stream, int len)
{ {
((S9xSDLSoundDriver *) userdata)->mix ((unsigned char *) stream, len); ((S9xSDLSoundDriver *)userdata)->mix((unsigned char *)stream, len);
} }
static void static void samples_available(void *data)
samples_available (void *data)
{ {
SDL_LockAudio (); SDL_LockAudio();
S9xFinalizeSamples (); S9xFinalizeSamples();
SDL_UnlockAudio (); SDL_UnlockAudio();
} }
void void S9xSDLSoundDriver::mix(unsigned char *output, int bytes)
S9xSDLSoundDriver::mix (unsigned char *output, int bytes)
{ {
SDL_LockAudio (); SDL_LockAudio();
S9xMixSamples (output, bytes >> (Settings.SixteenBitSound ? 1 : 0)); S9xMixSamples(output, bytes >> 1);
SDL_UnlockAudio (); SDL_UnlockAudio();
} }
S9xSDLSoundDriver::S9xSDLSoundDriver () S9xSDLSoundDriver::S9xSDLSoundDriver()
{ {
audiospec = NULL; audiospec = NULL;
} }
void void S9xSDLSoundDriver::init()
S9xSDLSoundDriver::init ()
{ {
SDL_InitSubSystem (SDL_INIT_AUDIO); SDL_InitSubSystem(SDL_INIT_AUDIO);
stop (); stop();
} }
void void S9xSDLSoundDriver::terminate()
S9xSDLSoundDriver::terminate ()
{ {
stop (); stop();
if (audiospec) if (audiospec)
{ {
SDL_CloseAudio (); SDL_CloseAudio();
free (audiospec); free(audiospec);
audiospec = NULL; audiospec = NULL;
} }
SDL_QuitSubSystem (SDL_INIT_AUDIO); SDL_QuitSubSystem(SDL_INIT_AUDIO);
} }
void void S9xSDLSoundDriver::start()
S9xSDLSoundDriver::start ()
{ {
if (!gui_config->mute_sound) if (!gui_config->mute_sound)
{ {
if (audiospec) if (audiospec)
{ {
SDL_PauseAudio (0); SDL_PauseAudio(0);
} }
} }
} }
void void S9xSDLSoundDriver::stop()
S9xSDLSoundDriver::stop ()
{ {
if (audiospec) if (audiospec)
{ {
SDL_PauseAudio (1); SDL_PauseAudio(1);
} }
} }
bool S9xSDLSoundDriver::open_device() bool S9xSDLSoundDriver::open_device()
{ {
audiospec = (SDL_AudioSpec *) malloc (sizeof (SDL_AudioSpec)); audiospec = (SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
audiospec->freq = Settings.SoundPlaybackRate; audiospec->freq = Settings.SoundPlaybackRate;
audiospec->channels = Settings.Stereo ? 2 : 1; audiospec->channels = 2;
audiospec->format = Settings.SixteenBitSound ? AUDIO_S16SYS : AUDIO_U8; audiospec->format = AUDIO_S16SYS;
audiospec->samples = (gui_config->sound_buffer_size * audiospec->freq / 1000) >> 1; audiospec->samples = (gui_config->sound_buffer_size * audiospec->freq / 1000) >> 1;
audiospec->callback = sdl_audio_callback; audiospec->callback = sdl_audio_callback;
audiospec->userdata = this; audiospec->userdata = this;
printf ("SDL sound driver initializing...\n"); printf("SDL sound driver initializing...\n");
printf (" --> (Frequency: %dhz, Latency: %dms)...", printf(" --> (Frequency: %dhz, Latency: %dms)...",
audiospec->freq, audiospec->freq,
(audiospec->samples * 1000 / audiospec->freq) << 1); (audiospec->samples * 1000 / audiospec->freq) << 1);
if (SDL_OpenAudio (audiospec, NULL) < 0) if (SDL_OpenAudio(audiospec, NULL) < 0)
{ {
printf ("Failed\n"); printf("Failed\n");
free (audiospec); free(audiospec);
audiospec = NULL; audiospec = NULL;
return false; return false;
} }
printf ("OK\n"); printf("OK\n");
S9xSetSamplesAvailableCallback (samples_available, NULL); S9xSetSamplesAvailableCallback(samples_available, NULL);
return true; return true;
} }

View File

@ -14,18 +14,17 @@
class S9xSDLSoundDriver : public S9xSoundDriver class S9xSDLSoundDriver : public S9xSoundDriver
{ {
public: public:
S9xSDLSoundDriver (); S9xSDLSoundDriver();
void init (); void init();
void terminate (); void terminate();
bool open_device (); bool open_device();
void start (); void start();
void stop (); void stop();
void mix (unsigned char *output, int bytes); void mix(unsigned char *output, int bytes);
private: private:
SDL_AudioSpec *audiospec; SDL_AudioSpec *audiospec;
}; };
#endif /* __GTK_SOUND_DRIVER_SDL_H */ #endif /* __GTK_SOUND_DRIVER_SDL_H */

View File

@ -4218,22 +4218,6 @@
<property name="position">4</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="stereo_check">
<property name="label" translatable="yes">Stereo</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Output two channels, left and right</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
<child> <child>
<object class="GtkTable" id="table7"> <object class="GtkTable" id="table7">
<property name="visible">True</property> <property name="visible">True</property>
@ -4451,7 +4435,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">6</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
</object> </object>