summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-12-25 00:48:08 +1100
committer Vas Crabb <vas@vastheman.com>2018-12-25 00:48:08 +1100
commitbc6e3672d16864d4f77a1e6ac14d90c411be7ba0 (patch)
tree7112b1a47f93693c9c228a98b519c3379545b156 /src/osd
parent726fa9b6dfce0ffb63cf7e55318bd9bc14d668bc (diff)
clean up sdl_sound a bit (nw)
Diffstat (limited to 'src/osd')
-rw-r--r--src/osd/modules/sound/sdl_sound.cpp187
1 files 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,6 +22,10 @@
#include "../../sdl/osdsdl.h"
+#include <algorithm>
+#include <fstream>
+#include <memory>
+
//============================================================
// DEBUGGING
//============================================================
@@ -29,43 +33,18 @@
#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<int8_t []> 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<ring_buffer> stream_buffer;
uint32_t stream_buffer_size;
- // buffer over/underflow counts
+ // diagnostics
int buffer_underflows;
int buffer_overflows;
-
-
+ std::unique_ptr<std::ofstream> sound_log;
};
@@ -116,71 +112,37 @@ private:
#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<int8_t>(size + 1)), buffer_size(size + 1), head(0), tail(0)
+sound_sdl::ring_buffer::ring_buffer(size_t size)
+ : buffer(std::make_unique<int8_t []>(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<int8_t const *>(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<int8_t *>(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<sound_sdl *>(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<std::ofstream>(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<ring_buffer>(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();
}