mirror of
https://github.com/libretro/bk-emulator.git
synced 2024-11-23 08:49:54 +00:00
Encapsulate SDL-sound code into separate file
This commit is contained in:
parent
f2b872c46f
commit
bef7ae60a5
4
Makefile
4
Makefile
@ -49,11 +49,11 @@ UTILS = maketape readtape
|
|||||||
SRCS = access.c boot.c branch.c conf.c covox.c double.c ea.c itab.c \
|
SRCS = access.c boot.c branch.c conf.c covox.c double.c ea.c itab.c \
|
||||||
main.c service.c ui.c scr-sdl.c scr.c timer.c tape.c disk.c mouse.c printer.c \
|
main.c service.c ui.c scr-sdl.c scr.c timer.c tape.c disk.c mouse.c printer.c \
|
||||||
single.c weird.c tty.c io.c timing.c sound.c disas.c serial.c bkplip.c \
|
single.c weird.c tty.c io.c timing.c sound.c disas.c serial.c bkplip.c \
|
||||||
terakdisk.c synth.c emu2149.c sdltty.c
|
terakdisk.c synth.c emu2149.c sdlsound.c sdltty.c
|
||||||
OBJS = access.o boot.o branch.o conf.o covox.o double.o ea.o itab.o icon.o \
|
OBJS = access.o boot.o branch.o conf.o covox.o double.o ea.o itab.o icon.o \
|
||||||
main.o service.o ui.o scr-sdl.o scr.o timer.o tape.o disk.o mouse.o printer.o \
|
main.o service.o ui.o scr-sdl.o scr.o timer.o tape.o disk.o mouse.o printer.o \
|
||||||
single.o weird.o tty.o io.o timing.o sound.o disas.o serial.o bkplip.o \
|
single.o weird.o tty.o io.o timing.o sound.o disas.o serial.o bkplip.o \
|
||||||
terakdisk.o synth.o emu2149.o sdltty.o
|
terakdisk.o synth.o emu2149.o sdlsound.o sdltty.o
|
||||||
INCS = defines.h scr.h conf.h emu2149.h emutypes.h
|
INCS = defines.h scr.h conf.h emu2149.h emutypes.h
|
||||||
USRCS = readtape.c maketape.c pngtorgba.c
|
USRCS = readtape.c maketape.c pngtorgba.c
|
||||||
TEXTS = README.html configure.in icon.c
|
TEXTS = README.html configure.in icon.c
|
||||||
|
109
sdlsound.c
Normal file
109
sdlsound.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#include "defines.h"
|
||||||
|
#include "conf.h"
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <SDL/SDL_thread.h>
|
||||||
|
#include <SDL/SDL_mutex.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#define _(String) gettext (String)
|
||||||
|
|
||||||
|
//#define SOUND_EXPONENT (8+io_sound_freq/20000)
|
||||||
|
//#define SOUND_BUFSIZE (1<<SOUND_EXPONENT) /* about 1/43 sec */
|
||||||
|
#define SOUND_BUFSIZE 512
|
||||||
|
|
||||||
|
#define NUMBUF 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short * buf;
|
||||||
|
unsigned int ptr;
|
||||||
|
} sound_buf_t;
|
||||||
|
|
||||||
|
sound_buf_t sound_buf[NUMBUF];
|
||||||
|
unsigned io_sound_bufsize;
|
||||||
|
|
||||||
|
int cur_buf;
|
||||||
|
|
||||||
|
static SDL_sem * sem;
|
||||||
|
|
||||||
|
static void callback(void * dummy, Uint8 * outbuf, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int cur_out_buf;
|
||||||
|
if (SDL_SemValue(sem) == NUMBUF) {
|
||||||
|
// Underflow: TODO fill the buffer with silence
|
||||||
|
// fprintf(stderr, "!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(outbuf, sound_buf[cur_out_buf].buf, len);
|
||||||
|
cur_out_buf = (cur_out_buf + 1) % NUMBUF;
|
||||||
|
SDL_SemPost(sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sound_finish() {
|
||||||
|
/* release the write thread so it can terminate */
|
||||||
|
SDL_PauseAudio(1);
|
||||||
|
SDL_DestroySemaphore(sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_AudioSpec desired;
|
||||||
|
|
||||||
|
void platform_sound_flush() {
|
||||||
|
if (sound_buf[cur_buf].ptr != 0) {
|
||||||
|
SDL_SemWait(sem);
|
||||||
|
sound_buf[cur_buf].ptr = 0;
|
||||||
|
cur_buf = (cur_buf + 1) % NUMBUF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_write_sample(short val) {
|
||||||
|
short * p = &sound_buf[cur_buf].buf[sound_buf[cur_buf].ptr++];
|
||||||
|
if (sound_buf[cur_buf].buf == NULL)
|
||||||
|
return;
|
||||||
|
*p = val;
|
||||||
|
if (io_sound_bufsize == sound_buf[cur_buf].ptr) {
|
||||||
|
platform_sound_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_discard() {
|
||||||
|
sound_buf[cur_buf].ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_sound_init() {
|
||||||
|
int iarg, i;
|
||||||
|
|
||||||
|
if (fullspeed) {
|
||||||
|
io_max_sound_age = 2 * SOUND_BUFSIZE;
|
||||||
|
/* otherwise UINT_MAX */
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, _("sound_init called\n"));
|
||||||
|
|
||||||
|
if (-1 == SDL_InitSubSystem(SDL_INIT_AUDIO)) {
|
||||||
|
fprintf(stderr, _("Failed to initialize audio subsystem\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
desired.format = 16;
|
||||||
|
desired.channels = 1;
|
||||||
|
desired.freq = io_sound_freq;
|
||||||
|
desired.samples = io_sound_bufsize = SOUND_BUFSIZE;
|
||||||
|
desired.callback = callback;
|
||||||
|
if (-1 == SDL_OpenAudio(&desired, 0)) {
|
||||||
|
fprintf(stderr, _("Failed to initialize sound, freq %d, %d samples\n"), io_sound_freq, SOUND_BUFSIZE);
|
||||||
|
nflag = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sem = SDL_CreateSemaphore(NUMBUF);
|
||||||
|
|
||||||
|
for (i = 0; i < NUMBUF; i++) {
|
||||||
|
sound_buf[i].ptr = 0;
|
||||||
|
sound_buf[i].buf = malloc(io_sound_bufsize * sizeof(short));
|
||||||
|
}
|
||||||
|
if (!sound_buf[NUMBUF-1].buf) {
|
||||||
|
fprintf(stderr, _("Failed to allocate sound buffers\n"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(sound_finish);
|
||||||
|
SDL_PauseAudio(0);
|
||||||
|
}
|
117
sound.c
117
sound.c
@ -1,131 +1,46 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "conf.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL/SDL.h>
|
#include "intl.h"
|
||||||
#include <SDL/SDL_thread.h>
|
|
||||||
#include <SDL/SDL_mutex.h>
|
|
||||||
#include <libintl.h>
|
|
||||||
#define _(String) gettext (String)
|
|
||||||
|
|
||||||
#define SOUND_EXPONENT (8+io_sound_freq/20000)
|
|
||||||
//#define SOUND_BUFSIZE (1<<SOUND_EXPONENT) /* about 1/43 sec */
|
|
||||||
#define SOUND_BUFSIZE 512
|
|
||||||
#define MAX_SOUND_AGE ~0 /* always play */
|
#define MAX_SOUND_AGE ~0 /* always play */
|
||||||
|
|
||||||
unsigned io_sound_bufsize,
|
unsigned io_sound_freq = 44100;
|
||||||
io_sound_freq = 11025;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
short * buf;
|
|
||||||
unsigned int ptr;
|
|
||||||
} sound_buf_t;
|
|
||||||
|
|
||||||
#define NUMBUF 2
|
|
||||||
|
|
||||||
sound_buf_t sound_buf[NUMBUF];
|
|
||||||
|
|
||||||
SDL_sem * sem;
|
|
||||||
|
|
||||||
int cur_buf;
|
|
||||||
|
|
||||||
void callback(void * dummy, Uint8 * outbuf, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
static int cur_out_buf;
|
|
||||||
if (SDL_SemValue(sem) == NUMBUF) {
|
|
||||||
// Underflow: TODO fill the buffer with silence
|
|
||||||
// fprintf(stderr, "!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(outbuf, sound_buf[cur_out_buf].buf, len);
|
|
||||||
cur_out_buf = (cur_out_buf + 1) % NUMBUF;
|
|
||||||
SDL_SemPost(sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called after every instruction */
|
/* Called after every instruction */
|
||||||
void sound_flush() {
|
void sound_flush() {
|
||||||
int i;
|
|
||||||
if (fullspeed && io_sound_age >= io_max_sound_age && covox_age >= io_max_sound_age) {
|
if (fullspeed && io_sound_age >= io_max_sound_age && covox_age >= io_max_sound_age) {
|
||||||
if (sound_buf[cur_buf].ptr != 0)
|
platform_sound_flush();
|
||||||
{
|
|
||||||
SDL_SemWait(sem);
|
|
||||||
sound_buf[cur_buf].ptr = 0;
|
|
||||||
cur_buf = (cur_buf + 1) % NUMBUF;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (ticks >= io_sound_count) {
|
while (ticks >= io_sound_count) {
|
||||||
short * p = &sound_buf[cur_buf].buf[sound_buf[cur_buf].ptr++];
|
|
||||||
if (io_sound_age < 1000)
|
if (io_sound_age < 1000)
|
||||||
*p = io_sound_val + covox_val << 4;
|
sound_write_sample (io_sound_val + covox_val << 4);
|
||||||
else
|
else
|
||||||
*p = (covox_val << 4) + synth_next();
|
sound_write_sample ((covox_val << 4) + synth_next());
|
||||||
io_sound_count += io_sound_pace;
|
|
||||||
io_sound_age++;
|
io_sound_age++;
|
||||||
covox_age++;
|
if (io_sound_age == io_max_sound_age) {
|
||||||
if (io_sound_bufsize == sound_buf[cur_buf].ptr ||
|
platform_sound_flush();
|
||||||
io_sound_age == io_max_sound_age) {
|
|
||||||
SDL_SemWait(sem);
|
|
||||||
sound_buf[cur_buf].ptr = 0;
|
|
||||||
cur_buf = (cur_buf + 1) % NUMBUF;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
covox_age++;
|
||||||
|
io_sound_count += io_sound_pace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_finish() {
|
|
||||||
/* release the write thread so it can terminate */
|
|
||||||
SDL_PauseAudio(1);
|
|
||||||
SDL_DestroySemaphore(sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_AudioSpec desired;
|
|
||||||
|
|
||||||
void sound_init() {
|
void sound_init() {
|
||||||
static init_done = 0;
|
static int init_done = 0;
|
||||||
int iarg, i;
|
|
||||||
io_max_sound_age = MAX_SOUND_AGE;
|
|
||||||
io_sound_age = MAX_SOUND_AGE;
|
|
||||||
|
|
||||||
if (!nflag)
|
if (!nflag)
|
||||||
return;
|
return;
|
||||||
if (fullspeed) {
|
|
||||||
io_max_sound_age = 2 * SOUND_BUFSIZE;
|
|
||||||
/* otherwise UINT_MAX */
|
|
||||||
}
|
|
||||||
if (init_done) {
|
if (init_done) {
|
||||||
sound_buf[cur_buf].ptr = 0;
|
|
||||||
io_sound_age = io_max_sound_age;
|
io_sound_age = io_max_sound_age;
|
||||||
return;
|
sound_discard();
|
||||||
}
|
|
||||||
fprintf(stderr, _("sound_init called\n"));
|
|
||||||
|
|
||||||
if (-1 == SDL_InitSubSystem(SDL_INIT_AUDIO)) {
|
|
||||||
fprintf(stderr, _("Failed to initialize audio subsystem\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
desired.format = 16;
|
|
||||||
desired.channels = 1;
|
|
||||||
desired.freq = io_sound_freq;
|
|
||||||
desired.samples = io_sound_bufsize = SOUND_BUFSIZE;
|
|
||||||
desired.callback = callback;
|
|
||||||
if (-1 == SDL_OpenAudio(&desired, 0)) {
|
|
||||||
fprintf(stderr, _("Failed to initialize sound, freq %d, %d samples\n"), io_sound_freq, SOUND_BUFSIZE);
|
|
||||||
nflag = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
io_sound_pace = TICK_RATE/io_sound_freq;
|
platform_sound_init();
|
||||||
sem = SDL_CreateSemaphore(NUMBUF);
|
|
||||||
|
|
||||||
for (i = 0; i < NUMBUF; i++) {
|
io_sound_pace = TICK_RATE/(io_sound_freq + 0.0);
|
||||||
sound_buf[i].ptr = 0;
|
io_max_sound_age = MAX_SOUND_AGE;
|
||||||
sound_buf[i].buf = malloc(io_sound_bufsize * sizeof(short));
|
io_sound_age = MAX_SOUND_AGE; /* in io_sound_pace's since last change */
|
||||||
}
|
|
||||||
if (!sound_buf[NUMBUF-1].buf) {
|
|
||||||
fprintf(stderr, _("Failed to allocate sound buffers\n"));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
atexit(sound_finish);
|
|
||||||
SDL_PauseAudio(0);
|
|
||||||
init_done = 1;
|
init_done = 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user