summaryrefslogtreecommitdiff
path: root/pcsound
diff options
context:
space:
mode:
Diffstat (limited to 'pcsound')
-rw-r--r--pcsound/pcsound.c8
-rw-r--r--pcsound/pcsound.h21
-rw-r--r--pcsound/pcsound_internal.h47
-rw-r--r--pcsound/pcsound_linux.c1
-rw-r--r--pcsound/pcsound_sdl.c63
-rw-r--r--pcsound/pcsound_win32.c1
6 files changed, 122 insertions, 19 deletions
diff --git a/pcsound/pcsound.c b/pcsound/pcsound.c
index 1491ff61..8c739b35 100644
--- a/pcsound/pcsound.c
+++ b/pcsound/pcsound.c
@@ -29,6 +29,7 @@
#include "config.h"
#include "pcsound.h"
+#include "pcsound_internal.h"
#ifdef _WIN32
extern pcsound_driver_t pcsound_win32_driver;
@@ -54,6 +55,13 @@ static pcsound_driver_t *drivers[] =
static pcsound_driver_t *pcsound_driver = NULL;
+int pcsound_sample_rate;
+
+void PCSound_SetSampleRate(int rate)
+{
+ pcsound_sample_rate = rate;
+}
+
int PCSound_Init(pcsound_callback_func callback_func)
{
char *driver_name;
diff --git a/pcsound/pcsound.h b/pcsound/pcsound.h
index 12a4ffe9..e64796b8 100644
--- a/pcsound/pcsound.h
+++ b/pcsound/pcsound.h
@@ -26,22 +26,21 @@
#ifndef PCSOUND_H
#define PCSOUND_H
-#define PCSOUND_8253_FREQUENCY 1193280
-
-typedef struct pcsound_driver_s pcsound_driver_t;
typedef void (*pcsound_callback_func)(int *duration, int *frequency);
-typedef int (*pcsound_init_func)(pcsound_callback_func callback);
-typedef void (*pcsound_shutdown_func)(void);
-struct pcsound_driver_s
-{
- char *name;
- pcsound_init_func init_func;
- pcsound_shutdown_func shutdown_func;
-};
+// Initialise the PC speaker subsystem. The given function is called
+// periodically to request more sound data to play.
int PCSound_Init(pcsound_callback_func callback_func);
+
+// Shut down the PC speaker subsystem.
+
void PCSound_Shutdown(void);
+// Set the preferred output sample rate when emulating a PC speaker.
+// This must be called before PCSound_Init.
+
+void PCSound_SetSampleRate(int rate);
+
#endif /* #ifndef PCSOUND_H */
diff --git a/pcsound/pcsound_internal.h b/pcsound/pcsound_internal.h
new file mode 100644
index 00000000..c5ae90b6
--- /dev/null
+++ b/pcsound/pcsound_internal.h
@@ -0,0 +1,47 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 2007 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION:
+// PC speaker interface.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef PCSOUND_INTERNAL_H
+#define PCSOUND_INTERNAL_H
+
+#include "pcsound.h"
+
+#define PCSOUND_8253_FREQUENCY 1193280
+
+typedef struct pcsound_driver_s pcsound_driver_t;
+typedef int (*pcsound_init_func)(pcsound_callback_func callback);
+typedef void (*pcsound_shutdown_func)(void);
+
+struct pcsound_driver_s
+{
+ char *name;
+ pcsound_init_func init_func;
+ pcsound_shutdown_func shutdown_func;
+};
+
+extern int pcsound_sample_rate;
+
+#endif /* #ifndef PCSOUND_INTERNAL_H */
+
diff --git a/pcsound/pcsound_linux.c b/pcsound/pcsound_linux.c
index 7c1abc7b..02ab47b5 100644
--- a/pcsound/pcsound_linux.c
+++ b/pcsound/pcsound_linux.c
@@ -40,6 +40,7 @@
#include "SDL_thread.h"
#include "pcsound.h"
+#include "pcsound_internal.h"
#define CONSOLE_DEVICE "/dev/console"
diff --git a/pcsound/pcsound_sdl.c b/pcsound/pcsound_sdl.c
index 50820394..f862dfa7 100644
--- a/pcsound/pcsound_sdl.c
+++ b/pcsound/pcsound_sdl.c
@@ -30,9 +30,17 @@
#include "SDL_mixer.h"
#include "pcsound.h"
+#include "pcsound_internal.h"
#define SQUARE_WAVE_AMP 0x2000
+// If true, we initialised SDL and have the responsibility to shut it
+// down
+
+static int sdl_was_initialised = 0;
+
+// Callback function to invoke when we want new sound data
+
static pcsound_callback_func callback;
// Output sound format
@@ -137,16 +145,57 @@ static void PCSound_Mix_Callback(void *udata, Uint8 *stream, int len)
}
}
+static int SDLIsInitialised(void)
+{
+ int freq, channels;
+ Uint16 format;
+
+ return Mix_QuerySpec(&freq, &format, &channels);
+}
+
+static void PCSound_SDL_Shutdown(void)
+{
+ if (sdl_was_initialised)
+ {
+ Mix_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ sdl_was_initialised = 0;
+ }
+}
+
static int PCSound_SDL_Init(pcsound_callback_func callback_func)
{
- // Check that SDL_mixer has been opened already
- // If not, fail
+ // Check if SDL_mixer has been opened already
+ // If not, we must initialise it now
- if (!Mix_QuerySpec(&mixing_freq, &mixing_format, &mixing_channels))
+ if (!SDLIsInitialised())
{
- return 0;
+ if (SDL_Init(SDL_INIT_AUDIO) < 0)
+ {
+ fprintf(stderr, "Unable to set up sound.\n");
+ return 0;
+ }
+
+ if (Mix_OpenAudio(pcsound_sample_rate, AUDIO_S16SYS, 2, 1024) < 0)
+ {
+ fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
+
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return 0;
+ }
+
+ SDL_PauseAudio(0);
+
+ // When this module shuts down, it has the responsibility to
+ // shut down SDL.
+
+ sdl_was_initialised = 1;
}
+ // Get the mixer frequency, format and number of channels.
+
+ Mix_QuerySpec(&mixing_freq, &mixing_format, &mixing_channels);
+
// Only supports AUDIO_S16SYS
if (mixing_format != AUDIO_S16SYS || mixing_channels != 2)
@@ -154,6 +203,8 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
fprintf(stderr,
"PCSound_SDL only supports native signed 16-bit LSB, "
"stereo format!\n");
+
+ PCSound_SDL_Shutdown();
return 0;
}
@@ -166,10 +217,6 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
return 1;
}
-static void PCSound_SDL_Shutdown(void)
-{
-}
-
pcsound_driver_t pcsound_sdl_driver =
{
"SDL",
diff --git a/pcsound/pcsound_win32.c b/pcsound/pcsound_win32.c
index 48677d73..7976b444 100644
--- a/pcsound/pcsound_win32.c
+++ b/pcsound/pcsound_win32.c
@@ -29,6 +29,7 @@
#include <windows.h>
#include "pcsound.h"
+#include "pcsound_internal.h"
static SDL_Thread *sound_thread_handle;
static int sound_thread_running;