Alsa player is still broken... but trying to do things differently at least.

Originally committed to SVN as r1145.
This commit is contained in:
Niels Martin Hansen 2007-04-26 18:34:36 +00:00
parent e04c25d378
commit 2e82606c29

View file

@ -68,7 +68,9 @@ private:
snd_pcm_format_t sample_format; snd_pcm_format_t sample_format;
unsigned int rate; // sample rate of audio unsigned int rate; // sample rate of audio
unsigned int real_rate; // actual sample rate played back unsigned int real_rate; // actual sample rate played back
int periods; // number of bytes in a frame unsigned int period_len; // length of period in microseconds
unsigned int buflen; // length of buffer in microseconds
snd_pcm_uframes_t period; // size of period in frames
snd_pcm_uframes_t bufsize; // size of buffer in frames snd_pcm_uframes_t bufsize; // size of buffer in frames
void SetUpHardware(); void SetUpHardware();
@ -161,6 +163,8 @@ void AlsaPlayer::OpenStream()
void AlsaPlayer::SetUpHardware() void AlsaPlayer::SetUpHardware()
{ {
int dir;
// Allocate params structure // Allocate params structure
snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_t *hwparams;
snd_pcm_hw_params_malloc(&hwparams); snd_pcm_hw_params_malloc(&hwparams);
@ -205,22 +209,34 @@ void AlsaPlayer::SetUpHardware()
throw _T("Could not set number of channels"); throw _T("Could not set number of channels");
} }
// Set periods (number of bytes ideally written at a time)
// Somewhat arbitrary for now (256 frames)
periods = provider->GetChannels() * provider->GetBytesPerSample() * 256;
if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0) < 0) {
throw _T("Could not set periods");
}
// Set buffer size // Set buffer size
snd_pcm_uframes_t wanted_bufsize = rate; unsigned int wanted_buflen = 1000000; // microseconds
bufsize = wanted_bufsize; buflen = wanted_buflen;
if (snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &bufsize) < 0) { if (snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams, &buflen, &dir) < 0) {
throw _T("Could not set buffer size"); throw _T("Couldn't set buffer length");
} }
if (bufsize != wanted_bufsize) { if (buflen != wanted_buflen) {
wxLogDebug(_T("Couldn't get wanted buffer size of %u, got %u instead"), wanted_bufsize, bufsize); wxLogDebug(_T("Couldn't get wanted buffer size of %u, got %u instead"), wanted_buflen, buflen);
} }
if (snd_pcm_hw_params_get_buffer_size(hwparams, &bufsize) < 0) {
throw _T("Couldn't get buffer size");
}
printf("Buffer size: %lu\n", bufsize);
// Set period (number of frames ideally written at a time)
// Somewhat arbitrary for now
unsigned int wanted_period = bufsize / 4;
period_len = wanted_period; // microseconds
if (snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams, &period_len, &dir) < 0) {
throw _T("Couldn't set period length");
}
if (period_len != wanted_period) {
wxLogDebug(_T("Couldn't get wanted period size of %d, got %d instead"), wanted_period, period_len);
}
if (snd_pcm_hw_params_get_period_size(hwparams, &period, &dir) < 0) {
throw _T("Couldn't get period size");
}
printf("Period size: %lu\n", period);
// Apply parameters // Apply parameters
if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) { if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) {
@ -249,7 +265,7 @@ void AlsaPlayer::SetUpAsync()
} }
// The the largest write guaranteed never to block // The the largest write guaranteed never to block
if (snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, bufsize/4) < 0) { if (snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, period) < 0) {
throw _T("Failed setting min available buffer"); throw _T("Failed setting min available buffer");
} }