From bc6e3672d16864d4f77a1e6ac14d90c411be7ba0 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 25 Dec 2018 00:48:08 +1100 Subject: clean up sdl_sound a bit (nw) --- src/osd/modules/sound/sdl_sound.cpp | 187 ++++++++++++++---------------------- 1 file changed, 74 insertions(+), 113 deletions(-) diff --git a/src/osd/modules/sound/sdl_sound.cpp b/src/osd/modules/sound/sdl_sound.cpp index b59f0cf9ea2..a04a44c0298 100644 --- a/src/osd/modules/sound/sdl_sound.cpp +++ b/src/osd/modules/sound/sdl_sound.cpp @@ -22,50 +22,29 @@ #include "../../sdl/osdsdl.h" +#include +#include +#include + //============================================================ // DEBUGGING //============================================================ #define LOG_SOUND 0 -//============================================================ -// PROTOTYPES -//============================================================ - -static void sdl_callback(void *userdata, Uint8 *stream, int len); - //============================================================ // CLASS //============================================================ -class ring_buffer -{ -public: - ring_buffer(size_t size); - virtual ~ring_buffer(); - - size_t data_size(); - size_t free_size(); - int append(const void *data, size_t size); - int pop(void *data, size_t size); - -private: - int8_t *buffer; - size_t buffer_size; - int head, tail; -}; - class sound_sdl : public osd_module, public sound_module { public: - friend void sdl_callback(void *userdata, Uint8 *stream, int len); - // number of samples per SDL callback static const int SDL_XFER_SAMPLES = 512; - sound_sdl() - : osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(), + sound_sdl() : + osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(), stream_in_initialized(0), stream_loop(0), attenuation(0), buf_locked(0), stream_buffer(nullptr), stream_buffer_size(0), buffer_underflows(0), buffer_overflows(0) @@ -83,12 +62,30 @@ public: virtual void set_mastervolume(int attenuation) override; private: - int lock_buffer(void); - void unlock_buffer(void); + class ring_buffer + { + public: + ring_buffer(size_t size); + + size_t data_size() const { return (tail - head + buffer_size) % buffer_size; } + size_t free_size() const { return (head - tail - 1 + buffer_size) % buffer_size; } + int append(const void *data, size_t size); + int pop(void *data, size_t size); + + private: + std::unique_ptr const buffer; + size_t const buffer_size; + int head = 0, tail = 0; + }; + + static void sdl_callback(void *userdata, Uint8 *stream, int len); + + int lock_buffer(); + void unlock_buffer(); void attenuate(int16_t *data, int bytes); void copy_sample_data(bool is_throttled, const int16_t *data, int bytes_to_copy); - int sdl_create_buffers(void); - void sdl_destroy_buffers(void); + int sdl_create_buffers(); + void sdl_destroy_buffers(); int sdl_xfer_samples; int stream_in_initialized; @@ -96,15 +93,14 @@ private: int attenuation; int buf_locked; - ring_buffer *stream_buffer; + std::unique_ptr stream_buffer; uint32_t stream_buffer_size; - // buffer over/underflow counts + // diagnostics int buffer_underflows; int buffer_overflows; - - + std::unique_ptr sound_log; }; @@ -115,72 +111,38 @@ private: // maximum audio latency #define MAX_AUDIO_LATENCY 5 -//============================================================ -// LOCAL VARIABLES -//============================================================ - -// debugging -static FILE *sound_log; - - //============================================================ // ring_buffer - constructor //============================================================ -ring_buffer::ring_buffer(size_t size) -: buffer(global_alloc_array_clear(size + 1)), buffer_size(size + 1), head(0), tail(0) +sound_sdl::ring_buffer::ring_buffer(size_t size) + : buffer(std::make_unique(size + 1)), buffer_size(size + 1) { // A size+1 bytes buffer is allocated because it can never be full. // Otherwise the case head == tail couldn't be distinguished between a // full buffer and an empty buffer. -} - -//============================================================ -// ring_buffer - destructor -//============================================================ - -ring_buffer::~ring_buffer() -{ - global_free_array(buffer); -} - -//============================================================ -// ring_buffer::data_size -//============================================================ - -size_t ring_buffer::data_size() -{ - return (tail - head + buffer_size) % buffer_size; -} - -//============================================================ -// ring_buffer::free_size -//============================================================ - -size_t ring_buffer::free_size() { - return (head - tail - 1 + buffer_size) % buffer_size; + std::fill_n(buffer.get(), size + 1, 0); } //============================================================ // ring_buffer::append //============================================================ -int ring_buffer::append(const void *data, size_t size) +int sound_sdl::ring_buffer::append(const void *data, size_t size) { - int8_t *data8 = (int8_t *)data; - size_t sz; - if (free_size() < size) return -1; - sz = buffer_size - tail; + int8_t const *const data8 = reinterpret_cast(data); + size_t sz = buffer_size - tail; if (size <= sz) sz = size; else - memcpy(buffer, &data8[sz], size - sz); + std::copy_n(&data8[sz], size - sz, &buffer[0]); - memcpy(&buffer[tail], data8, sz); + std::copy_n(data8, sz, &buffer[tail]); tail = (tail + size) % buffer_size; + return 0; } @@ -188,25 +150,25 @@ int ring_buffer::append(const void *data, size_t size) // ring_buffer::pop //============================================================ -int ring_buffer::pop(void *data, size_t size) +int sound_sdl::ring_buffer::pop(void *data, size_t size) { - int8_t *data8 = (int8_t *)data; - size_t sz; - if (data_size() < size) return -1; - sz = buffer_size - head; + int8_t *const data8 = reinterpret_cast(data); + size_t sz = buffer_size - head; if (size <= sz) sz = size; - else { - memcpy(&data8[sz], buffer, size - sz); - memset(buffer, 0, size - sz); + else + { + std::copy_n(&buffer[0], size - sz, &data8[sz]); + std::fill_n(&buffer[0], size - sz, 0); } - memcpy(data8, &buffer[head], sz); - memset(&buffer[head], 0, sz); + std::copy_n(&buffer[head], sz, data8); + std::fill_n(&buffer[head], sz, 0); head = (head + size) % buffer_size; + return 0; } @@ -224,7 +186,7 @@ int sound_sdl::lock_buffer() buf_locked++; if (LOG_SOUND) - fprintf(sound_log, "locking\n"); + *sound_log << "locking\n"; return 0; } @@ -232,14 +194,14 @@ int sound_sdl::lock_buffer() //============================================================ // unlock_buffer //============================================================ -void sound_sdl::unlock_buffer(void) +void sound_sdl::unlock_buffer() { buf_locked--; if (!buf_locked) SDL_UnlockAudio(); if (LOG_SOUND) - fprintf(sound_log, "unlocking\n"); + *sound_log << "unlocking\n"; } @@ -266,11 +228,11 @@ void sound_sdl::attenuate(int16_t *data, int bytes_to_copy) void sound_sdl::copy_sample_data(bool is_throttled, const int16_t *data, int bytes_to_copy) { lock_buffer(); - int err = stream_buffer->append((void *)data, bytes_to_copy); + int const err = stream_buffer->append(data, bytes_to_copy); unlock_buffer(); if (LOG_SOUND && err) - fprintf(sound_log, "Late detection of overflow. This shouldn't happen.\n"); + *sound_log << "Late detection of overflow. This shouldn't happen.\n"; } @@ -281,7 +243,7 @@ void sound_sdl::copy_sample_data(bool is_throttled, const int16_t *data, int byt void sound_sdl::update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame) { // if nothing to do, don't do it - if (sample_rate() == 0 || stream_buffer == nullptr) + if (sample_rate() == 0 || !stream_buffer) return; @@ -304,7 +266,7 @@ void sound_sdl::update_audio_stream(bool is_throttled, const int16_t *buffer, in if (stream_buffer->free_size() < bytes_this_frame) { if (LOG_SOUND) - fprintf(sound_log, "Overflow: DS=%zu FS=%zu BTF=%zu\n", data_size, free_size, bytes_this_frame); + util::stream_format(*sound_log, "Overflow: DS=%u FS=%u BTF=%u\n", data_size, free_size, bytes_this_frame); buffer_overflows++; return; } @@ -314,7 +276,7 @@ void sound_sdl::update_audio_stream(bool is_throttled, const int16_t *buffer, in size_t nfree_size = stream_buffer->free_size(); size_t ndata_size = stream_buffer->data_size(); if (LOG_SOUND) - fprintf(sound_log, "Appended data: DS=%zu(%zu) FS=%zu(%zu) BTF=%zu\n", data_size, ndata_size, free_size, nfree_size, bytes_this_frame); + util::stream_format(*sound_log, "Appended data: DS=%u(%u) FS=%u(%u) BTF=%u\n", data_size, ndata_size, free_size, nfree_size, bytes_this_frame); } @@ -340,17 +302,17 @@ void sound_sdl::set_mastervolume(int _attenuation) //============================================================ // sdl_callback //============================================================ -static void sdl_callback(void *userdata, Uint8 *stream, int len) +void sound_sdl::sdl_callback(void *userdata, Uint8 *stream, int len) { - sound_sdl *thiz = (sound_sdl *) userdata; - size_t free_size = thiz->stream_buffer->free_size(); - size_t data_size = thiz->stream_buffer->data_size(); + sound_sdl *thiz = reinterpret_cast(userdata); + size_t const free_size = thiz->stream_buffer->free_size(); + size_t const data_size = thiz->stream_buffer->data_size(); if (data_size < len) { thiz->buffer_underflows++; if (LOG_SOUND) - fprintf(sound_log, "Underflow at sdl_callback: DS=%zu FS=%zu Len=%d\n", data_size, free_size, len); + util::stream_format(*thiz->sound_log, "Underflow at sdl_callback: DS=%u FS=%u Len=%d\n", data_size, free_size, len); // Maybe read whatever is left in the stream_buffer anyway? memset(stream, 0, len); @@ -359,12 +321,12 @@ static void sdl_callback(void *userdata, Uint8 *stream, int len) int err = thiz->stream_buffer->pop((void *)stream, len); if (LOG_SOUND && err) - fprintf(sound_log, "Late detection of underflow. This shouldn't happen.\n"); + *thiz->sound_log << "Late detection of underflow. This shouldn't happen.\n"; thiz->attenuate((int16_t *)stream, len); if (LOG_SOUND) - fprintf(sound_log, "callback: xfer DS=%zu FS=%zu Len=%d\n", data_size, free_size, len); + util::stream_format(*thiz->sound_log, "callback: xfer DS=%u FS=%u Len=%d\n", data_size, free_size, len); } @@ -380,12 +342,13 @@ int sound_sdl::init(const osd_options &options) char audio_driver[16] = ""; if (LOG_SOUND) - sound_log = fopen(SDLMAME_SOUND_LOG, "w"); + sound_log = std::make_unique(SDLMAME_SOUND_LOG); // skip if sound disabled if (sample_rate() != 0) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO)) { + if (SDL_InitSubSystem(SDL_INIT_AUDIO)) + { osd_printf_error("Could not initialize SDL %s\n", SDL_GetError()); return -1; } @@ -469,8 +432,8 @@ void sound_sdl::exit() if (LOG_SOUND) { - fprintf(sound_log, "Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); - fclose(sound_log); + util::stream_format(*sound_log, "Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows); + sound_log.reset(); } } @@ -480,11 +443,11 @@ void sound_sdl::exit() // dsound_create_buffers //============================================================ -int sound_sdl::sdl_create_buffers(void) +int sound_sdl::sdl_create_buffers() { osd_printf_verbose("sdl_create_buffers: creating stream buffer of %u bytes\n", stream_buffer_size); - stream_buffer = new ring_buffer(stream_buffer_size); + stream_buffer = std::make_unique(stream_buffer_size); buf_locked = 0; return 0; } @@ -493,12 +456,10 @@ int sound_sdl::sdl_create_buffers(void) // sdl_destroy_buffers //============================================================ -void sound_sdl::sdl_destroy_buffers(void) +void sound_sdl::sdl_destroy_buffers() { // release the buffer - if (stream_buffer) - delete stream_buffer; - stream_buffer = nullptr; + stream_buffer.reset(); } -- cgit v1.2.3