Re: [alsa-devel] multi pcm and mmap problem
At Wed, 21 Nov 2007 16:27:52 -0500, Tim wrote:
On Wednesday 21 November 2007 06:01:22 am you wrote:
At Wed, 21 Nov 2007 01:58:41 -0500,
terminator356@users.sourceforge.net wrote:
After 2 years I've finally traced and fixed a problem which was preventing me from using anything after ALSA 1.0.9b !
In ALSA lib 1.0.9b: pcm/pcm_generic.c: int snd_pcm_generic_channel_info() { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_channel_info(generic->slave, info); }
But in ALSA lib 1.0.15: pcm/pcm_generic.c: int snd_pcm_generic_channel_info() { snd_pcm_generic_t *generic = pcm->private_data; if (pcm->mmap_shadow) { /* No own buffer is required - the plugin won't change * the data on the buffer, or do safely on-the-place * conversion */ return snd_pcm_channel_info(generic->slave, info); } else { // Tim: TESTED: This is now called instead of the other one! /* Allocate own buffer */ return snd_pcm_channel_info_shm(pcm, info, -1); } }
My multi PCM consists of a plughw:0,2 and a hw:1,0 In ALSA 1.0.9b, all five PCMs ALSA creates for this arrangement create their areas with mmap(). And it works. But in ALSA 1.0.15 my hw:1,0 and its multi PCM areas are created with mmap(), and my plughw:0,2 and its PCMs areas are created with malloc(). Can't hear/record any sound from the plughw:0,2 part of the multi.
I have verified that ALSA 1.0.15 is copying the plughw:0,2 HW PCM areas to its LINEAR PCM areas, but NOT finally to its multi PCM areas. It just copies all zeros. That's the reason I hear/record no sound from the plughw:0,2 part of the multi PCM. So I reverted the function's code back to 1.0.9b and presto! It works now, the same as in ALSA 1.0.9b
So please tell me, am I missing something?
Well, first of all, could you elaborate what is the real problem you are facing? Judging from your description above, it sounds like a clear bug, but I'm not sure where to start.
In addition to the detailed bug description, a testcase program would be greatly helpful.
OK. First, here's my simple testing .asoundrc : pcm.multi_rec { type multi; slaves.a.pcm "hw:1,0"; slaves.a.channels 12; slaves.b.pcm "plughw:0,2"; slaves.b.channels 16; bindings.0.slave a; bindings.0.channel 4; bindings.1.slave b; bindings.1.channel 10; } ctl.multi_rec { type hw; card 0; }
The two cards are SBLive! (emu10k1) and Delta1010LT (ice1712).
And here is the command line I run: arecord -I -v -t wav -c2 -r 48000 -f S32_LE -Dmulti_rec -d 3 \ --buffer-size 128 arecord-multi-ice-emu.wav
My problem is under ALSA 1.0.15 no sound is recorded from slave 'b' - (the plughw:0,2 channel). When I look at the two generated wav files, the first has data, and the second has all zeros.
So as I said before, I found that ALSA is copying data from the plughw:0,2 HW PCM area to its LINEAR PCM area (i.e. the actual conversion is taking place), but then somehow the data is not finally copied to its multi slave b PCM area - just all zeros are copied. Hence all zeros are stored in the second wav file.
But with ALSA 1.0.9b, since all the areas are allocated with mmap(), it works fine. It is only after ALSA 1.0.9b, that I get the problem. Because ALSA 1.0.15 is allocating both the plughw:0,2 LINEAR PCM area and multi slave slave b's PCM area with malloc(). It seems ALSA doesn't want to copy to areas created with malloc().
OK, point taken.
The problem is that the multi plugin creates unnecessary local buffer. It works somehow when the slave is a hw, but it doesn't for other types.
Try the patch below. This should fix the problem. Now the multi plugin just shadows the slave buffers via mmap.
Should I add something more to my .asoundrc ? I see that besides {type multi ... }, there is a {type share ...} defined. *** Does the 'share' have any use here? Can't find any docs on it.
The share type is used only for share plugin, so you can ignore it.
Also: Yes, I can see now, why you made this code change. mmap() has limits, so you switched over to malloc(). Those limits force the user to use small buffers and/or reduce the number of channels created.
No, mmap was never used between plugins. It was only for the hw layer even in the earlier verson. In the earlier version, SHM was used instead. But, the plugin buffer is referred only locally, so it makes no sense to use SHM for that. That's why now it was switched to malloc. (snd_pcm_channel_info_shm() is a rest of the old behavior, and thus its name is confusing...)
My point was this: Under ALSA 1.0.9b, (and with my fix to ALSA 1.0.15 to force it to use mmap() always - see above), if I run: arecord -I -v -t wav -c2 -r 48000 -f S32_LE -Dmulti_rec -d 3 \ --buffer-size 128 arecord-multi-ice-emu.wav it will run. But if I run arecord -I -v -t wav -c2 -r 48000 -f S32_LE -Dmulti_rec -d 3 \ --buffer-size 256 arecord-multi-ice-emu.wav it fails with "mmap() failed: Invalid argument". I quadrupled the available locked memory with a line in /etc/security/limits.conf * - memlock 128 but the second command line still fails. What am I doing wrong? How can I increase mmap() limits?
It must be irrelevant now...
Takashi
diff -r 3539f279ec38 src/pcm/pcm_multi.c --- a/src/pcm/pcm_multi.c Wed Nov 21 12:19:43 2007 +0100 +++ b/src/pcm/pcm_multi.c Fri Nov 23 14:40:39 2007 +0100 @@ -690,13 +690,43 @@ static snd_pcm_sframes_t snd_pcm_multi_m return size; }
-static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_munmap(snd_pcm_t *pcm) { + free(pcm->mmap_channels); + free(pcm->running_areas); + pcm->mmap_channels = NULL; + pcm->running_areas = NULL; return 0; }
-static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_mmap(snd_pcm_t *pcm) { + snd_pcm_multi_t *multi = pcm->private_data; + unsigned int c; + + pcm->mmap_channels = calloc(pcm->channels, + sizeof(pcm->mmap_channels[0])); + pcm->running_areas = calloc(pcm->channels, + sizeof(pcm->running_areas[0])); + if (!pcm->mmap_channels || !pcm->running_areas) { + snd_pcm_multi_munmap(pcm); + return -ENOMEM; + } + + /* Copy the slave mmapped buffer data */ + for (c = 0; c < pcm->channels; c++) { + snd_pcm_multi_channel_t *chan = &multi->channels[c]; + snd_pcm_t *slave; + if (chan->slave_idx < 0) { + snd_pcm_multi_munmap(pcm); + return -ENXIO; + } + slave = multi->slaves[chan->slave_idx].pcm; + pcm->mmap_channels[c] = + slave->mmap_channels[chan->slave_channel]; + pcm->running_areas[c] = + slave->running_areas[chan->slave_channel]; + } return 0; }
@@ -850,6 +880,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, return err; } pcm->mmap_rw = 1; + pcm->mmap_shadow = 1; /* has own mmap method */ pcm->ops = &snd_pcm_multi_ops; pcm->fast_ops = &snd_pcm_multi_fast_ops; pcm->private_data = multi;
At Fri, 23 Nov 2007 14:41:43 +0100, I wrote:
Try the patch below. This should fix the problem. Now the multi plugin just shadows the slave buffers via mmap.
There was a minor bug in the last patch. The revised version is below.
Takashi
diff -r 3539f279ec38 src/pcm/pcm_multi.c --- a/src/pcm/pcm_multi.c Wed Nov 21 12:19:43 2007 +0100 +++ b/src/pcm/pcm_multi.c Fri Nov 23 15:34:16 2007 +0100 @@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_m return size; }
-static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_munmap(snd_pcm_t *pcm) { + free(pcm->mmap_channels); + free(pcm->running_areas); + pcm->mmap_channels = NULL; + pcm->running_areas = NULL; return 0; }
-static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_mmap(snd_pcm_t *pcm) { + snd_pcm_multi_t *multi = pcm->private_data; + unsigned int c; + + pcm->mmap_channels = calloc(pcm->channels, + sizeof(pcm->mmap_channels[0])); + pcm->running_areas = calloc(pcm->channels, + sizeof(pcm->running_areas[0])); + if (!pcm->mmap_channels || !pcm->running_areas) { + snd_pcm_multi_munmap(pcm); + return -ENOMEM; + } + + /* Copy the slave mmapped buffer data */ + for (c = 0; c < pcm->channels; c++) { + snd_pcm_multi_channel_t *chan = &multi->channels[c]; + snd_pcm_t *slave; + if (chan->slave_idx < 0) { + snd_pcm_multi_munmap(pcm); + return -ENXIO; + } + slave = multi->slaves[chan->slave_idx].pcm; + pcm->mmap_channels[c] = + slave->mmap_channels[chan->slave_channel]; + pcm->mmap_channels[c].channel = c; + pcm->running_areas[c] = + slave->running_areas[chan->slave_channel]; + } return 0; }
@@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, return err; } pcm->mmap_rw = 1; + pcm->mmap_shadow = 1; /* has own mmap method */ pcm->ops = &snd_pcm_multi_ops; pcm->fast_ops = &snd_pcm_multi_fast_ops; pcm->private_data = multi;
Thank you! Thank you! Thank you! Freaking awesome! You fixed two bugs in one! I can now use recent ALSA versions (and linux distros), AND I can combine the two cards at 24 bits resolution, at any buffer size, instead of 16 bits (because mmap was requiring me to use really small buffers).
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | I.O.U. | One case of <your favourite beverage> | Or one bottle of <something special> | | Expires: Never. ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OK, sure, I know I should run out and buy one of the newer 24 bit Creative cards so I don't have to convert, but hey, there's a lot of SBLive! cards out there... I need it for the hardware soundfonts only. Fluidsynth is good but a software solution.
* Anyways, initial tests are good. * I will test this weekend and let you know how it goes, * and after you can commit the patch for good.
A final 'note': The envy24control app's Master Clock - Signal/No Signal seems broken again. I know the cards are locked, but it still says 'No signal' when S/PDIF is selected. Some weirdness happening, seems to not actually lock sometimes, forcing me to switch back and forth between Int48000 and S/PDIF. But at least it mostly works.
I really appreciate you listening to me and taking the time to fix things. I know that given precise information, you always squash these bugs quickly. Tim.
On Friday 23 November 2007 09:35:35 am you wrote:
At Fri, 23 Nov 2007 14:41:43 +0100,
I wrote:
Try the patch below. This should fix the problem. Now the multi plugin just shadows the slave buffers via mmap.
There was a minor bug in the last patch. The revised version is below.
Takashi
diff -r 3539f279ec38 src/pcm/pcm_multi.c --- a/src/pcm/pcm_multi.c Wed Nov 21 12:19:43 2007 +0100 +++ b/src/pcm/pcm_multi.c Fri Nov 23 15:34:16 2007 +0100 @@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_m return size; }
-static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_munmap(snd_pcm_t *pcm) {
- free(pcm->mmap_channels);
- free(pcm->running_areas);
- pcm->mmap_channels = NULL;
- pcm->running_areas = NULL; return 0;
}
-static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_mmap(snd_pcm_t *pcm) {
- snd_pcm_multi_t *multi = pcm->private_data;
- unsigned int c;
- pcm->mmap_channels = calloc(pcm->channels,
sizeof(pcm->mmap_channels[0]));
- pcm->running_areas = calloc(pcm->channels,
sizeof(pcm->running_areas[0]));
- if (!pcm->mmap_channels || !pcm->running_areas) {
snd_pcm_multi_munmap(pcm);
return -ENOMEM;
- }
- /* Copy the slave mmapped buffer data */
- for (c = 0; c < pcm->channels; c++) {
snd_pcm_multi_channel_t *chan = &multi->channels[c];
snd_pcm_t *slave;
if (chan->slave_idx < 0) {
snd_pcm_multi_munmap(pcm);
return -ENXIO;
}
slave = multi->slaves[chan->slave_idx].pcm;
pcm->mmap_channels[c] =
slave->mmap_channels[chan->slave_channel];
pcm->mmap_channels[c].channel = c;
pcm->running_areas[c] =
slave->running_areas[chan->slave_channel];
- } return 0;
}
@@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, return err; } pcm->mmap_rw = 1;
- pcm->mmap_shadow = 1; /* has own mmap method */ pcm->ops = &snd_pcm_multi_ops; pcm->fast_ops = &snd_pcm_multi_fast_ops; pcm->private_data = multi;
At Fri, 23 Nov 2007 20:31:03 -0500, Tim wrote:
A final 'note': The envy24control app's Master Clock - Signal/No Signal seems broken again. I know the cards are locked, but it still says 'No signal' when S/PDIF is selected. Some weirdness happening, seems to not actually lock sometimes, forcing me to switch back and forth between Int48000 and S/PDIF. But at least it mostly works.
Hm, could you check whether it's a driver bug or a bug of envy24control? This control can be basically also get/set via alsactl. For example, just run "alsactl -f somefile store", edit the file, and "alsactl -f somefile restore". Also, you can set the value via amixer, too.
Takashi
On Saturday 24 November 2007 05:16:38 am you wrote:
At Fri, 23 Nov 2007 20:31:03 -0500, Tim wrote:
A final 'note': The envy24control app's Master Clock - Signal/No Signal seems broken again. I know the cards are locked, but it still says 'No signal' when S/PDIF is selected.
Hm, could you check whether it's a driver bug or a bug of envy24control? This control can be basically also get/set via alsactl. For example, just run "alsactl -f somefile store", edit the file, and "alsactl -f somefile restore". Also, you can set the value via amixer, too.
Pardon my previous enthusiasm. So many months debugging! I've straightened my tie and regained my composure now.
I tried creating a new asound.state with alsactl. The resulting asound.state was smaller, but did not fix the problem. I also tried manually turning the 'IEC958 CS8427 Error Status', and the other related controls, on/off with a mixer, no luck.
I know the two cards are locked because if I disconnect the S/PDIF cable, the ice1712 card goes silent or makes noises. This is normal behaviour. Also, I have run this setup for hours without an xrun or 'un-synced drifting'.
You know, the 'locked/no signal' indicator never has worked right. In ALSA 1.0.9b it always just says 'locked' (see below). In ALSA 1.0.15 it says 'locked' only when on a fixed internal rate.
** Here is some info below which I think will help.
It seems to me, looking at the 'IEC958 CS8427 Error Status' results below, that envy24control should perhaps be using it, instead of 'Word Clock Status', as a 'locked' indicator.
Thanks again. Tim.
---------------------------------------------------------- ALSA 1.0.15 + new distro: ---------------------------------------------------------- Master Clock says 'No signal'. Master Clock: S/PDIF. S/PDIF cable is connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=on numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=32 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=15
Master Clock says 'No signal'. Master Clock: S/PDIF. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=on numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=54 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=15
Master Clock says 'No signal'. Master Clock: Word Clock. S/PDIF cable is connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=on numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=on numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=32 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=15
Master Clock says 'No signal'. Master Clock: Word Clock. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=on numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=on numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=54 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=15
Master Clock says 'Locked'. Master Clock: 48000 Internal. S/PDIF cable is connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=off numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=0 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=67
Master Clock says 'Locked'. Master Clock: 48000 Internal. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=65,iface=MIXER,name='Word Clock Status' ; type=BOOLEAN,access=r-------,values=1 : values=off numid=64,iface=MIXER,name='Word Clock Sync' ; type=BOOLEAN,access=rw------,values=1 : values=off numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=0 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r-------,values=1,min=0,max=255,step=0 : values=67
---------------------------------------------------------- ALSA 1.0.9b + older distro: ---------------------------------------------------------- Master Clock says 'Locked' in all cases below... Note: I could not find a 'Word Clock Status' item. Perhaps that's why it never worked at all under ALSA 1.0.9b ?
Master Clock: S/PDIF. S/PDIF cable is connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=0 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=off
Master Clock: S/PDIF. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=63 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=off
Master Clock: Word Clock. S/PDIF cable is connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=0 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=on
Master Clock: Word Clock. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=23 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=on
Master Clock: 48000 Internal. S/PDIF cable is connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=31 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=off
Master Clock: 48000 Internal. S/PDIF cable is NOT connected. $ amixer -c1 contents ... numid=2,iface=PCM,name='IEC958 CS8427 Error Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=22 numid=1,iface=PCM,name='IEC958 CS8427 Input Status' ; type=INTEGER,access=r----,values=1,min=0,max=255,step=0 : values=67 numid=64,iface=PCM,name='Word Clock Sync' ; type=BOOLEAN,access=rw---,values=1 : values=off
At Sun, 25 Nov 2007 17:51:04 -0500, Tim wrote:
On Saturday 24 November 2007 05:16:38 am you wrote:
At Fri, 23 Nov 2007 20:31:03 -0500, Tim wrote:
A final 'note': The envy24control app's Master Clock - Signal/No Signal seems broken again. I know the cards are locked, but it still says 'No signal' when S/PDIF is selected.
Hm, could you check whether it's a driver bug or a bug of envy24control? This control can be basically also get/set via alsactl. For example, just run "alsactl -f somefile store", edit the file, and "alsactl -f somefile restore". Also, you can set the value via amixer, too.
Pardon my previous enthusiasm. So many months debugging! I've straightened my tie and regained my composure now.
I tried creating a new asound.state with alsactl. The resulting asound.state was smaller, but did not fix the problem. I also tried manually turning the 'IEC958 CS8427 Error Status', and the other related controls, on/off with a mixer, no luck.
I know the two cards are locked because if I disconnect the S/PDIF cable, the ice1712 card goes silent or makes noises. This is normal behaviour. Also, I have run this setup for hours without an xrun or 'un-synced drifting'.
You know, the 'locked/no signal' indicator never has worked right. In ALSA 1.0.9b it always just says 'locked' (see below).
It was a bug. It used a wrong GPIO with assumption that 1010LT is compatible with 1010 regarding that, and thus returned only a bogus value.
In ALSA 1.0.15 it says 'locked' only when on a fixed internal rate.
** Here is some info below which I think will help.
It seems to me, looking at the 'IEC958 CS8427 Error Status' results below, that envy24control should perhaps be using it, instead of 'Word Clock Status', as a 'locked' indicator.
Actually 'Word Clock Status' is determined from this register value. So far it checks whether its zero or not. But this seesm too strict. We'll need to check only the UNLOCK bit (bit 4) for sync status.
How about the patch below (to alsa-kernel)?
Takashi
diff -r 5e8cab953031 pci/ice1712/delta.c --- a/pci/ice1712/delta.c Mon Nov 26 09:00:56 2007 +0100 +++ b/pci/ice1712/delta.c Mon Nov 26 11:56:18 2007 +0100 @@ -405,7 +405,7 @@ static int snd_ice1712_delta1010lt_wordc if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); snd_i2c_readbytes(ice->cs8427, ®, 1); - ucontrol->value.integer.value[0] = (reg ? 1 : 0); + ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0; return 0; }
On Monday 26 November 2007 05:38:59 am you wrote:
It seems to me, looking at the 'IEC958 CS8427 Error Status' results below, that envy24control should perhaps be using it, instead of 'Word Clock Status', as a 'locked' indicator.
Actually 'Word Clock Status' is determined from this register value. So far it checks whether its zero or not. But this seesm too strict. We'll need to check only the UNLOCK bit (bit 4) for sync status.
How about the patch below (to alsa-kernel)?
diff -r 5e8cab953031 pci/ice1712/delta.c --- a/pci/ice1712/delta.c Mon Nov 26 09:00:56 2007 +0100 +++ b/pci/ice1712/delta.c Mon Nov 26 11:56:18 2007 +0100 @@ -405,7 +405,7 @@ static int snd_ice1712_delta1010lt_wordc if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); snd_i2c_readbytes(ice->cs8427, ®, 1);
- ucontrol->value.integer.value[0] = (reg ? 1 : 0);
- ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0; return 0;
}
Ah, there we go! Tested OK connecting/disconnecting S/PDIF cable - says 'locked' then 'no signal'. Thanks again, Takashi. Tim.
At Mon, 26 Nov 2007 17:46:59 -0500, Tim wrote:
On Monday 26 November 2007 05:38:59 am you wrote:
It seems to me, looking at the 'IEC958 CS8427 Error Status' results below, that envy24control should perhaps be using it, instead of 'Word Clock Status', as a 'locked' indicator.
Actually 'Word Clock Status' is determined from this register value. So far it checks whether its zero or not. But this seesm too strict. We'll need to check only the UNLOCK bit (bit 4) for sync status.
How about the patch below (to alsa-kernel)?
diff -r 5e8cab953031 pci/ice1712/delta.c --- a/pci/ice1712/delta.c Mon Nov 26 09:00:56 2007 +0100 +++ b/pci/ice1712/delta.c Mon Nov 26 11:56:18 2007 +0100 @@ -405,7 +405,7 @@ static int snd_ice1712_delta1010lt_wordc if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); snd_i2c_readbytes(ice->cs8427, ®, 1);
- ucontrol->value.integer.value[0] = (reg ? 1 : 0);
- ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0; return 0;
}
Ah, there we go! Tested OK connecting/disconnecting S/PDIF cable - says 'locked' then 'no signal'. Thanks again, Takashi. Tim.
OK, the patch is now on ALSA HG tree. Thanks for confirmation.
Takashi
Takashi, after a week of testing your multi-plughw patch I'm satisfied it works fine.
One odd thing is that when I start Jack, sometimes I immediately get a series of ever increasing xruns, sometimes hundreds of them with each display update of QJackctl. Simply restarting QJackctl cures it and it runs for many hours without trouble. I am not convinced it has anything to do with your patch, maybe just my new .asoundrc and new altered setup.
Also, I never have tested any multi playback configuration, just record. When I get a chance I will test it.
Thanks. Tim.
On Sat, Dec 01, 2007 at 06:33:35PM -0500, Tim wrote:
Takashi, after a week of testing your multi-plughw patch I'm satisfied it works fine.
One odd thing is that when I start Jack, sometimes I immediately get a series of ever increasing xruns, sometimes hundreds of them with each display update of QJackctl. Simply restarting QJackctl cures it and it runs for many hours without trouble. I am not convinced it has anything to do with your patch, maybe just my new .asoundrc and new altered setup.
It's a known problem with pcm_multi and qjackctl. qjackctl reports xruns that aren't actually happening when using pcm_multi. Some other apps like jamin do this too. Don't worry about it unless you hear dropouts (in which case the alsa driver will report a real xrun).
John
participants (3)
-
John Rigg
-
Takashi Iwai
-
Tim