summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Yves Avenard <jyavenard@mythtv.org>2010-12-16 12:08:28 (GMT)
committer Jean-Yves Avenard <jyavenard@mythtv.org>2010-12-16 12:08:28 (GMT)
commit271c60a5d4428475cbcc502ad49ac033c2840f9a (patch)
tree8184a7e8830359d3b2f184217fe4597605b6cf10
parenteb65d4be48eeffde2fc91359f4ce36b4f530056c (diff)
Change on how we calculate the required ALSA hardware buffer size.
Hopefully 4th time lucky. Instead of calculating what we think the size should be, use the size of the buffer ALSA allocated following our request. If less than requested, use the ratio between what we asked for and what we got, and multiply the current hardware buffer size by this value. Round it up the new nearest 64kB multiple
-rw-r--r--mythtv/libs/libmyth/audio/audiooutputalsa.cpp41
-rw-r--r--mythtv/libs/libmyth/audio/audiooutputalsa.h2
2 files changed, 21 insertions, 22 deletions
diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.cpp b/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
index 5180647..a71a7fc 100644
--- a/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
+++ b/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
@@ -178,7 +178,7 @@ bool AudioOutputALSA::SetPreallocBufferSize(int size)
int card, device, subdevice;
bool ret = true;
- VBAUDIO(QString("Setting preallocated buffer size to %1").arg(size));
+ VBERROR(QString("Setting hardware audio buffer size to %1").arg(size));
if (GetPCMInfo(card, device, subdevice) < 0)
return false;
@@ -193,9 +193,10 @@ bool AudioOutputALSA::SetPreallocBufferSize(int size)
if (!pfile.open(QIODevice::ReadWrite))
{
- VBERROR(QString("Error opening %1: %2. "
- "Try to increase it with: echo %3 | sudo tee %1")
- .arg(pfile.fileName()).arg(pfile.errorString()).arg(size));
+ VBERROR(QString("Error opening %1: %2. ")
+ .arg(pfile.fileName()).arg(pfile.errorString()));
+ VBERROR(QString("Try to manually increase audio buffer with: echo %1 "
+ "| sudo tee %2").arg(size).arg(pfile.fileName()));
return false;
}
@@ -212,7 +213,7 @@ bool AudioOutputALSA::SetPreallocBufferSize(int size)
return ret;
}
-bool AudioOutputALSA::IncPreallocBufferSize(int buffer_time)
+bool AudioOutputALSA::IncPreallocBufferSize(int requested, int buffer_time)
{
int card, device, subdevice;
bool ret = true;
@@ -242,21 +243,12 @@ bool AudioOutputALSA::IncPreallocBufferSize(int buffer_time)
int cur = pfile.readAll().trimmed().toInt();
int max = mfile.readAll().trimmed().toInt();
- int size = (((samplerate / 1000) *
- (buffer_time / 1000) *
- output_bytes_per_frame / 1024) / 64 + 1) * 64;
+ int size = ((int)(cur * (float)requested / (float)buffer_time)
+ / 64 + 1) * 64;
- VBAUDIO(QString("Prealloc buffer cur: %1 need: %2 max: %3")
+ VBAUDIO(QString("Hardware audio buffer cur: %1 need: %2 max allowed: %3")
.arg(cur).arg(size).arg(max));
- if(size == cur)
- {
- pfile.close();
- mfile.close();
- ret = false;
- return ret;
- }
-
if (size > max || !size)
{
size = max;
@@ -429,8 +421,8 @@ bool AudioOutputALSA::OpenDevice()
{
// We need to increase preallocated buffer size in the driver
// Set it and try again
- if(!IncPreallocBufferSize(buffer_time))
- VBERROR("Unable to sufficiently increase preallocated buffer size"
+ if(!IncPreallocBufferSize(buffer_time, err))
+ VBERROR("Unable to sufficiently increase ALSA hardware buffer size"
" - underruns are likely");
return OpenDevice();
}
@@ -588,6 +580,13 @@ int AudioOutputALSA::GetBufferedOnSoundcard(void) const
return delay * output_bytes_per_frame;
}
+/*
+ * Set the various ALSA audio parameters.
+ * Returns:
+ * < 0 : an error occurred
+ * 0 : Succeeded
+ * > 0 : Buffer timelength returned by ALSA which is less than what we asked for
+ */
int AudioOutputALSA::SetParameters(snd_pcm_t *handle, snd_pcm_format_t format,
uint channels, uint rate, uint buffer_time,
uint period_time)
@@ -606,7 +605,7 @@ int AudioOutputALSA::SetParameters(snd_pcm_t *handle, snd_pcm_format_t format,
if (handle == NULL)
{
Error("SetParameters() called with handle == NULL!");
- return 0;
+ return -1;
}
snd_pcm_hw_params_alloca(&params);
@@ -662,7 +661,7 @@ int AudioOutputALSA::SetParameters(snd_pcm_t *handle, snd_pcm_format_t format,
// See if we need to increase the prealloc'd buffer size
// If buffer_time is too small we could underrun
// Make 10% leeway okay
- if (buffer_time * 1.10f < (float)original_buffer_time && pbufsize < 0)
+ if ((buffer_time * 1.10f < (float)original_buffer_time) && pbufsize < 0)
{
VBAUDIO(QString("Requested %1us got %2 buffer time")
.arg(original_buffer_time).arg(buffer_time));
diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.h b/mythtv/libs/libmyth/audio/audiooutputalsa.h
index 2218b33..d0438f4 100644
--- a/mythtv/libs/libmyth/audio/audiooutputalsa.h
+++ b/mythtv/libs/libmyth/audio/audiooutputalsa.h
@@ -34,7 +34,7 @@ class AudioOutputALSA : public AudioOutputBase
int TryOpenDevice(int open_mode, int try_ac3);
int GetPCMInfo(int &card, int &device, int &subdevice);
bool SetPreallocBufferSize(int size);
- bool IncPreallocBufferSize(int buffer_time);
+ bool IncPreallocBufferSize(int requested, int buffer_time);
inline int SetParameters(snd_pcm_t *handle, snd_pcm_format_t format,
uint channels, uint rate, uint buffer_time,
uint period_time);