diff options
Diffstat (limited to 'src/osd/modules/sound/pa_sound.cpp')
-rw-r--r-- | src/osd/modules/sound/pa_sound.cpp | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/src/osd/modules/sound/pa_sound.cpp b/src/osd/modules/sound/pa_sound.cpp index 41645318672..68200a9c3f1 100644 --- a/src/osd/modules/sound/pa_sound.cpp +++ b/src/osd/modules/sound/pa_sound.cpp @@ -9,44 +9,50 @@ *******************************************************************c********/ #include "sound_module.h" + #include "modules/osdmodule.h" #ifndef NO_USE_PORTAUDIO -#include <portaudio.h> #include "modules/lib/osdobj_common.h" +#include "osdcore.h" -#include <iostream> -#include <fstream> -#include <sstream> +#include <portaudio.h> + +#include <algorithm> #include <atomic> -#include <cmath> #include <climits> -#include <algorithm> +#include <cmath> +#include <fstream> +#include <iostream> +#include <sstream> -#ifdef WIN32 +#ifdef _WIN32 #include "pa_win_wasapi.h" #endif + +namespace osd { + +namespace { + #define LOG_FILE "pa.log" #define LOG_BUFCNT 0 class sound_pa : public osd_module, public sound_module { public: - sound_pa() - : osd_module(OSD_SOUND_PROVIDER, "portaudio"), sound_module() + sound_pa() : osd_module(OSD_SOUND_PROVIDER, "portaudio") { } virtual ~sound_pa() { } - virtual int init(osd_options const &options) override; + virtual int init(osd_interface &osd, osd_options const &options) override; virtual void exit() override; // sound_module - virtual void update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame) override; - virtual void set_mastervolume(int attenuation) override; + virtual void stream_sink_update(uint32_t, const s16 *buffer, int samples_this_frame) override; private: // Lock free SPSC ring buffer @@ -73,14 +79,14 @@ private: writepos.store((writepos + n) % size); } - int write(const T* src, int n, int attenuation) { + int write(const T* src, int n) { n = std::min<int>(n, size - reserve - count()); if (writepos + n > size) { - att_memcpy(buf + writepos, src, sizeof(T) * (size - writepos), attenuation); - att_memcpy(buf, src + (size - writepos), sizeof(T) * (n - (size - writepos)), attenuation); + memcpy(buf + writepos, src, sizeof(T) * (size - writepos)); + memcpy(buf, src + (size - writepos), sizeof(T) * (n - (size - writepos))); } else { - att_memcpy(buf + writepos, src, sizeof(T) * n, attenuation); + memcpy(buf + writepos, src, sizeof(T) * n); } increment_writepos(n); @@ -121,13 +127,6 @@ private: return n; } - - void att_memcpy(T* dest, const T* data, int n, int attenuation) { - int level = powf(10.0, attenuation / 20.0) * 32768; - n /= sizeof(T); - while (n--) - *dest++ = (*data++ * level) >> 15; - } }; enum @@ -150,7 +149,8 @@ private: PaStream* m_pa_stream; PaError err; - int m_attenuation; + int m_sample_rate; + int m_audio_latency; audio_buffer<s16>* m_ab; @@ -170,8 +170,12 @@ private: #endif }; -int sound_pa::init(osd_options const &options) +int sound_pa::init(osd_interface &osd, osd_options const &options) { + m_sample_rate = options.sample_rate(); + if (!m_sample_rate) + return 0; + PaStreamParameters stream_params; const PaStreamInfo* stream_info; const PaHostApiInfo* api_info; @@ -180,10 +184,6 @@ int sound_pa::init(osd_options const &options) unsigned long frames_per_callback = paFramesPerBufferUnspecified; double callback_interval; - if (!sample_rate()) - return 0; - - m_attenuation = options.volume(); m_underflows = 0; m_overflows = 0; m_has_overflowed = false; @@ -192,7 +192,7 @@ int sound_pa::init(osd_options const &options) m_skip_threshold_ticks = 0; m_osd_tps = osd_ticks_per_second(); m_buffer_min_ct = INT_MAX; - m_audio_latency = std::min<int>(std::max<int>(m_audio_latency, LATENCY_MIN), LATENCY_MAX); + m_audio_latency = std::clamp<int>(options.audio_latency(), LATENCY_MIN, LATENCY_MAX); try { m_ab = new audio_buffer<s16>(m_sample_rate, 2); @@ -216,7 +216,7 @@ int sound_pa::init(osd_options const &options) // 0 = use default stream_params.suggestedLatency = options.pa_latency() ? options.pa_latency() : device_info->defaultLowOutputLatency; -#ifdef WIN32 +#ifdef _WIN32 PaWasapiStreamInfo wasapi_stream_info; // if requested latency is less than 20 ms, we need to use exclusive mode @@ -364,7 +364,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples) int adjust = m_buffer_min_ct - m_skip_threshold / 2; // if adjustment is less than two milliseconds, don't bother - if (adjust / 2 > sample_rate() / 500) { + if (adjust / 2 > m_sample_rate / 500) { m_ab->increment_playpos(adjust); m_has_overflowed = true; } @@ -379,7 +379,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples) m_ab->read(output_buffer, buf_ct); std::memset(output_buffer + buf_ct, 0, (number_of_samples - buf_ct) * sizeof(s16)); - // if update_audio_stream has been called, note the underflow + // if stream_sink_update has been called, note the underflow if (m_osd_ticks) m_has_underflowed = true; @@ -389,9 +389,9 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples) return paContinue; } -void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame) +void sound_pa::stream_sink_update(uint32_t, const s16 *buffer, int samples_this_frame) { - if (!sample_rate()) + if (!m_sample_rate) return; #if LOG_BUFCNT @@ -413,20 +413,15 @@ void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int sam m_has_overflowed = false; } - m_ab->write(buffer, samples_this_frame * 2, m_attenuation); + m_ab->write(buffer, samples_this_frame * 2); // for determining buffer overflows, take the sample here instead of in the callback m_osd_ticks = osd_ticks(); } -void sound_pa::set_mastervolume(int attenuation) -{ - m_attenuation = attenuation; -} - void sound_pa::exit() { - if (!sample_rate()) + if (!m_sample_rate) return; #if LOG_BUFCNT @@ -456,8 +451,14 @@ void sound_pa::exit() osd_printf_verbose("Sound: overflows=%d underflows=%d\n", m_overflows, m_underflows); } +} // anonymous namespace + +} // namespace osd + #else - MODULE_NOT_SUPPORTED(sound_pa, OSD_SOUND_PROVIDER, "portaudio") + +namespace osd { namespace { MODULE_NOT_SUPPORTED(sound_pa, OSD_SOUND_PROVIDER, "portaudio") } } + #endif -MODULE_DEFINITION(SOUND_PORTAUDIO, sound_pa) +MODULE_DEFINITION(SOUND_PORTAUDIO, osd::sound_pa) |