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);
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"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");
#undef z
@ -517,9 +514,6 @@ int Snes9xConfig::load_config_file ()
inbool (z"DynamicRateControl", Settings.DynamicRateControl);
inint (z"DynamicRateControlLimit", Settings.DynamicRateLimit);
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);
#undef z

View File

@ -633,7 +633,6 @@ Snes9xPreferences::move_settings_to_dialog ()
set_combo ("default_esc_behavior", config->default_esc_behavior);
set_check ("prevent_screensaver", config->prevent_screensaver);
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 ("hw_accel", combo_value (config->hw_accel));
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")) ||
(config->mute_sound != get_check ("mute_sound_check")) ||
(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_input_rate != get_slider ("sound_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.SuperFXClockMultiplier = get_spin ("superfx_multiplier");
config->sound_driver = get_combo ("sound_driver");
Settings.Stereo = get_check ("stereo_check");
config->sound_playback_rate = 7 - (get_combo ("playback_combo"));
config->sound_buffer_size = get_spin ("sound_buffer_size");
config->sound_input_rate = get_slider ("sound_input_rate");

View File

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

View File

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

View File

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

View File

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

View File

@ -4,58 +4,53 @@
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "gtk_s9x.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 <sys/ioctl.h>
#include <sys/soundcard.h>
#include <sys/time.h>
static void
oss_samples_available (void *data)
static void oss_samples_available(void *data)
{
((S9xOSSSoundDriver *) data)->samples_available ();
((S9xOSSSoundDriver *)data)->samples_available();
}
S9xOSSSoundDriver::S9xOSSSoundDriver ()
S9xOSSSoundDriver::S9xOSSSoundDriver()
{
filedes = -1;
sound_buffer = NULL;
sound_buffer_size = 0;
}
void
S9xOSSSoundDriver::init ()
void S9xOSSSoundDriver::init()
{
}
void
S9xOSSSoundDriver::terminate ()
void S9xOSSSoundDriver::terminate()
{
stop ();
stop();
S9xSetSamplesAvailableCallback (NULL, NULL);
S9xSetSamplesAvailableCallback(NULL, NULL);
if (filedes >= 0)
{
close (filedes);
close(filedes);
}
if (sound_buffer)
{
free (sound_buffer);
free(sound_buffer);
sound_buffer = NULL;
}
}
void
S9xOSSSoundDriver::start ()
void S9xOSSSoundDriver::start()
{
}
void
S9xOSSSoundDriver::stop ()
void S9xOSSSoundDriver::stop()
{
}
@ -70,110 +65,108 @@ bool S9xOSSSoundDriver::open_device()
if (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)
{
printf ("Failed.\n");
printf("Failed.\n");
char dspstring[16] = "/dev/dspX\0";
for (int i = 1; i <= 9; 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 (i == 9)
goto fail;
printf ("Failed.\n");
printf("Failed.\n");
}
else
break;
}
}
printf ("OK\n");
printf("OK\n");
printf (" --> (Format: 16-bit)...");
printf(" --> (Format: 16-bit)...");
temp = AFMT_S16_LE;
if (ioctl (filedes, SNDCTL_DSP_SETFMT, &temp) < 0)
if (ioctl(filedes, SNDCTL_DSP_SETFMT, &temp) < 0)
goto close_fail;
printf ("OK\n");
printf("OK\n");
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;
printf ("OK\n");
printf("OK\n");
printf (" --> (Frequency: %d)...", Settings.SoundPlaybackRate);
if (ioctl (filedes, SNDCTL_DSP_SPEED, &Settings.SoundPlaybackRate) < 0)
printf(" --> (Frequency: %d)...", Settings.SoundPlaybackRate);
if (ioctl(filedes, SNDCTL_DSP_SPEED, &Settings.SoundPlaybackRate) < 0)
goto close_fail;
printf ("OK\n");
printf("OK\n");
/* 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. */
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;
ioctl (filedes, SNDCTL_DSP_GETOSPACE, &info);
ioctl(filedes, SNDCTL_DSP_GETOSPACE, &info);
output_buffer_size = info.fragsize * info.fragstotal;
printf (" --> (Buffer size: %d bytes, %dms latency)...",
output_buffer_size,
(output_buffer_size * 250) / Settings.SoundPlaybackRate);
printf(" --> (Buffer size: %d bytes, %dms latency)...",
output_buffer_size,
(output_buffer_size * 250) / Settings.SoundPlaybackRate);
printf ("OK\n");
printf("OK\n");
S9xSetSamplesAvailableCallback (oss_samples_available, this);
S9xSetSamplesAvailableCallback(oss_samples_available, this);
return true;
close_fail:
close (filedes);
close(filedes);
fail:
printf ("failed\n");
printf("failed\n");
return false;
}
void
S9xOSSSoundDriver::samples_available ()
void S9xOSSSoundDriver::samples_available()
{
audio_buf_info info;
int samples_to_write;
int bytes_to_write;
int bytes_written;
ioctl (filedes, SNDCTL_DSP_GETOSPACE, &info);
ioctl(filedes, SNDCTL_DSP_GETOSPACE, &info);
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)
{
@ -181,23 +174,23 @@ S9xOSSSoundDriver::samples_available ()
// maintain an accurate measurement.
if (samples_to_write > (info.bytes >> 1))
{
S9xClearSamples ();
S9xClearSamples();
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)
return;
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;
}
S9xMixSamples (sound_buffer, samples_to_write);
S9xMixSamples(sound_buffer, samples_to_write);
bytes_written = 0;
bytes_to_write = samples_to_write * 2;
@ -206,9 +199,9 @@ S9xOSSSoundDriver::samples_available ()
{
int result;
result = write (filedes,
((char *) sound_buffer) + bytes_written,
bytes_to_write - bytes_written);
result = write(filedes,
((char *)sound_buffer) + bytes_written,
bytes_to_write - bytes_written);
if (result < 0)
break;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4218,22 +4218,6 @@
<property name="position">4</property>
</packing>
</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>
<object class="GtkTable" id="table7">
<property name="visible">True</property>
@ -4451,7 +4435,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
<property name="position">5</property>
</packing>
</child>
</object>