#include "zx_speaker.h" #include #include "z80.h" #include namespace speaker { #define SAMPLING_FREQ 44100 #define AUDIO_BUFFER_SIZE 2048 SDL_AudioDeviceID sdlAudioDevice; uint8_t sound_buffer[AUDIO_BUFFER_SIZE]; uint16_t sound_pos=0; uint16_t t_sound=0; std::vector sources; float cycles_per_sample; void init() { SDL_AudioSpec audioSpec{SAMPLING_FREQ, AUDIO_U8, 1, 0, AUDIO_BUFFER_SIZE>>2, 0, 0, NULL, NULL}; sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); cycles_per_sample = z80::getClock() / SAMPLING_FREQ; enable(); } void enable() { SDL_PauseAudioDevice(sdlAudioDevice, 0); } void disable() { SDL_PauseAudioDevice(sdlAudioDevice, 1); } void register_source(uint8_t(*callback)()) { sources.push_back(callback); } void update(const uint8_t dt) { t_sound += dt; if (t_sound>=cycles_per_sample) { t_sound-=cycles_per_sample; uint32_t sample = 0; for (auto callback : sources) sample += callback(); sample /= sources.size(); sound_buffer[(sound_pos++)&(AUDIO_BUFFER_SIZE-1)] = sample; } if (sound_pos>=1000) { SDL_QueueAudio(sdlAudioDevice, sound_buffer, sound_pos); sound_pos = 0; while (SDL_GetQueuedAudioSize(sdlAudioDevice) > 4096 ) {} } } }