snes9x/common/audio/s9x_sound_driver_sdl.cpp

99 lines
2.3 KiB
C++
Raw Normal View History

/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
#include "s9x_sound_driver_sdl.hpp"
#include "SDL_audio.h"
2010-09-25 15:46:12 +00:00
void S9xSDLSoundDriver::write_samples(int16_t *data, int samples)
2019-02-10 01:18:45 +00:00
{
mutex.lock();
if (samples > buffer.space_empty())
samples = buffer.space_empty();
buffer.push(data, samples);
2019-02-10 01:18:45 +00:00
mutex.unlock();
2010-09-25 15:46:12 +00:00
}
void S9xSDLSoundDriver::mix(unsigned char *output, int bytes)
2010-09-25 15:46:12 +00:00
{
2019-02-10 01:18:45 +00:00
mutex.lock();
2019-05-14 20:34:25 +00:00
if (buffer.avail() >= bytes >> 1)
buffer.read((int16_t *)output, bytes >> 1);
2019-02-10 01:18:45 +00:00
mutex.unlock();
2010-09-25 15:46:12 +00:00
}
S9xSDLSoundDriver::S9xSDLSoundDriver()
2010-09-25 15:46:12 +00:00
{
}
void S9xSDLSoundDriver::init()
2010-09-25 15:46:12 +00:00
{
SDL_InitSubSystem(SDL_INIT_AUDIO);
stop();
2010-09-25 15:46:12 +00:00
}
void S9xSDLSoundDriver::deinit()
2010-09-25 15:46:12 +00:00
{
stop();
2019-05-14 20:34:25 +00:00
SDL_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
2010-09-25 15:46:12 +00:00
}
void S9xSDLSoundDriver::start()
2010-09-25 15:46:12 +00:00
{
SDL_PauseAudio(0);
2010-09-25 15:46:12 +00:00
}
void S9xSDLSoundDriver::stop()
2010-09-25 15:46:12 +00:00
{
2019-05-14 20:34:25 +00:00
SDL_PauseAudio(1);
2010-09-25 15:46:12 +00:00
}
bool S9xSDLSoundDriver::open_device(int playback_rate, int buffer_size)
2010-09-25 15:46:12 +00:00
{
2019-05-14 20:34:25 +00:00
audiospec = {};
audiospec.freq = playback_rate;
2019-05-14 20:34:25 +00:00
audiospec.channels = 2;
audiospec.format = AUDIO_S16SYS;
audiospec.samples = audiospec.freq * 4 / 1000; // 4ms per sampling
audiospec.callback = [](void *userdata, uint8_t *stream, int len) {
((S9xSDLSoundDriver *)userdata)->mix((unsigned char *)stream, len);
};
2019-05-14 20:34:25 +00:00
audiospec.userdata = this;
2010-09-25 15:46:12 +00:00
printf("SDL sound driver initializing...\n");
printf(" --> (Frequency: %dhz, Latency: %dms)...",
2019-05-14 20:34:25 +00:00
audiospec.freq,
(audiospec.samples * 1000 / audiospec.freq));
2010-09-25 15:46:12 +00:00
2019-05-14 20:34:25 +00:00
if (SDL_OpenAudio(&audiospec, NULL) < 0)
2010-09-25 15:46:12 +00:00
{
printf("Failed\n");
return false;
2010-09-25 15:46:12 +00:00
}
printf("OK\n");
2010-09-25 15:46:12 +00:00
buffer.resize(buffer_size * audiospec.freq / 1000);
2010-09-25 15:46:12 +00:00
return true;
2010-09-25 15:46:12 +00:00
}
int S9xSDLSoundDriver::space_free()
{
mutex.lock();
auto space_empty = buffer.space_empty();
mutex.unlock();
return space_empty;
}
std::pair<int, int> S9xSDLSoundDriver::buffer_level()
{
mutex.lock();
std::pair<int, int> level = { buffer.space_empty(), buffer.buffer_size };
mutex.unlock();
return level;
}