summaryrefslogtreecommitdiff
path: root/drivers/alsa
diff options
context:
space:
mode:
authorlonesurvivor <musicmylove@gmx.net>2017-01-03 19:00:31 +0100
committerlonesurvivor <musicmylove@gmx.net>2017-01-05 15:36:29 +0100
commitda6b6c2dd790a1a6f1702efe1b075b09ec76fb48 (patch)
tree54ba398c7dc24db3bb765cb5d53a0aa36830ce25 /drivers/alsa
parent495d059a744b268b0355d0cbfbb9ef30fec865e2 (diff)
Fix for the huge audio latency of the SamplePlayer (>200 ms)
- fixes PulseAudio, ALSA and RtAudio driver - cleans up the driver files for better readability (mostly whitespace-related stuff) - makes ALSA and Pulseaudio actually use the global setting "audio/mix_rate" for the sample rate instead of a fixed value (RtAudio did this already)
Diffstat (limited to 'drivers/alsa')
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp50
-rw-r--r--drivers/alsa/audio_driver_alsa.h1
2 files changed, 20 insertions, 31 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 9895a10007..b026241579 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -45,7 +45,7 @@ Error AudioDriverALSA::init() {
samples_in = NULL;
samples_out = NULL;
- mix_rate = 44100;
+ mix_rate = GLOBAL_DEF("audio/mix_rate",44100);
output_format = OUTPUT_STEREO;
channels = 2;
@@ -70,67 +70,62 @@ Error AudioDriverALSA::init() {
ERR_FAIL_COND_V( status<0, ERR_CANT_OPEN );
snd_pcm_hw_params_alloca(&hwparams);
- status = snd_pcm_hw_params_any(pcm_handle, hwparams);
+ status = snd_pcm_hw_params_any(pcm_handle, hwparams);
CHECK_FAIL( status<0 );
status = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
-
CHECK_FAIL( status<0 );
//not interested in anything else
status = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE);
-
CHECK_FAIL( status<0 );
//todo: support 4 and 6
status = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2);
-
CHECK_FAIL( status<0 );
status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &mix_rate, NULL);
-
-
CHECK_FAIL( status<0 );
int latency = GLOBAL_DEF("audio/output_latency",25);
buffer_size = nearest_power_of_2( latency * mix_rate / 1000 );
- status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &buffer_size, NULL);
-
+ // set buffer size from project settings
+ status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);
+ CHECK_FAIL( status<0 );
+ // make period size 1/8
+ period_size = buffer_size >> 3;
+ status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &period_size, NULL);
CHECK_FAIL( status<0 );
unsigned int periods=2;
status = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &periods, NULL);
-
CHECK_FAIL( status<0 );
status = snd_pcm_hw_params(pcm_handle,hwparams);
-
CHECK_FAIL( status<0 );
//snd_pcm_hw_params_free(&hwparams);
snd_pcm_sw_params_alloca(&swparams);
+
status = snd_pcm_sw_params_current(pcm_handle, swparams);
CHECK_FAIL( status<0 );
- status = snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, buffer_size);
-
+ status = snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, period_size);
CHECK_FAIL( status<0 );
status = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1);
-
CHECK_FAIL( status<0 );
status = snd_pcm_sw_params(pcm_handle, swparams);
-
CHECK_FAIL( status<0 );
- samples_in = memnew_arr(int32_t, buffer_size*channels);
- samples_out = memnew_arr(int16_t, buffer_size*channels);
+ samples_in = memnew_arr(int32_t, period_size*channels);
+ samples_out = memnew_arr(int16_t, period_size*channels);
snd_pcm_nonblock(pcm_handle, 0);
@@ -144,36 +139,28 @@ void AudioDriverALSA::thread_func(void* p_udata) {
AudioDriverALSA* ad = (AudioDriverALSA*)p_udata;
-
while (!ad->exit_thread) {
-
-
if (!ad->active) {
-
- for (unsigned int i=0; i < ad->buffer_size*ad->channels; i++) {
-
+ for (unsigned int i=0; i < ad->period_size*ad->channels; i++) {
ad->samples_out[i] = 0;
};
} else {
-
ad->lock();
- ad->audio_server_process(ad->buffer_size, ad->samples_in);
+ ad->audio_server_process(ad->period_size, ad->samples_in);
ad->unlock();
- for(unsigned int i=0;i<ad->buffer_size*ad->channels;i++) {
-
+ for(unsigned int i=0;i<ad->period_size*ad->channels;i++) {
ad->samples_out[i]=ad->samples_in[i]>>16;
}
};
- int todo = ad->buffer_size; // * ad->channels * 2;
+ int todo = ad->period_size;
int total = 0;
while (todo) {
-
if (ad->exit_thread)
break;
uint8_t* src = (uint8_t*)ad->samples_out;
@@ -184,7 +171,8 @@ void AudioDriverALSA::thread_func(void* p_udata) {
break;
if ( wrote == -EAGAIN ) {
- usleep(1000); //can't write yet (though this is blocking..)
+ //can't write yet (though this is blocking..)
+ usleep(1000);
continue;
}
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
@@ -197,9 +185,9 @@ void AudioDriverALSA::thread_func(void* p_udata) {
}
continue;
};
+
total += wrote;
todo -= wrote;
-
};
};
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 487f017584..df28294f56 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -51,6 +51,7 @@ class AudioDriverALSA : public AudioDriverSW {
OutputFormat output_format;
snd_pcm_uframes_t buffer_size;
+ snd_pcm_uframes_t period_size;
int channels;
bool active;