Bug 1004739
| Summary: | Audio problems with the multi PCM plugin - alsa-lib | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 6 | Reporter: | Jaroslav Kysela <jkysela> | ||||||||||
| Component: | alsa-lib | Assignee: | Jaroslav Kysela <jkysela> | ||||||||||
| Status: | CLOSED WONTFIX | QA Contact: | Desktop QE <desktop-qa-list> | ||||||||||
| Severity: | high | Docs Contact: | |||||||||||
| Priority: | high | ||||||||||||
| Version: | 6.4 | CC: | curtis.zinzilieta, jhunt, jkysela, snagar, Steven.Seed, tpelka, wtaymans | ||||||||||
| Target Milestone: | rc | Keywords: | OtherQA | ||||||||||
| Target Release: | --- | ||||||||||||
| Hardware: | x86_64 | ||||||||||||
| OS: | Linux | ||||||||||||
| Whiteboard: | |||||||||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||||||||
| Doc Text: | Story Points: | --- | |||||||||||
| Clone Of: | Environment: | ||||||||||||
| Last Closed: | 2015-09-18 13:54:56 UTC | Type: | Bug | ||||||||||
| Regression: | --- | Mount Type: | --- | ||||||||||
| Documentation: | --- | CRM: | |||||||||||
| Verified Versions: | Category: | --- | |||||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||||
| Embargoed: | |||||||||||||
| Bug Depends On: | |||||||||||||
| Bug Blocks: | 1002711 | ||||||||||||
| Attachments: |
|
||||||||||||
|
Description
Jaroslav Kysela
2013-09-05 11:35:13 UTC
Created attachment 794231 [details]
The used alsa-lib configuration
Second issue: "With the same configuration we are also occasionally having the audio drop out completely after playing an audio stream (for example in a flash plugin). To correct this we have to reload the web page." Created attachment 794325 [details]
output from alsa-info.sh for system tonberryking
output from alsa-info.sh from system tonberryking, per request.
-Curtis
I guess we have to process this issue as OtherQA, can we get commitment from Disney that they will test once fixed rpm available. We are waiting on direction or updated bits, and will test basically immediately when recommendations or updates are available. -Curtis Jaroslav, You mentioned in a previous email that "... the multi plugin was designed to group the outputs from same soundcard (one clock source) or synchronized sound cards (word clock, S/PDIF input clock or so)." Is it possible we can configure our environment so that the two cards use the same clock source? If so, how? There are no input ports on the Teradici card for audio. Any update on this issue? As I wrote in e-mail, the problem is in the two clock sources. Basically, we have one producer (application) and two consumers (sound cards). Both sound cards have own timing to "eat" samples. There is no way to use same clock for them (the hardware limitation in this case). Even if the clock drift is about 1%, the timing will be broken after some minutes, because the queue with samples for one soundcard will be empty or full (depending which consumer is the master for the multi plugin). So, it's a design issue and not the problem with the multi plugin itself. The solution is to put the adaptive resampling for one soundcard to maintain the clock differences. Unfortunately, alsa-lib does not have this implemented. I think that the easiest solution - in this case - is to keep the primary soundcard in the multi plugin configuration and use the ALSA's loopback driver (snd-aloop) as the second "monitoring" output. You can grab the returned samples using the alsaloop utility (in the alsa-utils package) and copy them with the resampling (not adaptive at the time) to the monitoring sound card. You can control the drift manually using 'PCM Rate Shift 100000' control (see 'amixer controls' command on the command line when the snd-aloop kernel module is loaded). Also note that the sync mode for alsaloop must be 'samplerate', otherwise the alsaloop will try to play with the 'PCM Rate Shift 100000' (adaptive resampling), but this will not work in this case, because the goal is to keep sync with the primary sound card and alsaloop cannot be instructed to do it. I believe that you can find the shift value to keep the clock differences (clicks) at minimum. There is one drawback with this solution - the delay on the "monitoring" output from the alsaloop. The minimal delay can be about 25-40ms - depending on the configuration. The above solution might be improved with the adaptive resampling, but the driver and/or the multi plugin in alsa-lib must be enhanced to do the clock sync. Please, if you like, try the suggested solution. I can eventually try to develop the sync code, but maybe, the manual time shift setting is sufficient in this case. Sorry, I was out of town last week. I'll see if I can try your solution with the alsaloop command will work for us and get back to you. I'm having difficutly in getting this to work. I'm loaded the snd-aloop module, but I'm not sure what to do with the new loopback devices. I've tried to run the alsaloop command to see if I can re-route the audio from one device to the other, but there is no audio coming out of the second device. Here are my cards: % aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Teradici [HDA Teradici], device 0: ALC888 Analog [ALC888 Analog] Subdevices: 0/1 Subdevice #0: subdevice #0 card 1: Intel [HDA Intel], device 0: ALC262 Analog [ALC262 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 Here is the command I run: % alsaloop -v -C hw:1,0 -P hw:0,0 -A 1 -n !!!Scheduler set to Round Robin with priority 99 FAILED! Hardware PCM card 0 'HDA Teradici' device 0 subdevice 0 Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 1920 period_size : 192 period_time : 4000 tstamp_mode : NONE period_step : 1 avail_min : 1560 period_event : 0 start_threshold : 2147483647 stop_threshold : 1920 silence_threshold: 0 silence_size : 0 boundary : 8646911284551352320 appl_ptr : 0 hw_ptr : 0 Hardware PCM card 1 'HDA Intel' device 0 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 1920 period_size : 240 period_time : 5000 tstamp_mode : NONE period_step : 1 avail_min : 240 period_event : 0 start_threshold : 2147483647 stop_threshold : 1920 silence_threshold: 0 silence_size : 0 boundary : 8646911284551352320 appl_ptr : 0 hw_ptr : 0 Latency 480 frames, 10000.000us, 10.000000ms (100.0000Hz) playback hw:0,0/capture hw:1,0 sync type: SAMPLERATE (SRC_SINC_MEDIUM_QUALITY) New pitch for playback hw:0,0/capture hw:1,0: 1.00000000 (min/max samples = 0/0) New pitch for playback hw:0,0/capture hw:1,0: 1.00001042 (min/max samples = 0/80) If I play audio on hw:1,0, I only hear it there. I must be missing something. This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate, in the next release of Red Hat Enterprise Linux. First we need to load the snd-aloop module, this should give a new card(s) with 2 new devices. Please paste output of aplay -l after modprobing the snd-aloop module to verify this setup.
You can try this setup like this (change the card number to the loopback device):
aplay -D hw:1,0 <some wav file to test>
This sends some audio to the new loop device, we can read this output by reading from the corresponding capture device:
alsaloop -C hw:1,1 -P hw:0,0 -v
We send this then to the real playback device and you should be able to hear the wav file.
Now, the idea is to send the audio to both the Intel card and the loopback device for the Intel card, which is the new device created by snd-aloop.
For that, the alsa configuration should be updated. I would suggest to make a new Intel_loop PCM device that send the audio to the loopback card. Add something like this to the config (need to use the right card numbers as seen with aplay -l):
pcm.Intel_loop_out_hw {
type hw
nonblock 1
card 3 # this should be the card number of the Intel loopback
device 0 # device 0 of loopback is for playback
subdevice 0
}
pcm.Intel_loop_in_hw {
type hw
nonblock 1
card 3 # this should be the card number of the Intel loopback
device 1 # device 1 of loopback is for capture
subdevice 0
}
pcm.Intel_loop_out {
type dmix
ipc_key 1024
ipc_key_add_uid false # let multiple users share
ipc_perm 0666 # IPC permissions for multi-user sharing (octal, default 0600)
slave {
pcm Intel_loop_out_hw
period_time 0
period_size 1024
buffer_size 16384
channels 2
}
hint { show on
description "dmix plugin for Intel_loopback"
}
bindings {
0 0
1 1
}
}
pcm.Intel_loop {
type asym
playback.pcm Intel_loop_out
capture.pcm Intel_loop_in_hw
}
Then we combine the Intel and the Intel loop cards by changing the pcm.dmixer device to something like this:
pcm.dmixer {
type route
hint { show on
description "dmixer combined pcm device"
}
slave.pcm {
type multi
slaves.0.pcm Intel_loop
slaves.0.channels 2
bindings.0.slave 0
bindings.0.channel 0
bindings.1.slave 0
bindings.1.channel 1
slaves.1.pcm Intel
slaves.1.channels 2
bindings.2.slave 1
bindings.2.channel 0
bindings.3.slave 1
bindings.3.channel 1
}
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
}
With this config, audio should be played to the Intel and the Intel_loop device.
The next step is to take the audio from the Intel_loop and send it to the Teradici device with alsaloop:
alsaloop -v -C Intel_loop -P Teradici
Now you should have both audio on Intel and Teradici and the alsaloop utility should dynamically adjust the samplerate to keep the clocks in sync.
I was able to get this working using your examples. Thanks. I've noticed there was quite a bit of latency between the two devices, so I tried reducing the latency value from the default down to 4000us. This seems to be fairly stable, but any latency below this seems to generate a significant number of underrun messages and eventually causes the alsaloop process to abort. It also seems to cause significantly more CPU load below this level. I just switched to running the alsaloop with the -d daemon mode and without the -v flag using the -t 4000 flag. Things seem more stable now. I'll run it like this for a while and see how it goes. Even in daemon mode running at 4000us, the aslaloop process still aborted after a couple of hours. Dec 23 16:10:49 astaroth alsaloop[24879]: playback hw:Teradici start failed: Broken pipe Dec 23 16:10:49 astaroth alsaloop[24879]: pcmjob failed. Is there any thing I can do to stabilize this or ensure the process stays up? alsaloop should use real-time round-robin scheduling when started by a sufficiently priviledged user. Could you try to run alsaloop as root to see if that avoids the underruns? Also, as per Comment 10, use the samplerate sync method with the -S4 option. Could you also paste the underrun info as generated with the -U option? With the new options, things seem more stable with less under runs. I'm running alsaloop as root with these options and it hasn't aborted yet in about 2 hours. I'll let it run over night to see if it stays up. # alsaloop -v -C Loopback -P hw:Teradici -S4 -t 4000 -U Here are some of the output data: playback hw:Teradici/capture Loopback sync type: SAMPLERATE (SRC_SINC_FASTEST) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -55/36) Hardware PCM card 1 'HDA Teradici' device 0 subdevice 0 Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 768 period_size : 96 period_time : 2000 tstamp_mode : NONE period_step : 1 avail_min : 624 period_event : 0 start_threshold : 2147483647 stop_threshold : 768 silence_threshold: 0 silence_size : 0 boundary : 6917529027641081856 appl_ptr : 0 hw_ptr : 0 Hardware PCM card 4 'Loopback' device 1 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 768 period_size : 96 period_time : 2000 tstamp_mode : NONE period_step : 1 avail_min : 96 period_event : 0 start_threshold : 2147483647 stop_threshold : 768 silence_threshold: 0 silence_size : 0 boundary : 6917529027641081856 appl_ptr : 0 hw_ptr : 0 Latency 192 frames, 4000.000us, 4.000000ms (250.0000Hz) playback hw:Teradici/capture Loopback sync type: SAMPLERATE (SRC_SINC_FASTEST) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -55/36) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -55/36) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -55/85) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00004167 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00004167 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = -55/90) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -57/90) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -70/90) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -77/90) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -77/90) New pitch for playback hw:Teradici/capture Loopback: 0.99998958 (min/max samples = -79/90) New pitch for playback hw:Teradici/capture Loopback: 0.99998958 (min/max samples = -79/90) underrun for playback hw:Teradici last write before 14.8650ms, queued 3.5625ms/0.0000ms -> missing 11.3025ms expected 4.0000ms, processing 0.1580ms, max missing 11.3025ms last wake 14.9030ms, last check 14.9030ms, avail_min 1.0000ms max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.2520ms New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = 0/16) underrun for playback hw:Teradici last write before 6.7810ms, queued 4.4792ms/0.0000ms -> missing 2.3018ms expected 4.0000ms, processing 0.3650ms, max missing 11.3025ms last wake 6.8180ms, last check 6.8180ms, avail_min 1.0000ms max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.1150ms New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = 0/14) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = 0/14) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = 0/14) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = 0/14) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -11/14) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -11/29) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -18/29) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -18/29) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -18/29) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -18/29) New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = -18/29) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -55/29) New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = -55/29) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -64/29) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = -64/29) underrun for playback hw:Teradici last write before 6.9360ms, queued 3.5208ms/0.0000ms -> missing 3.4152ms expected 4.0000ms, processing 0.2200ms, max missing 11.3025ms last wake 6.9540ms, last check 6.9540ms, avail_min 1.0000ms max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.1210ms Things have stayed up for over 12 hours. I think this is going to work for us. I'll be working on a implementing a solution that we can roll into production. Thanks While things are remaining up, I'm noticing that after a long period of time, the audio stream that is being passed through alsaloop is getting noisy with crackling and can possibly be delayed. I"m running a new test with the -v flag enabled (I was running without it). I'll get you some logs after this happens again. I'm also seeing a issue when I disconnect and reconnect my PCoIP client where the audio is very garbled and staticy with a large delay. This is pretty consistent. If I kill and relaunch the alsaloop process, the audio is back to normal again. I'm not sure if this is an issue with PCoIP or with alsa. It sounds like you hear dmix static that happens when it is close to underrunning. Do you happen to have some logs from alsaloop? It would be interesting to see what kind of resampling factor it calculates when the garbling starts. I think this is more of a problem caused by the Teradici card when it starts a connection and there is already an audio stream playing. Even restarting the alsaloop doesn't help if I do it quickly enough. I can get the audio between the two devices to sync up and eliminate the static if I just pause my audio for about 20 seconds and then restart it. During the time when the audio is out of sync and cracking, I see this in the logs: Jan 8 13:42:33 astaroth alsaloop[12248]: Scheduler set to Round Robin with priority 99 Jan 8 13:42:49 astaroth alsaloop[12248]: last write before 0.0810ms, queued 16.0000ms/15.0000ms -> missing -15.9190ms Jan 8 13:42:49 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.1970ms, max missing 0.0000ms Jan 8 13:42:49 astaroth alsaloop[12248]: last wake 0.0440ms, last check 0.0440ms, avail_min 1.0000ms Jan 8 13:42:49 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 41.2500ms, cfilled 32.0000ms Jan 8 13:42:49 astaroth alsaloop[12248]: job started before 0.0340ms Jan 8 13:43:00 astaroth alsaloop[12248]: last write before 0.0730ms, queued 16.0000ms/15.1667ms -> missing -15.9270ms Jan 8 13:43:00 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.2470ms, max missing 0.0000ms Jan 8 13:43:00 astaroth alsaloop[12248]: last wake 0.0370ms, last check 0.0370ms, avail_min 1.0000ms Jan 8 13:43:00 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 43.2500ms, cfilled 32.0000ms Jan 8 13:43:00 astaroth alsaloop[12248]: job started before 0.0250ms Jan 8 13:43:10 astaroth alsaloop[12248]: last write before 0.0790ms, queued 16.0000ms/15.0000ms -> missing -15.9210ms Jan 8 13:43:10 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.1810ms, max missing 0.0000ms Jan 8 13:43:10 astaroth alsaloop[12248]: last wake 0.0260ms, last check 0.0260ms, avail_min 1.0000ms Jan 8 13:43:10 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 44.1667ms, cfilled 32.0000ms Jan 8 13:43:10 astaroth alsaloop[12248]: job started before 0.0150ms Jan 8 13:43:45 astaroth alsaloop[12248]: last write before 10.3750ms, queued 6.1250ms/0.0000ms -> missing 4.2500ms Jan 8 13:43:45 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.1490ms, max missing 4.2500ms Jan 8 13:43:45 astaroth alsaloop[12248]: last wake 10.4430ms, last check 10.4430ms, avail_min 1.0000ms Jan 8 13:43:45 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms Jan 8 13:43:45 astaroth alsaloop[12248]: job started before 0.1720ms Jan 8 13:43:45 astaroth alsaloop[12248]: last write before 15.6060ms, queued 3.3333ms/0.0000ms -> missing 12.2727ms Jan 8 13:43:45 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.3630ms, max missing 12.2727ms Jan 8 13:43:45 astaroth alsaloop[12248]: last wake 15.6450ms, last check 15.6450ms, avail_min 1.0000ms Jan 8 13:43:45 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms Jan 8 13:43:45 astaroth alsaloop[12248]: job started before 0.0290ms Jan 8 13:44:23 astaroth alsaloop[12248]: last write before 9.7170ms, queued 3.7708ms/0.0000ms -> missing 5.9462ms Jan 8 13:44:23 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.1310ms, max missing 12.2727ms Jan 8 13:44:23 astaroth alsaloop[12248]: last wake 9.7560ms, last check 9.7560ms, avail_min 1.0000ms Jan 8 13:44:23 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms Jan 8 13:44:23 astaroth alsaloop[12248]: job started before 0.1610ms Jan 8 13:44:43 astaroth alsaloop[12248]: last write before 13.6540ms, queued 3.0833ms/0.0000ms -> missing 10.5707ms Jan 8 13:44:43 astaroth alsaloop[12248]: expected 4.0000ms, processing 0.2900ms, max missing 12.2727ms Jan 8 13:44:43 astaroth alsaloop[12248]: last wake 13.6730ms, last check 13.6730ms, avail_min 1.0000ms Jan 8 13:44:43 astaroth alsaloop[12248]: max buf 16.0000ms, pfilled 0.0000ms, cfilled 0.0000ms Jan 8 13:44:43 astaroth alsaloop[12248]: job started before 0.2260ms I'm also getting quite a bit of static and distortion just playing audio without the connection/disconnection issue. These appear to be caused by overruns. See logs below. Is there something I can do to control the flow better so it doesn't overrun like a buffer size? New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = 0/0) Hardware PCM card 1 'HDA Teradici' device 0 subdevice 0 Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 1536 period_size : 192 period_time : 4000 tstamp_mode : NONE period_step : 1 avail_min : 1248 period_event : 0 start_threshold : 2147483647 stop_threshold : 1536 silence_threshold: 0 silence_size : 0 boundary : 6917529027641081856 appl_ptr : 0 hw_ptr : 0 Hardware PCM card 3 'Loopback' device 1 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 1536 period_size : 192 period_time : 4000 tstamp_mode : NONE period_step : 1 avail_min : 192 period_event : 0 start_threshold : 2147483647 stop_threshold : 1536 silence_threshold: 0 silence_size : 0 boundary : 6917529027641081856 appl_ptr : 0 hw_ptr : 0 Latency 384 frames, 8000.000us, 8.000000ms (125.0000Hz) playback hw:Teradici/capture Loopback sync type: SAMPLERATE (SRC_SINC_FASTEST) New pitch for playback hw:Teradici/capture Loopback: 1.00000000 (min/max samples = 0/0) underrun for playback hw:Teradici last write before 17.3830ms, queued 7.2500ms/0.0000ms -> missing 10.1330ms expected 8.0000ms, processing 0.2270ms, max missing 10.1330ms last wake 17.4930ms, last check 17.4930ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.4110ms underrun for playback hw:Teradici last write before 14.2990ms, queued 7.8333ms/0.0000ms -> missing 6.4657ms expected 8.0000ms, processing 0.5920ms, max missing 10.1330ms last wake 14.4090ms, last check 14.4090ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.3200ms underrun for playback hw:Teradici last write before 11.1010ms, queued 8.1667ms/0.0000ms -> missing 2.9343ms expected 8.0000ms, processing 0.5220ms, max missing 10.1330ms last wake 11.2130ms, last check 11.2130ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 0.0000ms, cfilled 0.0000ms job started before 0.2640ms overrun for capture Loopback last write before 223.7900ms, queued 32.0000ms/0.0000ms -> missing 191.7900ms expected 8.0000ms, processing 0.4840ms, max missing 191.7900ms last wake 0.0520ms, last check 0.0520ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 2.9167ms, cfilled 0.0000ms job started before 0.0270ms New pitch for playback hw:Teradici/capture Loopback: 1.00001042 (min/max samples = 0/6441) overrun for capture Loopback last write before 0.0990ms, queued 32.0000ms/31.0000ms -> missing -31.9010ms expected 8.0000ms, processing 0.6010ms, max missing 191.7900ms last wake 0.0720ms, last check 0.0720ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 85.4167ms, cfilled 64.0000ms job started before 0.0410ms New pitch for playback hw:Teradici/capture Loopback: 1.00002083 (min/max samples = 0/5411) New pitch for playback hw:Teradici/capture Loopback: 1.00003125 (min/max samples = 0/7229) overrun for capture Loopback last write before 0.1210ms, queued 32.0000ms/31.0000ms -> missing -31.8790ms expected 8.0000ms, processing 0.6100ms, max missing 191.7900ms last wake 0.0470ms, last check 0.0470ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 85.5000ms, cfilled 64.0000ms job started before 0.0220ms New pitch for playback hw:Teradici/capture Loopback: 1.00004167 (min/max samples = 0/5413) New pitch for playback hw:Teradici/capture Loopback: 1.00005208 (min/max samples = 0/7215) overrun for capture Loopback last write before 0.1020ms, queued 32.0000ms/31.0000ms -> missing -31.8980ms expected 8.0000ms, processing 0.5930ms, max missing 191.7900ms last wake 0.0470ms, last check 0.0470ms, avail_min 2.0000ms max buf 32.0000ms, pfilled 81.5000ms, cfilled 64.0000ms job started before 0.0240ms I've switched to using -S1 instead of -S4 and I seem to have gotten rid of the static noise. It's a lot better but I'm still having occasional audio sync issues. Can you think of any way to improve this? The sync goes in and out and back in. I'm getting frequent messages like this: Jan 12 20:21:40 astaroth alsaloop[1399]: job started before 0.0250ms Jan 12 20:21:48 astaroth alsaloop[1399]: last write before 0.1220ms, queued 16.0000ms/15.0833ms -> missing -15.8780ms Jan 12 20:21:48 astaroth alsaloop[1399]: expected 4.0000ms, processing 0.1090ms, max missing 376.2030ms Jan 12 20:21:48 astaroth alsaloop[1399]: last wake 0.0320ms, last check 0.0320ms, avail_min 1.0000ms Jan 12 20:21:48 astaroth alsaloop[1399]: max buf 16.0000ms, pfilled 31.9167ms, cfilled 32.0000ms Jan 12 20:21:48 astaroth alsaloop[1399]: job started before 0.0220ms Jan 12 20:21:56 astaroth alsaloop[1399]: last write before 0.1540ms, queued 16.0000ms/15.0833ms -> missing -15.8460ms Jan 12 20:21:56 astaroth alsaloop[1399]: expected 4.0000ms, processing 0.1080ms, max missing 376.2030ms Jan 12 20:21:56 astaroth alsaloop[1399]: last wake 0.0750ms, last check 0.0750ms, avail_min 1.0000ms Jan 12 20:21:56 astaroth alsaloop[1399]: max buf 16.0000ms, pfilled 31.9167ms, cfilled 32.0000ms Jan 12 20:21:56 astaroth alsaloop[1399]: job started before 0.0230ms Jan 12 20:22:04 astaroth alsaloop[1399]: last write before 0.1100ms, queued 16.0000ms/15.0833ms -> missing -15.8900ms Jan 12 20:22:04 astaroth alsaloop[1399]: expected 4.0000ms, processing 0.1090ms, max missing 376.2030ms Jan 12 20:22:04 astaroth alsaloop[1399]: last wake 0.0320ms, last check 0.0320ms, avail_min 1.0000ms Jan 12 20:22:04 astaroth alsaloop[1399]: max buf 16.0000ms, pfilled 31.9167ms, cfilled 32.0000ms Jan 12 20:22:04 astaroth alsaloop[1399]: job started before 0.0220ms I think that -S1 hides only the real problem. Your configuration uses 8ms latency which is too small. It seems that Terradici updates the pointer in the DMA ring buffer with some granurality, so I would suggest to use the latency between 25-50ms. Also, we don't use the real-time linux kernel, so smaller latencies might be impossible with the linux kernel scheduler / some hardware drivers. alsaloop -t 50000 I see your comment#15 which asks to reduce the latency to minimum, but I don't understand the goal, because if you have the remote display/audio, you usually don't expect to have same latencies as for the direct hardware. Also, how is the graphics is synchronized with the remote side? Perhaps, a fixed delay can be added to video to keep the video/audio in sync. I think S1 works the best because it's dropping samples to keep up which I think is acceptable for our remote clients. I think sync is more important than sample integrity. The problem with latency that is too high is there is noticeable lag between audio and video during playback. While there is typically 25-40ms latency when viewing remotely from a PCoIP system, the audio and video have the same latency. With alsaloop it adds additional latency on the audio stream that is not present on the video stream creating the sync issue. I'll see how things work with '-t 25000'. I know that 50ms is too high. Do you see the same problems when using a higher latency? I've tried latency values up to 72000. I've moved in a new direction which is to trigger alsaloop to start as soon as the user connects and to exit when they disconnect. This helps with the lag seen with new connections, however I'm still not happy with the results. As soon as I move windows around and utilize some of the bandwidth, it causes the audio to get out of sync again until I restart alsaloop. I think Teradici is doing something with PCoIP to compensate for network speed and drops some of the video data to catch up, but the audio doesn't seem to get dropped accordingly by alsaloop possibly because of buffering. As a result, the audio ends up behind of the video. Is there a way to set alsaloop to keep a minimum of a buffer or when an overrun occurs to drop the buffer or some how resync with the source? I never have these sync issues when using the Teradici PCoIP audio device directly. It's only when I use alsaloop to loop the audio from a second source to the Teradici device. Is audio interrupted (little skips) if you move the windows? Could you attach debug output from alsaloop with 15 -v options (-vvvvvvvvvvvvvvv) for 50000 latency? It would be nice, if you can mark somehow the point when the A/V streams are desynced. (In reply to Steven Seed from comment #30) > I never have these sync issues when using the Teradici PCoIP audio device > directly. It's only when I use alsaloop to loop the audio from a second > source to the Teradici device. But the alsaloop should have similar feedback from the Teradici driver like am audio player for the direct playback. Perhaps the alsaloop is just confused, if the audio device behaves in some non-standard way. It might be also good to know, if Terradici does also the sound sync (stream time modification). Could you play some long file with 'aplay' on the direct Terradici device without system load and with heavy video load / windows moves? If times are different (example 'time aplay -D Terradici <some_wav_file>'), then we cannot use the linear clock difference assumption (between the onboard audio and Terradici). Audio doesn't seem to skip when moving windows. I can't seem to pin point a specific time when the a/v goes out of sync, but it doesn't take too much. If I'm working with a more restrictive network, say with about 15Mbps throughput the sync problem happens more quickly than over a LAN. I'm attaching the debug output for you, one at full 1Gbps network speeds (alsaloop.log) and one restricted to 15Mbps (alsaloop-15M.log Regarding the stream time modification, I tried a few tests with a 3 minute clip with and without network load and I couldn't really seem a consistent time difference playing back the clip. There was a variance of about .03-0.10s with or without load. Do you think I need longer clip to test with? Created attachment 858903 [details]
alsaloop debug output (1Gpbs)
Created attachment 858904 [details]
alsaloop debug output (15Mbps)
This Bugzilla has been reviewed by Red Hat and is not planned on being addressed in Red Hat Enterprise Linux 6 and therefore will be closed. If this bug is critical to production systems, please contact your Red Hat support representative and provide sufficient business justification. |