2012/5/18 cee1 <[email protected]>: > 2012/5/18 cee1 <[email protected]>: >> 在 2012年5月18日星期五,Clemens Ladisch 写道: >> >>> cee1 wrote: >>> > We've found a way the can reproduce the problem more quickly on our >>> > product: >>> > 1. do audio playback >>> > 2. alsamixer, select 'Master', press 'm' and hold for a while. >>> > >>> > Then release 'm', playback corrupts(sounds similar to >>> > http://dev.lemote.com/files/upload/software/PA-apc/corrupted_sound.ogg). I've written a small program[1] that will let PA mute/unmute repeatedly.
I find the problem is something to do with rewind_safeguard, If I
adjust rewind_safeguard to eighth of the original value, it can also
be easily reproduced through pa-mute-test.c on the AMD turion 64 x2
board in ubuntu 12.04:
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -86,8 +86,8 @@
#define VOLUME_ACCURACY (PA_VOLUME_NORM/100) /* don't require volume
adjustments to be perfectly correct. do
-#define DEFAULT_REWIND_SAFEGUARD_BYTES (256U) /* 1.33ms @48kHz, we'll
never rewind less than this */
-#define DEFAULT_REWIND_SAFEGUARD_USEC (1330) /* 1.33ms, depending on
channels/rate/sample we may rewind more
+#define DEFAULT_REWIND_SAFEGUARD_BYTES (32U) /* 1.33ms @48kHz, we'll
never rewind less than this */
+#define DEFAULT_REWIND_SAFEGUARD_USEC (166) /* 1.33ms, depending on
channels/rate/sample we may rewind more t
struct userdata {
pa_core *core;
Should we calculate limit_nbytes considering tsched_watermark?
e.g.(which works on our platform)
@@ -1614,7 +1614,7 @@ static int process_rewind(struct userdata *u) {
unused_nbytes = (size_t) unused * u->frame_size;
/* make sure rewind doesn't go too far, can cause issues with DMAs */
- unused_nbytes += u->rewind_safeguard;
+ unused_nbytes += u->tsched_watermark;
if (u->hwbuf_size > unused_nbytes)
limit_nbytes = u->hwbuf_size - unused_nbytes;
----
[1]. See pa-mute-test.c in attachment, using build.sh to build it.
Regards,
-- cee1
#include <glib.h>
#include <pulse/pulseaudio.h>
#include <pulse/glib-mainloop.h>
#define INTERVAL 125
#define TEST_NR ((1000/INTERVAL)*3600*72UL)
struct context{
pa_context *pa_cxt;
GMainLoop *main_loop;
};
gboolean set_mute_unmute(struct context *cxt)
{
static gboolean mute = TRUE;
static gint count = 0;
pa_operation *o;
mute = !mute;
count++;
o = pa_context_set_sink_mute_by_index(cxt->pa_cxt, 0, mute, NULL, NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_mute_by_index() failed: %s", pa_strerror(pa_context_errno(cxt->pa_cxt)));
g_main_quit(cxt->main_loop);
return FALSE;
}
if (count == TEST_NR) {
g_print("Max test number(=%lu) reached, quit.\n", TEST_NR);
g_main_quit(cxt->main_loop);
return FALSE;
}
g_print("\r%10d:\tset to %6s", count, mute ? "mute":"unmute");
pa_operation_unref(o);
return TRUE;
}
int main()
{
struct context cxt;
pa_glib_mainloop *pa_main_loop;
int r;
pa_main_loop = pa_glib_mainloop_new(NULL);
cxt.pa_cxt = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "mute-automute-test");
cxt.main_loop = g_main_loop_new(NULL, FALSE);
r = pa_context_connect(cxt.pa_cxt, NULL, 0, NULL);
if (r) {
g_print("Failed to connect PA server.\n");
exit(3);
}
g_timeout_add(INTERVAL, (GSourceFunc) set_mute_unmute, &cxt);
g_main_loop_run(cxt.main_loop);
return 0;
}
build.sh
Description: Bourne shell script
_______________________________________________ pulseaudio-discuss mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
