[alsa-devel] loopback snd_pcm_writei
Hi,
I have the configuration in the asound.conf above.
my_plug - - > my_route - - > my_multi - - > slave0 (forward) - - > slave1 (loopback)
I open the plug my_plug in the block mode:
writtenFrames = snd_pcm_writei(handle, bufferToWrite, bufferToWriteSize);
The issue I see is that there are several "writes" with 0 written frames. It seems like the snd_pcm_writei does not hold until data will be written. In general, 0 written frames sounds weird to me, because snd_pcm_writei should block itself if no space is available in the circular buffer right?
I have tried to fix the following method in pcm_multi.c, as Jaroslav Kysela suggests.
-static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail ATTRIBUTE_UNUSED) +static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail) { snd_pcm_multi_t *multi = pcm->private_data; - snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm; - return snd_pcm_may_wait_for_avail_min(slave, snd_pcm_mmap_avail(slave)); + unsigned int i; + for (i = 0; i < multi->slaves_count; ++i) { + if (snd_pcm_may_wait_for_avail_min(multi->slaves[i].pcm, avail)) + return 1; + } + return 0; }
But unfortunately the issue has not been resolved.
#************************************************* # PLAYBACK #*************************************************
pcm.my_plug { type plug slave.pcm my_route slave.channels 2 }
pcm.my_route { type route slave.pcm my_multi slave.channels 4 ttable.0.0 1 ttable.0.1 1 ttable.1.2 1 ttable.1.3 1 }
pcm.my_multi { type multi slaves { slave0 { pcm my_dmix channels 2 } slave1 { pcm my_dmix_loop channels 2 } } bindings { 0 {slave slave0 channel 0} 1 {slave slave0 channel 1} 2 {slave slave1 channel 0} 3 {slave slave1 channel 1} } }
#-------------------- Slave 0 --------------------
pcm.my_dmix { type dmix ipc_key 1000 ipc_key_add_uid 1 ipc_perm 0600 slave.period_time 10000 slave.period_size 480 slave.buffer_size 3840 slave.rate 48000 slave.pcm "hw:0,0" }
#-------------------- Slave 1 --------------------
pcm.my_dmix_loop { type dmix ipc_key 1000 ipc_key_add_uid 1 ipc_perm 0600 slave.period_time 10000 slave.period_size 480 slave.buffer_size 3840 slave.rate 48000 slave.pcm my_loopback_out }
pcm.my_loopback_out { type hw card Loopback device 0 subdevice 0 }
#************************************************* # CAPTURE #*************************************************
pcm.my_dsnoop_loop { type dsnoop ipc_key 1000 ipc_key_add_uid 1 ipc_perm 0600 slave.period_time 10000 slave.period_size 480 slave.buffer_size 3840 slave.rate 48000 slave.pcm my_loopback_in }
pcm.my_loopback_in { type hw card Loopback device 1 subdevice 0 }
Dne 01. 04. 19 v 15:51 Giuliano Zannetti - ART S.p.A. napsal(a):
Hi,
I have the configuration in the asound.conf above.
my_plug - - > my_route - - > my_multi - - > slave0 (forward) - - > slave1 (loopback)
I open the plug my_plug in the block mode:
writtenFrames = snd_pcm_writei(handle, bufferToWrite, bufferToWriteSize);
The issue I see is that there are several "writes" with 0 written frames. It seems like the snd_pcm_writei does not hold until data will be written. In general, 0 written frames sounds weird to me, because snd_pcm_writei should block itself if no space is available in the circular buffer right?
I have tried to fix the following method in pcm_multi.c, as Jaroslav Kysela suggests.
-static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail ATTRIBUTE_UNUSED) +static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail) { snd_pcm_multi_t *multi = pcm->private_data;
snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm;
return snd_pcm_may_wait_for_avail_min(slave, snd_pcm_mmap_avail(slave));
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (snd_pcm_may_wait_for_avail_min(multi->slaves[i].pcm, avail))
return 1;
}
return 0;
}
But unfortunately the issue has not been resolved.
Hi,
I did some debugging (it's pretty reproducible) and the real fixes are here:
https://git.alsa-project.org/?p=alsa-lib.git;a=commit;h=4694a6643dc09c5e4196... https://git.alsa-project.org/?p=alsa-lib.git;a=commit;h=c7fc3fdbe23e63757b0e... https://git.alsa-project.org/?p=alsa-lib.git;a=commit;h=369df322577034ea8729... https://git.alsa-project.org/?p=alsa-lib.git;a=commit;h=0bfad420efea328a5036...
Just get the latest alsa-lib and it should work correctly now. Let me know the result.
Thanks. Jaroslav
Hi Jaroslav, Thank you for the fix. I tried it and I don't have 0-written-frames anymore. To be sure that the fix works fine, I compared the multi scenario (forward+loopback) with the forward-only scenario. It works fine in both cases, but sometimes in the multi scenario I have underruns. Could it depend from the fix? Or the usage of multi itself can bring to underruns?
-----Messaggio originale----- Da: Jaroslav Kysela perex@perex.cz Inviato: martedì 9 aprile 2019 10:37 A: Giuliano Zannetti - ART S.p.A. giuliano.zannetti@artgroup-spa.com; alsa-devel@alsa-project.org Oggetto: Re: [alsa-devel] loopback snd_pcm_writei
Dne 01. 04. 19 v 15:51 Giuliano Zannetti - ART S.p.A. napsal(a):
Hi,
I have the configuration in the asound.conf above.
my_plug - - > my_route - - > my_multi - - > slave0 (forward) - - > slave1 (loopback)
I open the plug my_plug in the block mode:
writtenFrames = snd_pcm_writei(handle, bufferToWrite, bufferToWriteSize);
The issue I see is that there are several "writes" with 0 written frames. It seems like the snd_pcm_writei does not hold until data will be written. In general, 0 written frames sounds weird to me, because snd_pcm_writei should block itself if no space is available in the circular buffer right?
I have tried to fix the following method in pcm_multi.c, as Jaroslav Kysela suggests.
-static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail ATTRIBUTE_UNUSED) +static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail) { snd_pcm_multi_t *multi = pcm->private_data;
snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm;
return snd_pcm_may_wait_for_avail_min(slave, snd_pcm_mmap_avail(slave));
unsigned int i;
for (i = 0; i < multi->slaves_count; ++i) {
if (snd_pcm_may_wait_for_avail_min(multi->slaves[i].pcm, avail))
return 1;
}
return 0;
}
But unfortunately the issue has not been resolved.
Hi,
I did some debugging (it's pretty reproducible) and the real fixes are here:
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.alsa-p... https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.alsa-p... https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.alsa-p... https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.alsa-p...
Just get the latest alsa-lib and it should work correctly now. Let me know the result.
Thanks. Jaroslav
participants (2)
-
Giuliano Zannetti - ART S.p.A.
-
Jaroslav Kysela