From 713ad8f45f92fee69d359d0dab79b67d72ef5c01 Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Sat, 4 Jan 2025 10:13:20 -0800 Subject: [PATCH] Actually add SDL audio source and blip_buf link --- Makefile | 2 +- blip-buf | 1 + src/audio.c | 17 ++++++++++++++ src/audio.h | 37 ++++++++++++++++++++++++++++++ src/sdl_audio.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 120000 blip-buf create mode 100644 src/audio.c create mode 100644 src/audio.h create mode 100644 src/sdl_audio.c diff --git a/Makefile b/Makefile index 36270fa..b885cbf 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ LDLIBS_1 = -lSDL2 SRC_SRCS_1 = nese.c ines.c SRC_SRCS_1 += nes.c ppu.c input.c SRC_SRCS_1 += cart.c mapper.c -SRC_SRCS_1 += apu.c +SRC_SRCS_1 += apu.c audio.c SRC_SRCS_1 += sdl_render.c sdl_input.c sdl_audio.c MAPDIR = src/map diff --git a/blip-buf b/blip-buf new file mode 120000 index 0000000..58cedc6 --- /dev/null +++ b/blip-buf @@ -0,0 +1 @@ +../blip-buf \ No newline at end of file diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 0000000..50c0c2e --- /dev/null +++ b/src/audio.c @@ -0,0 +1,17 @@ +#include "audio.h" +#include "blip-buf/blip_buf.h" + + +int nes_audio_fill(nes_Audio_Stream* stream, nes_apu* apu) { + int status = 0; + blip_end_frame(apu->blip, apu->time); + apu->time = 0; + while (status == 0 && blip_samples_avail(apu->blip) > 0) { + short samples[1024]; + int n_samples = blip_read_samples( + apu->blip, samples, 1024, 0 + ); + status = nes_audio_push(stream, samples, n_samples); + } + return status; +} diff --git a/src/audio.h b/src/audio.h new file mode 100644 index 0000000..4fe230f --- /dev/null +++ b/src/audio.h @@ -0,0 +1,37 @@ +#ifndef NES_AUDIO_H_ +#define NES_AUDIO_H_ + +#include "apu.h" + + +// System Glue + +typedef struct nes_Audio_Stream_t { + int (*init)(struct nes_Audio_Stream_t*, int frequency); + void (*done)(struct nes_Audio_Stream_t*); + int (*push)(struct nes_Audio_Stream_t*, short*, int); + void* data; +} nes_Audio_Stream; + + +static inline int nes_audio_init(nes_Audio_Stream* stream, + int frequency) { + return stream->init(stream, frequency); +} + +static inline void nes_audio_done(nes_Audio_Stream* stream) { + stream->done(stream); +} + +static inline int nes_audio_push(nes_Audio_Stream* stream, + short* samples, int n_samples) { + return stream->push(stream, samples, n_samples); +} + + +// Convenience + +int nes_audio_fill(nes_Audio_Stream* stream, nes_apu* apu); + + +#endif // NES_AUDIO_H_ diff --git a/src/sdl_audio.c b/src/sdl_audio.c new file mode 100644 index 0000000..9e02298 --- /dev/null +++ b/src/sdl_audio.c @@ -0,0 +1,60 @@ +#include + +#include "audio.h" + + +typedef struct { + SDL_AudioDeviceID id; +} sdl_audio_device; + +static sdl_audio_device the_audio_device = {0}; + + +int sdl_audio_init(nes_Audio_Stream* stream, int frequency) { + int status = SDL_Init(SDL_INIT_AUDIO); + + if (0 == status) { + sdl_audio_device* device = &the_audio_device; + + SDL_AudioSpec as = { + .freq = frequency, + .format = AUDIO_S16SYS, + .channels = 1, + }; + + device->id = SDL_OpenAudioDevice(NULL, 0, &as, NULL, 0); + if (0 == device->id) { + printf("SDL: %s\n", SDL_GetError()); + status = -1; + } else { + stream->data = device; + SDL_PauseAudioDevice(device->id, 0); + } + } + + return status; +} + +void sdl_audio_done(nes_Audio_Stream* stream) { + if (stream->data) { + SDL_CloseAudioDevice( + ((sdl_audio_device*)stream->data)->id + ); + stream->data = NULL; + } +} + +int sdl_audio_push(nes_Audio_Stream* stream, + short* samples, int n_samples) { + return SDL_QueueAudio( + ((sdl_audio_device*)stream->data)->id, + samples, n_samples * sizeof(short) + ); +} + + +nes_Audio_Stream sdl_audio = { + .init = sdl_audio_init, + .done = sdl_audio_done, + .push = sdl_audio_push, +};