|
|
|
@@ -0,0 +1,60 @@ |
|
|
|
#include <SDL2/SDL.h> |
|
|
|
|
|
|
|
#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, |
|
|
|
}; |