#include "speaker.h" #include #include #include namespace speaker { int sampling_freq = 44100; uint16_t audio_buffer_size = 1024; SDL_AudioStream* sdlAudioStream = nullptr; uint8_t *sound_buffer = nullptr; uint16_t sound_pos=0; float t_sound=0.0f; float cycles_per_sample = 0.0f; std::vector sources; void init(float clock_frequency) { if (sound_buffer) quit(); SDL_AudioSpec audioSpec{SDL_AUDIO_U8, 1, sampling_freq}; sdlAudioStream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audioSpec, nullptr, nullptr); cycles_per_sample = clock_frequency / (float)sampling_freq; sound_buffer = (uint8_t*)malloc(audio_buffer_size); sound_pos = 0; t_sound = 0.0f; enable(); } void quit() { disable(); sources.clear(); if (sound_buffer) { free(sound_buffer); sound_buffer = nullptr; } if (sdlAudioStream) { SDL_DestroyAudioStream(sdlAudioStream); sdlAudioStream = nullptr; } } void enable() { SDL_ResumeAudioStreamDevice(sdlAudioStream); } void disable() { SDL_PauseAudioStreamDevice(sdlAudioStream); } void register_source(uint8_t(*callback)()) { sources.push_back(callback); } void update(const uint32_t dt) { t_sound += (float)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++] = (uint8_t)sample; } if (sound_pos >= audio_buffer_size) { SDL_PutAudioStreamData(sdlAudioStream, sound_buffer, sound_pos); sound_pos = 0; while (SDL_GetAudioStreamQueued(sdlAudioStream) > 2048) { SDL_Delay(1); } } } }