summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd
diff options
context:
space:
mode:
author intealls <johan@wennersten.eu>2017-01-15 00:05:18 +0100
committer intealls <johan@wennersten.eu>2017-01-15 00:05:18 +0100
commit9d1c8c45aee985a6836da6450d13b03ed7c65a3e (patch)
tree97946506676a7047a8a6b778ce0a4baf7fbbe909 /src/osd
parente74399a7225542c5651b4e975c812be6585d7ac5 (diff)
fix indentation, leading spaces to tabs
Diffstat (limited to 'src/osd')
-rw-r--r--src/osd/modules/sound/pa_sound.cpp630
1 files changed, 315 insertions, 315 deletions
diff --git a/src/osd/modules/sound/pa_sound.cpp b/src/osd/modules/sound/pa_sound.cpp
index ee7f6420fe4..fb92689504f 100644
--- a/src/osd/modules/sound/pa_sound.cpp
+++ b/src/osd/modules/sound/pa_sound.cpp
@@ -2,9 +2,9 @@
// copyright-holders:intealls, R.Belmont
/***************************************************************************
- pa_sound.c
+ pa_sound.c
- PortAudio interface.
+ PortAudio interface.
*******************************************************************c********/
@@ -34,404 +34,404 @@
class sound_pa : public osd_module, public sound_module
{
public:
- sound_pa()
- : osd_module(OSD_SOUND_PROVIDER, "portaudio"), sound_module()
- {
- }
- virtual ~sound_pa() { }
+ sound_pa()
+ : osd_module(OSD_SOUND_PROVIDER, "portaudio"), sound_module()
+ {
+ }
+ virtual ~sound_pa() { }
- virtual int init(osd_options const &options);
- virtual void exit();
+ virtual int init(osd_options const &options);
+ virtual void exit();
- // sound_module
+ // sound_module
- virtual void update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame);
- virtual void set_mastervolume(int attenuation);
+ virtual void update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame);
+ virtual void set_mastervolume(int attenuation);
private:
- /* Lock free SPSC ring buffer */
- template <typename T>
- struct audio_buffer {
- T* buf;
- int size;
- int reserve;
- std::atomic<int> rd_pos, wr_pos;
-
- audio_buffer(int size, int reserve) : size(size), reserve(reserve) {
- rd_pos = wr_pos = 0;
- buf = new T[size]();
- }
-
- ~audio_buffer() { delete[] buf; }
-
- int count() {
- int diff;
- diff = wr_pos - rd_pos;
- diff = diff < 0 ? size + diff : diff;
- diff -= reserve;
- return diff < 0 ? 0 : diff;
- }
-
- void increment_wrpos(int n) {
- wr_pos = (wr_pos + n) % size;
- }
-
- int write(const T* src, int n, int attenuation) {
- n = std::min<int>(n, size - count());
-
- if (wr_pos + n > size) {
- att_memcpy(buf + wr_pos, src, sizeof(T) * (size - wr_pos), attenuation);
- att_memcpy(buf, src + (size - wr_pos), sizeof(T) * (n - (size - wr_pos)), attenuation);
- } else {
- att_memcpy(buf + wr_pos, src, sizeof(T) * n, attenuation);
- }
-
- increment_wrpos(n);
-
- return n;
- }
-
- void increment_rdpos(int n) {
- rd_pos = (rd_pos + n) % size;
- }
-
- int read(T* dst, int n) {
- n = std::min<int>(n, count());
-
- if (rd_pos + n > size) {
- std::memcpy(dst, buf + rd_pos, sizeof(T) * (size - rd_pos));
- std::memcpy(dst + (size - rd_pos), buf, sizeof(T) * (n - (size - rd_pos)));
- } else {
- std::memcpy(dst, buf + rd_pos, sizeof(T) * n);
- }
-
- increment_rdpos(n);
-
- return n;
- }
-
- int clear(int n) {
- n = std::min<int>(n, size - count());
-
- if (wr_pos + n > size) {
- std::memset(buf + wr_pos, 0, sizeof(T) * (size - wr_pos));
- std::memset(buf, 0, sizeof(T) * (n - (size - wr_pos)));
- } else {
- std::memset(buf + wr_pos, 0, sizeof(T) * n);
- }
-
- increment_wrpos(n);
-
- 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;
- }
- };
-
- int callback(s16* output_buffer, size_t number_of_frames);
- static int _callback(const void*,
- void *output_buffer,
- unsigned long number_of_frames,
- const PaStreamCallbackTimeInfo*,
- PaStreamCallbackFlags,
- void *arg) { return static_cast<sound_pa*> (arg)->
- callback((s16*) output_buffer, number_of_frames * 2); }
-
- PaDeviceIndex list_get_devidx(const char* api_str, const char* device_str);
-
- PaStream* m_pa_stream;
- PaError err;
-
- int m_attenuation;
-
- audio_buffer<s16>* m_ab;
-
- std::atomic<bool> m_has_underflowed;
- std::atomic<bool> m_has_overflowed;
- unsigned m_underflows;
- unsigned m_overflows;
+ /* Lock free SPSC ring buffer */
+ template <typename T>
+ struct audio_buffer {
+ T* buf;
+ int size;
+ int reserve;
+ std::atomic<int> rd_pos, wr_pos;
+
+ audio_buffer(int size, int reserve) : size(size), reserve(reserve) {
+ rd_pos = wr_pos = 0;
+ buf = new T[size]();
+ }
+
+ ~audio_buffer() { delete[] buf; }
+
+ int count() {
+ int diff;
+ diff = wr_pos - rd_pos;
+ diff = diff < 0 ? size + diff : diff;
+ diff -= reserve;
+ return diff < 0 ? 0 : diff;
+ }
+
+ void increment_wrpos(int n) {
+ wr_pos = (wr_pos + n) % size;
+ }
+
+ int write(const T* src, int n, int attenuation) {
+ n = std::min<int>(n, size - count());
+
+ if (wr_pos + n > size) {
+ att_memcpy(buf + wr_pos, src, sizeof(T) * (size - wr_pos), attenuation);
+ att_memcpy(buf, src + (size - wr_pos), sizeof(T) * (n - (size - wr_pos)), attenuation);
+ } else {
+ att_memcpy(buf + wr_pos, src, sizeof(T) * n, attenuation);
+ }
+
+ increment_wrpos(n);
+
+ return n;
+ }
+
+ void increment_rdpos(int n) {
+ rd_pos = (rd_pos + n) % size;
+ }
+
+ int read(T* dst, int n) {
+ n = std::min<int>(n, count());
+
+ if (rd_pos + n > size) {
+ std::memcpy(dst, buf + rd_pos, sizeof(T) * (size - rd_pos));
+ std::memcpy(dst + (size - rd_pos), buf, sizeof(T) * (n - (size - rd_pos)));
+ } else {
+ std::memcpy(dst, buf + rd_pos, sizeof(T) * n);
+ }
+
+ increment_rdpos(n);
+
+ return n;
+ }
+
+ int clear(int n) {
+ n = std::min<int>(n, size - count());
+
+ if (wr_pos + n > size) {
+ std::memset(buf + wr_pos, 0, sizeof(T) * (size - wr_pos));
+ std::memset(buf, 0, sizeof(T) * (n - (size - wr_pos)));
+ } else {
+ std::memset(buf + wr_pos, 0, sizeof(T) * n);
+ }
+
+ increment_wrpos(n);
+
+ 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;
+ }
+ };
+
+ int callback(s16* output_buffer, size_t number_of_frames);
+ static int _callback(const void*,
+ void *output_buffer,
+ unsigned long number_of_frames,
+ const PaStreamCallbackTimeInfo*,
+ PaStreamCallbackFlags,
+ void *arg) { return static_cast<sound_pa*> (arg)->
+ callback((s16*) output_buffer, number_of_frames * 2); }
+
+ PaDeviceIndex list_get_devidx(const char* api_str, const char* device_str);
+
+ PaStream* m_pa_stream;
+ PaError err;
+
+ int m_attenuation;
+
+ audio_buffer<s16>* m_ab;
+
+ std::atomic<bool> m_has_underflowed;
+ std::atomic<bool> m_has_overflowed;
+ unsigned m_underflows;
+ unsigned m_overflows;
- int m_skip_threshold; // this many samples in the buffer ~1 second in a row count as an overflow
- osd_ticks_t m_osd_ticks;
- osd_ticks_t m_skip_threshold_ticks;
- osd_ticks_t m_osd_tps;
- int m_buffer_min_ct;
+ int m_skip_threshold; // this many samples in the buffer ~1 second in a row count as an overflow
+ osd_ticks_t m_osd_ticks;
+ osd_ticks_t m_skip_threshold_ticks;
+ osd_ticks_t m_osd_tps;
+ int m_buffer_min_ct;
#if LOG_BUFCNT
- std::stringstream m_log;
+ std::stringstream m_log;
#endif
};
int sound_pa::init(osd_options const &options)
{
- PaStreamParameters stream_params;
- const PaStreamInfo* stream_info;
- const PaHostApiInfo* api_info;
- const PaDeviceInfo* device_info;
+ PaStreamParameters stream_params;
+ const PaStreamInfo* stream_info;
+ const PaHostApiInfo* api_info;
+ const PaDeviceInfo* device_info;
- unsigned long frames_per_callback = paFramesPerBufferUnspecified;
- double callback_interval;
+ unsigned long frames_per_callback = paFramesPerBufferUnspecified;
+ double callback_interval;
- if (!sample_rate())
- return 0;
+ if (!sample_rate())
+ return 0;
- m_attenuation = options.volume();
- m_underflows = 0;
- m_overflows = 0;
- m_has_overflowed = false;
- m_has_underflowed = false;
- m_skip_threshold_ticks = 0;
+ m_attenuation = options.volume();
+ m_underflows = 0;
+ m_overflows = 0;
+ m_has_overflowed = false;
+ m_has_underflowed = false;
+ m_skip_threshold_ticks = 0;
- try {
- m_ab = new audio_buffer<s16>(m_sample_rate, 2);
- } catch (std::bad_alloc&) {
- osd_printf_error("PortAudio: Unable to allocate audio buffer, sound is disabled\n");
- goto error;
- }
+ try {
+ m_ab = new audio_buffer<s16>(m_sample_rate, 2);
+ } catch (std::bad_alloc&) {
+ osd_printf_error("PortAudio: Unable to allocate audio buffer, sound is disabled\n");
+ goto error;
+ }
- m_osd_tps = osd_ticks_per_second();
+ m_osd_tps = osd_ticks_per_second();
- err = Pa_Initialize();
+ err = Pa_Initialize();
- if (err != paNoError) goto pa_error;
+ if (err != paNoError) goto pa_error;
- stream_params.device = list_get_devidx(options.pa_api(), options.pa_device());
+ stream_params.device = list_get_devidx(options.pa_api(), options.pa_device());
- stream_params.channelCount = 2;
- stream_params.sampleFormat = paInt16;
- stream_params.hostApiSpecificStreamInfo = NULL;
+ stream_params.channelCount = 2;
+ stream_params.sampleFormat = paInt16;
+ stream_params.hostApiSpecificStreamInfo = NULL;
- device_info = Pa_GetDeviceInfo(stream_params.device);
+ device_info = Pa_GetDeviceInfo(stream_params.device);
- // 0 = use default
- stream_params.suggestedLatency = options.pa_latency() ? options.pa_latency() : device_info->defaultLowOutputLatency;
+ // 0 = use default
+ stream_params.suggestedLatency = options.pa_latency() ? options.pa_latency() : device_info->defaultLowOutputLatency;
#ifdef WIN32
- PaWasapiStreamInfo wasapi_stream_info;
-
- // if requested latency is less than 20 ms, we need to use exclusive mode
- if (Pa_GetHostApiInfo(device_info->hostApi)->type == paWASAPI && stream_params.suggestedLatency < 0.020)
- {
- wasapi_stream_info.size = sizeof(PaWasapiStreamInfo);
- wasapi_stream_info.hostApiType = paWASAPI;
- wasapi_stream_info.flags = paWinWasapiExclusive;
- wasapi_stream_info.version = 1;
-
- stream_params.hostApiSpecificStreamInfo = &wasapi_stream_info;
-
- // for latencies lower than ~16 ms, we need to use event mode
- if (stream_params.suggestedLatency < 0.016)
- {
- // only way to control output latency with event mode
- frames_per_callback = stream_params.suggestedLatency * m_sample_rate;
-
- // needed for event mode to work
- stream_params.suggestedLatency = 0;
- }
- }
+ PaWasapiStreamInfo wasapi_stream_info;
+
+ // if requested latency is less than 20 ms, we need to use exclusive mode
+ if (Pa_GetHostApiInfo(device_info->hostApi)->type == paWASAPI && stream_params.suggestedLatency < 0.020)
+ {
+ wasapi_stream_info.size = sizeof(PaWasapiStreamInfo);
+ wasapi_stream_info.hostApiType = paWASAPI;
+ wasapi_stream_info.flags = paWinWasapiExclusive;
+ wasapi_stream_info.version = 1;
+
+ stream_params.hostApiSpecificStreamInfo = &wasapi_stream_info;
+
+ // for latencies lower than ~16 ms, we need to use event mode
+ if (stream_params.suggestedLatency < 0.016)
+ {
+ // only way to control output latency with event mode
+ frames_per_callback = stream_params.suggestedLatency * m_sample_rate;
+
+ // needed for event mode to work
+ stream_params.suggestedLatency = 0;
+ }
+ }
#endif
- err = Pa_OpenStream(&m_pa_stream,
- NULL,
- &stream_params,
- m_sample_rate,
- frames_per_callback,
- paClipOff,
- _callback,
- this);
+ err = Pa_OpenStream(&m_pa_stream,
+ NULL,
+ &stream_params,
+ m_sample_rate,
+ frames_per_callback,
+ paClipOff,
+ _callback,
+ this);
- if (err != paNoError) goto pa_error;
+ if (err != paNoError) goto pa_error;
- stream_info = Pa_GetStreamInfo(m_pa_stream);
- api_info = Pa_GetHostApiInfo(device_info->hostApi);
+ stream_info = Pa_GetStreamInfo(m_pa_stream);
+ api_info = Pa_GetHostApiInfo(device_info->hostApi);
- // in milliseconds
- callback_interval = static_cast<double>(stream_info->outputLatency) * 1000.0;
+ // in milliseconds
+ callback_interval = static_cast<double>(stream_info->outputLatency) * 1000.0;
- // clamp to a probable figure
- callback_interval = std::min<double>(callback_interval, 20.0);
+ // clamp to a probable figure
+ callback_interval = std::min<double>(callback_interval, 20.0);
- // set the best guess callback interval to allowed count, each audio_latency step > 1 adds 20 ms
- m_skip_threshold = ((std::max<double>(callback_interval, 10.0) + (m_audio_latency - 1) * 20.0) / 1000.0) * m_sample_rate * 2 + 0.5f;
+ // set the best guess callback interval to allowed count, each audio_latency step > 1 adds 20 ms
+ m_skip_threshold = ((std::max<double>(callback_interval, 10.0) + (m_audio_latency - 1) * 20.0) / 1000.0) * m_sample_rate * 2 + 0.5f;
- osd_printf_verbose("PortAudio: Using device \"%s\" on API \"%s\"\n", device_info->name, api_info->name);
- osd_printf_verbose("PortAudio: Sample rate is %0.0f Hz, device output latency is %0.2f ms\n",
- stream_info->sampleRate, stream_info->outputLatency * 1000.0);
- osd_printf_verbose("PortAudio: Allowed additional buffering latency is %0.2f ms/%d frames\n",
- (m_skip_threshold / 2.0) / (m_sample_rate / 1000.0), m_skip_threshold / 2);
+ osd_printf_verbose("PortAudio: Using device \"%s\" on API \"%s\"\n", device_info->name, api_info->name);
+ osd_printf_verbose("PortAudio: Sample rate is %0.0f Hz, device output latency is %0.2f ms\n",
+ stream_info->sampleRate, stream_info->outputLatency * 1000.0);
+ osd_printf_verbose("PortAudio: Allowed additional buffering latency is %0.2f ms/%d frames\n",
+ (m_skip_threshold / 2.0) / (m_sample_rate / 1000.0), m_skip_threshold / 2);
- err = Pa_StartStream(m_pa_stream);
+ err = Pa_StartStream(m_pa_stream);
- if (err != paNoError) goto pa_error;
+ if (err != paNoError) goto pa_error;
- return 0;
+ return 0;
pa_error:
- delete m_ab;
- osd_printf_error("PortAudio error: %s\n", Pa_GetErrorText(err));
- Pa_Terminate();
+ delete m_ab;
+ osd_printf_error("PortAudio error: %s\n", Pa_GetErrorText(err));
+ Pa_Terminate();
error:
- m_sample_rate = 0;
- return -1;
+ m_sample_rate = 0;
+ return -1;
}
PaDeviceIndex sound_pa::list_get_devidx(const char* api_str, const char* device_str)
{
- PaDeviceIndex selected_devidx = -1;
+ PaDeviceIndex selected_devidx = -1;
- for (PaHostApiIndex api_idx = 0; api_idx < Pa_GetHostApiCount(); api_idx++)
- {
- const PaHostApiInfo *api_info = Pa_GetHostApiInfo(api_idx);
+ for (PaHostApiIndex api_idx = 0; api_idx < Pa_GetHostApiCount(); api_idx++)
+ {
+ const PaHostApiInfo *api_info = Pa_GetHostApiInfo(api_idx);
- osd_printf_verbose("PortAudio: API %s has %d devices\n", api_info->name, api_info->deviceCount);
+ osd_printf_verbose("PortAudio: API %s has %d devices\n", api_info->name, api_info->deviceCount);
- for (int api_devidx = 0; api_devidx < api_info->deviceCount; api_devidx++)
- {
- PaDeviceIndex devidx = Pa_HostApiDeviceIndexToDeviceIndex(api_idx, api_devidx);
- const PaDeviceInfo *device_info = Pa_GetDeviceInfo(devidx);
+ for (int api_devidx = 0; api_devidx < api_info->deviceCount; api_devidx++)
+ {
+ PaDeviceIndex devidx = Pa_HostApiDeviceIndexToDeviceIndex(api_idx, api_devidx);
+ const PaDeviceInfo *device_info = Pa_GetDeviceInfo(devidx);
- // specified API and device is found
- if (!strcmp(api_str, api_info->name) && !strcmp(device_str, device_info->name))
- selected_devidx = devidx;
+ // specified API and device is found
+ if (!strcmp(api_str, api_info->name) && !strcmp(device_str, device_info->name))
+ selected_devidx = devidx;
- // if specified device cannot be found, use the default device of the specified API
- if (!strcmp(api_str, api_info->name) && api_devidx == api_info->deviceCount - 1 && selected_devidx == -1)
- selected_devidx = api_info->defaultOutputDevice;
+ // if specified device cannot be found, use the default device of the specified API
+ if (!strcmp(api_str, api_info->name) && api_devidx == api_info->deviceCount - 1 && selected_devidx == -1)
+ selected_devidx = api_info->defaultOutputDevice;
- osd_printf_verbose("PortAudio: %s: \"%s\"%s\n",
- api_info->name, device_info->name, api_info->defaultOutputDevice == devidx ? " (default)" : "");
- }
- }
+ osd_printf_verbose("PortAudio: %s: \"%s\"%s\n",
+ api_info->name, device_info->name, api_info->defaultOutputDevice == devidx ? " (default)" : "");
+ }
+ }
- if (selected_devidx < 0)
- {
- osd_printf_verbose("PortAudio: Unable to find specified API or device or none set, reverting to default\n");
- return Pa_GetDefaultOutputDevice();
- }
+ if (selected_devidx < 0)
+ {
+ osd_printf_verbose("PortAudio: Unable to find specified API or device or none set, reverting to default\n");
+ return Pa_GetDefaultOutputDevice();
+ }
- return selected_devidx;
+ return selected_devidx;
}
int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
{
- int buf_ct = m_ab->count();
-
- if (buf_ct >= number_of_samples)
- {
- m_ab->read(output_buffer, number_of_samples);
-
- // keep track of the minimum buffer count, skip samples adaptively to respect the audio_latency setting
- buf_ct -= number_of_samples;
-
- if (buf_ct < m_buffer_min_ct)
- m_buffer_min_ct = buf_ct;
-
- // if we are below the threshold, reset the counter
- if (buf_ct < m_skip_threshold)
- m_skip_threshold_ticks = m_osd_ticks;
-
- // if we have been above the set threshold for ~1 second, skip forward
- if (m_osd_ticks - m_skip_threshold_ticks > m_osd_tps)
- {
- 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) {
- m_ab->increment_rdpos(adjust);
- m_has_overflowed = true;
- }
-
- m_skip_threshold_ticks = m_osd_ticks;
- m_buffer_min_ct = INT_MAX;
- }
- }
- else
- {
- m_ab->read(output_buffer, buf_ct);
- std::memset(output_buffer + buf_ct, 0, (number_of_samples - buf_ct) * sizeof(s16));
-
- // rd_pos == wr_pos only happens when buffer hasn't received any samples,
- // i.e. before update_audio_stream has been called
- if (m_ab->rd_pos != m_ab->wr_pos)
- m_has_underflowed = true;
-
- m_skip_threshold_ticks = m_osd_ticks;
- }
-
- return paContinue;
+ int buf_ct = m_ab->count();
+
+ if (buf_ct >= number_of_samples)
+ {
+ m_ab->read(output_buffer, number_of_samples);
+
+ // keep track of the minimum buffer count, skip samples adaptively to respect the audio_latency setting
+ buf_ct -= number_of_samples;
+
+ if (buf_ct < m_buffer_min_ct)
+ m_buffer_min_ct = buf_ct;
+
+ // if we are below the threshold, reset the counter
+ if (buf_ct < m_skip_threshold)
+ m_skip_threshold_ticks = m_osd_ticks;
+
+ // if we have been above the set threshold for ~1 second, skip forward
+ if (m_osd_ticks - m_skip_threshold_ticks > m_osd_tps)
+ {
+ 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) {
+ m_ab->increment_rdpos(adjust);
+ m_has_overflowed = true;
+ }
+
+ m_skip_threshold_ticks = m_osd_ticks;
+ m_buffer_min_ct = INT_MAX;
+ }
+ }
+ else
+ {
+ m_ab->read(output_buffer, buf_ct);
+ std::memset(output_buffer + buf_ct, 0, (number_of_samples - buf_ct) * sizeof(s16));
+
+ // rd_pos == wr_pos only happens when buffer hasn't received any samples,
+ // i.e. before update_audio_stream has been called
+ if (m_ab->rd_pos != m_ab->wr_pos)
+ m_has_underflowed = true;
+
+ m_skip_threshold_ticks = m_osd_ticks;
+ }
+
+ return paContinue;
}
void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame)
{
- if (!sample_rate())
- return;
+ if (!sample_rate())
+ return;
- // for determining buffer overflows, take the sample here instead of in the callback
- m_osd_ticks = osd_ticks();
+ // for determining buffer overflows, take the sample here instead of in the callback
+ m_osd_ticks = osd_ticks();
#if LOG_BUFCNT
- if (m_log.good())
- m_log << m_ab->count() << std::endl;
+ if (m_log.good())
+ m_log << m_ab->count() << std::endl;
#endif
- if (m_has_underflowed)
- {
- m_underflows++;
- // add some silence to prevent immediate underflows
- m_ab->clear(m_skip_threshold / 4);
- m_has_underflowed = false;
- }
-
- if (m_has_overflowed)
- {
- m_overflows++;
- m_has_overflowed = false;
- }
-
- m_ab->write(buffer, samples_this_frame * 2, m_attenuation);
+ if (m_has_underflowed)
+ {
+ m_underflows++;
+ // add some silence to prevent immediate underflows
+ m_ab->clear(m_skip_threshold / 4);
+ m_has_underflowed = false;
+ }
+
+ if (m_has_overflowed)
+ {
+ m_overflows++;
+ m_has_overflowed = false;
+ }
+
+ m_ab->write(buffer, samples_this_frame * 2, m_attenuation);
}
void sound_pa::set_mastervolume(int attenuation)
{
- m_attenuation = attenuation;
+ m_attenuation = attenuation;
}
void sound_pa::exit()
{
- if (!sample_rate())
- return;
+ if (!sample_rate())
+ return;
#if LOG_BUFCNT
- std::ofstream m_logfile(LOG_FILE);
+ std::ofstream m_logfile(LOG_FILE);
- if (m_log.good() && m_logfile.is_open()) {
- m_logfile << m_log.str();
- m_logfile.close();
- }
+ if (m_log.good() && m_logfile.is_open()) {
+ m_logfile << m_log.str();
+ m_logfile.close();
+ }
- if (!m_log.good() || m_logfile.fail())
- osd_printf_error("PortAudio: Error writing log.\n");
+ if (!m_log.good() || m_logfile.fail())
+ osd_printf_error("PortAudio: Error writing log.\n");
#endif
- Pa_StopStream(m_pa_stream);
- err = Pa_Terminate();
+ Pa_StopStream(m_pa_stream);
+ err = Pa_Terminate();
- if (err != paNoError)
- osd_printf_error("PortAudio error: %s\n", Pa_GetErrorText(err));
+ if (err != paNoError)
+ osd_printf_error("PortAudio error: %s\n", Pa_GetErrorText(err));
- delete m_ab;
+ delete m_ab;
- if (m_overflows || m_underflows)
- osd_printf_verbose("Sound: overflows=%d underflows=%d\n", m_overflows, m_underflows);
+ if (m_overflows || m_underflows)
+ osd_printf_verbose("Sound: overflows=%d underflows=%d\n", m_overflows, m_underflows);
}
#else
- MODULE_NOT_SUPPORTED(sound_pa, OSD_SOUND_PROVIDER, "portaudio")
+ MODULE_NOT_SUPPORTED(sound_pa, OSD_SOUND_PROVIDER, "portaudio")
#endif
MODULE_DEFINITION(SOUND_PORTAUDIO, sound_pa)