[alsa-devel] commit bd5389278c96f585afcac4058420e4f3ac201d2a introduce big problem
Hi Takash,
commit bd5389278c96f585afcac4058420e4f3ac201d2a Author: Takashi Iwai tiwai@suse.de Date: Fri Aug 21 01:18:00 2009 +0200
pcm: workaround for avoiding automatic start in mmap mode
In the normal mmap mode, the stream isn't started automatically even after the data >= start_threshold has been written. However, in the mmap-emulation mode, the stream is started because it uses snd_pcm_write_areas() internally.
As a workaround for this inconsistency, start_threshold value is changed dynamically in sw_parmams and mmap_commit callbacks in mmap-emul plugin. Meanwhile, start_threshold for slave PCM is set to boundary so that only this plugin (or the one over it) can control the start of the stream.
This will fix problems in some apps using pulse plugin in the mmap mode.
Signed-off-by: Takashi Iwai tiwai@suse.de
src/pcm/pcm_mmap_emul.c
This commit caused codec using mmap-emul plugin can't work. My config file list below:
bfin-ad1836.pcm.default { @args [ CARD ] @args.CARD { type string } type plug slave.pcm { type mmap_emul slave.pcm { type hw card $CARD format S32_LE rate 48000 } } }
Alsa will not send SNDRV_PCM_IOCTL_START to driver. But if I revert this patch only, the sound will be bad. I guess there must be something else to do.
Regards, Scott
At Tue, 8 Nov 2011 17:16:33 +0800, Scott Jiang wrote:
Hi Takash,
commit bd5389278c96f585afcac4058420e4f3ac201d2a Author: Takashi Iwai tiwai@suse.de Date: Fri Aug 21 01:18:00 2009 +0200
pcm: workaround for avoiding automatic start in mmap mode In the normal mmap mode, the stream isn't started automatically even after the data >= start_threshold has been written. However, in the mmap-emulation mode, the stream is started because it uses snd_pcm_write_areas() internally. As a workaround for this inconsistency, start_threshold value is changed dynamically in sw_parmams and mmap_commit callbacks in mmap-emul plugin. Meanwhile, start_threshold for slave PCM is set to boundary so that only this plugin (or the one over it) can control the start of the stream. This will fix problems in some apps using pulse plugin in the mmap mode. Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/pcm/pcm_mmap_emul.c
This commit caused codec using mmap-emul plugin can't work. My config file list below:
bfin-ad1836.pcm.default { @args [ CARD ] @args.CARD { type string } type plug slave.pcm { type mmap_emul slave.pcm { type hw card $CARD format S32_LE rate 48000 } } }
Alsa will not send SNDRV_PCM_IOCTL_START to driver.
And how are you testing it? The whole background is missing...
Takashi
2011/11/8 Takashi Iwai tiwai@suse.de:
At Tue, 8 Nov 2011 17:16:33 +0800, Scott Jiang wrote:
Hi Takash,
commit bd5389278c96f585afcac4058420e4f3ac201d2a Author: Takashi Iwai tiwai@suse.de Date: Fri Aug 21 01:18:00 2009 +0200
pcm: workaround for avoiding automatic start in mmap mode
In the normal mmap mode, the stream isn't started automatically even after the data >= start_threshold has been written. However, in the mmap-emulation mode, the stream is started because it uses snd_pcm_write_areas() internally.
As a workaround for this inconsistency, start_threshold value is changed dynamically in sw_parmams and mmap_commit callbacks in mmap-emul plugin. Meanwhile, start_threshold for slave PCM is set to boundary so that only this plugin (or the one over it) can control the start of the stream.
This will fix problems in some apps using pulse plugin in the mmap mode.
Signed-off-by: Takashi Iwai tiwai@suse.de
src/pcm/pcm_mmap_emul.c
This commit caused codec using mmap-emul plugin can't work. My config file list below:
bfin-ad1836.pcm.default { @args [ CARD ] @args.CARD { type string } type plug slave.pcm { type mmap_emul slave.pcm { type hw card $CARD format S32_LE rate 48000 } } }
Alsa will not send SNDRV_PCM_IOCTL_START to driver.
And how are you testing it? The whole background is missing...
Sorry, I sent it to you in former mail. I post it again.
When I use ad1836 and ad1938 with alsa lib 1.0.24, there is an error:
root:/> arecord -t wav -c 2 -d 3 -r 48000 -f S32_LE 1.wav Recording WAVE '1.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo arecord: pcm_read:1773: read error: Input/output error
If format isn't S32_LE, snd_pcm_plugin_readi will be called and everything works fine.
Regards, Scott
When I use ad1836 and ad1938 with alsa lib 1.0.24, there is an error:
root:/> arecord -t wav -c 2 -d 3 -r 48000 -f S32_LE 1.wav Recording WAVE '1.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo arecord: pcm_read:1773: read error: Input/output error
If format isn't S32_LE, snd_pcm_plugin_readi will be called and everything works fine.
Hi Takashi, Any feedback for this bug? I appreciate your help.
Regards, Scott
At Mon, 14 Nov 2011 17:53:10 +0800, Scott Jiang wrote:
When I use ad1836 and ad1938 with alsa lib 1.0.24, there is an error:
root:/> arecord -t wav -c 2 -d 3 -r 48000 -f S32_LE 1.wav Recording WAVE '1.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo arecord: pcm_read:1773: read error: Input/output error
If format isn't S32_LE, snd_pcm_plugin_readi will be called and everything works fine.
Hi Takashi, Any feedback for this bug? I appreciate your help.
Does your driver support mmap? What shows aplay -v with the arguments above?
I know of a problem of mmap-emul plugin when it runs over a slave that supports the mmap by itself. But it should work when it runs over a slave that doesn't support mmap.
Takashi
2011/11/14 Takashi Iwai tiwai@suse.de:
At Mon, 14 Nov 2011 17:53:10 +0800, Does your driver support mmap?
No, our tdm driver doesn't support mmap.
struct snd_pcm_ops bf5xx_pcm_tdm_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, .hw_free = bf5xx_pcm_hw_free, .prepare = bf5xx_pcm_prepare, .trigger = bf5xx_pcm_trigger, .pointer = bf5xx_pcm_pointer, .copy = bf5xx_pcm_copy, .silence = bf5xx_pcm_silence, }; And only support s32_le and 48000 static const struct snd_pcm_hardware bf5xx_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME), .formats = SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_48000, .channels_min = 2, .channels_max = 8, .buffer_bytes_max = PCM_BUFFER_MAX, .period_bytes_min = FRAGMENT_SIZE_MIN, .period_bytes_max = PCM_BUFFER_MAX/2, .periods_min = FRAGMENTS_MIN, .periods_max = FRAGMENTS_MAX, };
What shows aplay -v with the arguments above?
root:/> arecord -t wav -c 2 -r 48000 -f S16_LE -d 3 -v 1.wav Recording WAVE '1.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo Plug PCM: Linear conversion PCM (S32_LE) 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 : 4096 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1 stop_threshold : 4096 silence_threshold: 0 silence_size : 0 boundary : 1073741824 Slave: Mmap emulation PCM Its setup is: stream : CAPTURE access : MMAP_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 4096 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1 stop_threshold : 4096 silence_threshold: 0 silence_size : 0 boundary : 1073741824 Slave: Hardware PCM card 0 'bfin-ad1836' device 0 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 4096 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1073741824 stop_threshold : 4096 silence_threshold: 0 silence_size : 0 boundary : 1073741824 appl_ptr : 0 hw_ptr : 0 root:/> arecord -t wav -c 2 -r 48000 -f S32_LE -d 3 -v 1.wav Recording WAVE '1.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo Plug PCM: Mmap emulation PCM Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 4096 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1 stop_threshold : 4096 silence_threshold: 0 silence_size : 0 boundary : 1073741824 Slave: Hardware PCM card 0 'bfin-ad1836' device 0 subdevice 0 Its setup is: stream : CAPTURE access : RW_INTERLEAVED format : S32_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 32 buffer_size : 4096 period_size : 1024 period_time : 21333 tstamp_mode : NONE period_step : 1 avail_min : 1024 period_event : 0 start_threshold : 1073741824 stop_threshold : 4096 silence_threshold: 0 silence_size : 0 boundary : 1073741824 appl_ptr : 0 hw_ptr : 0 arecord: pcm_read:1773: read error: Input/output error
I know of a problem of mmap-emul plugin when it runs over a slave that supports the mmap by itself. But it should work when it runs over a slave that doesn't support mmap.
I found this bug was introduced by this commit I mentioned.
I found this bug was introduced by this commit I mentioned. From aplay info above, it seems if there is no plugin prior to mmap-emul, alsa lib will never send start cmd to driver.
Add some strace info, For S32_LE: ioctl(4, SNDRV_PCM_IOCTL_HW_REFINE, 0x2cbd854) = 0 ioctl(4, SNDRV_PCM_IOCTL_HW_PARAMS, 0x2cbd854) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4b718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbd044) = 0 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbd39c) = 0 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbd718) = 0 ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0xfffff000) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4b718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4b718) = 0 mmap2(NULL, 12288, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS|0x4000000, 0, 0) = 0x2e54000 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B57600 opost isig icanon echo ...}) = 0 fcntl(0, F_GETFL) = 0x2 (flags O_RDWR) fcntl(0, F_SETFL, O_RDWR|O_NONBLOCK) = 0 ioctl(0, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B57600 opost isig -icanon echo ...}) = 0 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B57600 opost isig -icanon echo ...}) = 0 rmdir("1.wav") = -1 ENOENT (No such file or directory) open("1.wav", O_WRONLY|O_CREAT|O_LARGEFILE, 0644) = 3 write(3, "RIFF$\224\21\0WAVE", 12) = 12 write(3, "fmt \20\0\0\0", 8) = 8 write(3, "\1\0\2\0\200\273\0\0\0\334\5\0\10\0 \0", 16) = 16 write(3, "data\0\224\21\0", 8) = 8 read(0, 0x2cbdb2f, 1) = -1 EAGAIN (Resource temporarily unavailable) ioctl(4, SNDRV_PCM_IOCTL_READI_FRAMES, 0x2cbdb2c) = -1 EIO (Input/output error) write(2, "arecord", 7arecord) = 7 write(2, ": ", 2: ) = 2 write(2, "pcm_read", 8pcm_read) = 8 write(2, ":", 1:) = 1 write(2, "1773", 41773) = 4 write(2, ": ", 2: ) = 2 write(2, "read error: ", 12read error: ) = 12 write(2, "Input/output error", 18Input/output error) = 18 write(2, "\n", 1
And for S16_LE: ioctl(4, SNDRV_PCM_IOCTL_HW_REFINE, 0x2cbd0d4) = 0 ioctl(4, SNDRV_PCM_IOCTL_HW_PARAMS, 0x2cbd0d4) = -1 EINVAL (Invalid argument) ioctl(4, SNDRV_PCM_IOCTL_HW_REFINE, 0x2cbd0d4) = 0 ioctl(4, SNDRV_PCM_IOCTL_HW_PARAMS, 0x2cbd0d4) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbccdc) = 0 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbd034) = 0 mmap2(NULL, 36864, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS|0x4000000, 0, 0) = 0x2e60000 ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0x2cbd39c) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0xfffff000) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS|0x4000000, 0, 0) = 0x2e54000 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B57600 opost isig icanon echo ...}) = 0 fcntl(0, F_GETFL) = 0x2 (flags O_RDWR) fcntl(0, F_SETFL, O_RDWR|O_NONBLOCK) = 0 ioctl(0, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B57600 opost isig -icanon echo ...}) = 0 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B57600 opost isig -icanon echo ...}) = 0 rmdir("1.wav") = -1 ENOENT (No such file or directory) open("1.wav", O_WRONLY|O_CREAT|O_LARGEFILE, 0644) = 3 write(3, "RIFF$\312\10\0WAVE", 12) = 12 write(3, "fmt \20\0\0\0", 8) = 8 write(3, "\1\0\2\0\200\273\0\0\0\356\2\0\4\0\20\0", 16) = 16 write(3, "data\0\312\10\0", 8) = 8 read(0, 0x2cbdb2f, 1) = -1 EAGAIN (Resource temporarily unavailable) ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_START, 0xfffff000) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ppoll([{fd=4, events=POLLIN|POLLERR|POLLNVAL}], 1, NULL, NULL, 8) = 1 ([{fd=4, revents=POLLIN}]) ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_READI_FRAMES, 0x2cbd9d4) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 write(3, "\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0\352\0"..., 4096) = 4096 read(0, 0x2cbdb2f, 1) = -1 EAGAIN (Resource temporarily unavailable) ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_READI_FRAMES, 0x2cbd9d4) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0x2e4c718) = 0 ioctl(4, SNDRV_PCM_IOCTL_READI_FRAMES, 0x2cbd9d4) = 0
So we can see ioctl(4, SNDRV_PCM_IOCTL_START, 0xfffff000) was missed before ioctl(4, SNDRV_PCM_IOCTL_READI_FRAMES, 0x2cbd9d4) in S32_LE format test case.
Regards, Scott
At Tue, 15 Nov 2011 14:08:36 +0800, Scott Jiang wrote:
2011/11/14 Takashi Iwai tiwai@suse.de:
At Mon, 14 Nov 2011 17:53:10 +0800, Does your driver support mmap?
No, our tdm driver doesn't support mmap.
OK, then could you try the latest alsa-lib git? I committed the possible fix for your problem.
thanks,
Takashi
2011/11/15 Takashi Iwai tiwai@suse.de:
At Tue, 15 Nov 2011 14:08:36 +0800, Scott Jiang wrote:
2011/11/14 Takashi Iwai tiwai@suse.de:
At Mon, 14 Nov 2011 17:53:10 +0800, Does your driver support mmap?
No, our tdm driver doesn't support mmap.
OK, then could you try the latest alsa-lib git? I committed the possible fix for your problem.
I confirm the patch works. Thanks. Scott
participants (2)
-
Scott Jiang
-
Takashi Iwai