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 \
|
||||
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 \
|
||||
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 \
|
||||
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 \
|
||||
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
|
||||
USRCS = readtape.c maketape.c pngtorgba.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 "conf.h"
|
||||
#include <stdio.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_thread.h>
|
||||
#include <SDL/SDL_mutex.h>
|
||||
#include <libintl.h>
|
||||
#define _(String) gettext (String)
|
||||
#include "intl.h"
|
||||
|
||||
#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 */
|
||||
|
||||
unsigned io_sound_bufsize,
|
||||
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);
|
||||
}
|
||||
unsigned io_sound_freq = 44100;
|
||||
|
||||
/* Called after every instruction */
|
||||
void sound_flush() {
|
||||
int i;
|
||||
if (fullspeed && io_sound_age >= io_max_sound_age && covox_age >= io_max_sound_age) {
|
||||
if (sound_buf[cur_buf].ptr != 0)
|
||||
{
|
||||
SDL_SemWait(sem);
|
||||
sound_buf[cur_buf].ptr = 0;
|
||||
cur_buf = (cur_buf + 1) % NUMBUF;
|
||||
}
|
||||
platform_sound_flush();
|
||||
return;
|
||||
}
|
||||
while (ticks >= io_sound_count) {
|
||||
short * p = &sound_buf[cur_buf].buf[sound_buf[cur_buf].ptr++];
|
||||
if (io_sound_age < 1000)
|
||||
*p = io_sound_val + covox_val << 4;
|
||||
sound_write_sample (io_sound_val + covox_val << 4);
|
||||
else
|
||||
*p = (covox_val << 4) + synth_next();
|
||||
io_sound_count += io_sound_pace;
|
||||
sound_write_sample ((covox_val << 4) + synth_next());
|
||||
io_sound_age++;
|
||||
if (io_sound_age == io_max_sound_age) {
|
||||
platform_sound_flush();
|
||||
}
|
||||
covox_age++;
|
||||
if (io_sound_bufsize == sound_buf[cur_buf].ptr ||
|
||||
io_sound_age == io_max_sound_age) {
|
||||
SDL_SemWait(sem);
|
||||
sound_buf[cur_buf].ptr = 0;
|
||||
cur_buf = (cur_buf + 1) % NUMBUF;
|
||||
|
||||
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() {
|
||||
static init_done = 0;
|
||||
int iarg, i;
|
||||
io_max_sound_age = MAX_SOUND_AGE;
|
||||
io_sound_age = MAX_SOUND_AGE;
|
||||
|
||||
static int init_done = 0;
|
||||
if (!nflag)
|
||||
return;
|
||||
if (fullspeed) {
|
||||
io_max_sound_age = 2 * SOUND_BUFSIZE;
|
||||
/* otherwise UINT_MAX */
|
||||
}
|
||||
if (init_done) {
|
||||
sound_buf[cur_buf].ptr = 0;
|
||||
io_sound_age = io_max_sound_age;
|
||||
return;
|
||||
}
|
||||
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;
|
||||
sound_discard();
|
||||
return;
|
||||
}
|
||||
|
||||
io_sound_pace = TICK_RATE/io_sound_freq;
|
||||
sem = SDL_CreateSemaphore(NUMBUF);
|
||||
platform_sound_init();
|
||||
|
||||
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);
|
||||
io_sound_pace = TICK_RATE/(io_sound_freq + 0.0);
|
||||
io_max_sound_age = MAX_SOUND_AGE;
|
||||
io_sound_age = MAX_SOUND_AGE; /* in io_sound_pace's since last change */
|
||||
init_done = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user