Re: [alsa-devel] [LAD] announcing envy24control, mudita (*) edition.

On Sat, Jul 31, 2010 at 12:06 PM, Tim E. Real termtech@rogers.com wrote:
Niels do you have a new release or repo I can work with rather than the original release, which may be too outdated to patch against by now?
http://nielsmayer.com/envy24control/mudita24-1.0.1.tar.gz (source directory, follow README).
Please give it a try and report on how this "release candidate" works for you.
This 1.0.1 release should fix most of the problems/gripes/bugs/errors reported on linux-audio-devel. New command-line options "-g 1" allow multi-channel folk to get rid of the stereo grouping; those annoyed by the "detent" on the sliders or the extra space taken up by the markings, use "-n" to turn off this feature..
The main thing I haven't been able to resolve is Fons' complaint regarding the DAC Volumes in "Analog Volume" panel not all being the same height, due to a -10/+4 radiobox that only appears in first DAC column for the Terratec EWS88MT; this radiobox causes the associated slider to be shorter than the other channels. Shouldn't this radiobox appear in all DAC columns?. Is this a regression in "mudita24" or a feature request for standard "envy24control"? I didn't change this aspect of the code, as far as I can tell.
-- Niels. http://nielsmayer.com

On Sat, Jul 31, 2010 at 11:24:31PM -0700, Niels Mayer wrote:
The main thing I haven't been able to resolve is Fons' complaint regarding the DAC Volumes in "Analog Volume" panel not all being the same height, due to a -10/+4 radiobox that only appears in first DAC column for the Terratec EWS88MT; this radiobox causes the associated slider to be shorter than the other channels. Shouldn't this radiobox appear in all DAC columns?.
No, it's one switch for all channels.
Is this a regression in "mudita24" or a feature request for standard "envy24control"? I didn't change this aspect of the code, as far as I can tell.
The original has the same problem. Don't waste your time with it unless someone else thinks it matters. As said I have fixed levels on all channels, I don't ever use the mixer (as the card is connected to a real mixer anyway), and everything is initialised by an alsactl restore on booting. So in practice I never use envy24control.
Apart from that, I just don't understand why I toolkit like GTK apparently makes it difficult to get such a simple thing right. Same for the faders.
Ciao,

On Sun, Aug 1, 2010 at 3:54 PM, fons@kokkinizita.net wrote:
Is this a regression in "mudita24" or a feature request for standard "envy24control"? I didn't change this aspect of the code, as far as I can tell.
The original has the same problem.
Well that's "good" to hear, in the sense that I didn't cause a regression for which there was no way to predict how i could have caused, it, from the changes made. (Another bug I know of https://bugzilla.redhat.com/show_bug.cgi?id=602900 )
However your complaint forced me to look at the code enough that it would be a pretty easy fix. I'd special case for "dac_senses==1" (apparently an unfortunate shorthand for dac sensitivity adjust), and "adc_senses==1". For that condition, I'd lay out the radiobutton first as the leftmost column, and afterwards all the sliders for the DACs, and then if same for ADC's, again same way.
If there's multiple adc_senses and dac_senses (i don't know if there are ice1712 card models that do this, but i'd hope that is the case, as one normally has a mixture of consumer and pro devices to hookup) then the original code putting a dac/adc sensitivity radiobutton under each associated slider would kick-in.
Since I don't have the card to test this aspect, hopefully someone from ALSA will comment on why things are the way they are. Because it might also be just as well to leave the code as-is and not cause regressions on cards we might not be able to test on (or even find: http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=230506172001 ).
-- Niels http://nielsmayer.com

FYI, I added the following since http://nielsmayer.com/envy24control/mudita24-1.0.1.tar.gz ... shall I release a 1.0.2 with the following additions (?):
* fixed --card and --device to allow valid ALSA names and numbers ( https://bugzilla.redhat.com/show_bug.cgi?id=602900 ). * Add display of "Delta IEC958 Input Status" under "Hardware Settings." * Updated and corrected manual page and README
Before I release, I'd like to know what happens on cards that don't have this feature, or if it's universally supported, but badly named. Can those with a Terratec or other card test the following command and let me know the results of command "amixer -c M66 cget iface=MIXER,name='Delta IEC958 Input Status'" e.g.:
amixer -c M66 cget iface=MIXER,name='Delta IEC958 Input Status' numid=50,iface=MIXER,name='Delta IEC958 Input Status' ; type=BOOLEAN,access=r-------,values=1 : values=on
.................................................................................................
Also, in case anybody ever wondered what this one, under "Analog Volume" is for: "Volume Control Rate Register" I added it to the README:
.........................
Notes on the Envy24's hardware Digital Mixer and hardware Metering, by Niels Mayer ( http://nielsmayer.com ): --------------------
The "Monitor Inputs" and "Monitor PCMs" tabs contain multiple scale widgets grouped into L/R pairs and an associated peak-level meter. Each scale widget represents the 24 bit attenuation value of each input to the ice1712-based soundcard's digital mixer. This mixer is typically used for zero-latency monitoring of "live" inputs, alongside backing sounds and effects coming from the eight channels of PCM feeding the digital mixer. When many inputs are "hot" simultaneously these scale-widgets attenuate the inputs going into the digital mixer to prevent the output from clipping. For details see http://nielsmayer.com/npm/envy24mixer-architecture.png
(from http://alsa.cybermirror.org/manuals/icensemble/envy24.pdf )
This is what the above manual says about the Envy24's digital mixer:
4.5.5 Multi-Track Digital Monitoring
The Envy24 integrates a 36-bit resolution digital hardware mixer. The width of the data path is strictly to ensure that during processing of all the channels, under any condition, no resolution is lost. The dynamic range of the end user system will be limited by the range of the physical output devices used. In order to maintain identical gain to the input stream (i.e. 0dB), the resulting 24-bit is not msb-aligned to the 36-bit. The overflow bits correspond to the analog distortion due to saturation. The user would need to reduce the overall attenuation of the inputs to avoid clipping. Insertion of the digital mixer adds only a single sample cycle delay with respect to the original data. This extremely low latency all digital mixer provides monitoring functionality and can replace a traditional external analog input mixer. There are 20 independent audio data streams to mix and control the volume.
Adjustment of responsivity vs. "zipper noise" from the 1.5dB steps at the top-range of the digital mixer attenuators is achieved by the following control under "Hardware Settings":
MT3B: Volume Control Rate Register ... Volume update rate control (sampling rate, PSYNC) This register allows gradual change of the digital mixer volume setting. The value in MT3B specifies the number of samples to elapse (in hex) between each 1.5dB increment/decrement in volume mixer. This gradual volume update continues until the setting programmed into MT38 is reached. The appropriate value to program may vary, but 00 or 01h are good choices for most cases.
The peak metering data is displayed as 0 to -48dBFS in envy24control's meters. This data is derived from the envy24's hardware peak metering:
Peak data derived from the absolute value of 9 msb. 00h min - FFh max volume. Reading the register resets the meter to 00h.
This resolution of the hardware metering is descibed by Fons Adriaensen in a mailing list discussion:
http://lists.linuxaudio.org/pipermail/linux-audio-dev/2010-August/029009.htm...
[...] You have 128 steps between 0 and -6dB... And even at -24dB the next step is 1.3dB lower. Below that it gets worse radipdly. For a meter that is just supposed to keep a check on peak levels it's OK.
Note that hardware metering data is also available from the command-line:
amixer -c M66 cget iface=PCM,name='Multi Track Peak',numid=45 numid=45,iface=PCM,name='Multi Track Peak' ; type=INTEGER,access=r-------,values=22,min=0,max=255,step=0 : values=63,62,51,49,56,60,63,62,59,54,0,0,0,0,0,0,0,0,0,0,113,112
....................................................................
Niels http://nielsmayer.com

2010/8/4 Niels Mayer nielsmayer@gmail.com
FYI, I added the following since http://nielsmayer.com/envy24control/mudita24-1.0.1.tar.gz ... shall I release a 1.0.2 with the following additions (?):
- fixed --card and --device to allow valid ALSA names and numbers ( https://bugzilla.redhat.com/show_bug.cgi?id=602900 ).
./envy24control -Ddefault
card_number = atoi(strchr(name, ':') + sizeof(char));
This bug seem still occur when name does not contain ":" since ctl device is "hw:n" where n is card number
http://git.alsa-project.org/?p=alsa-tools.git;a=blobdiff;f=envy24control/env...

On Tue, Aug 3, 2010 at 10:38 PM, Raymond Yau superquad.vortex2@gmail.com wrote:
2010/8/4 Niels Mayer nielsmayer@gmail.com
* fixed --card and --device to allow valid ALSA names and numbers ( https://bugzilla.redhat.com/show_bug.cgi?id=602900 ).
./envy24control -Ddefault
card_number = atoi(strchr(name, ':') + sizeof(char));
This bug seem still occur when name does not contain ":" since ctl device is "hw:n" where n is card number
I used similar code to what's in alsamixer to perform the same functions as the old broken code. Now the code behaves as follows:
gnulem-238-~> envy24control -Dhw:default envy24control: invalid ALSA audio device, invalid index or name for card: hw:default gnulem-239-~> envy24control -Dhw:M66 using --- input_channels: 4 --- output_channels: 4 --- pcm_output_channels: 8 --- spdif in/out channels: 2 gnulem-240-~> envy24control -Dhw:M66.0 envy24control: invalid ALSA audio device, invalid index or name for card: hw:M66.0 gnulem-241-~> envy24control -Dhw:M66,0 envy24control: invalid ALSA audio device, invalid index or name for card: hw:M66,0 gnulem-242-~> envy24control -DM66 envy24control: ALSA audio device syntax expects ':' character: M66
Current code:
while ((c = getopt_long(argc, argv, "D:c:f:i:m:Mo:p:s:w:vt:ng:", long_options, NULL)) != -1) { switch (c) { case 'D': name = optarg; if (!index(name, ':')) { fprintf(stderr, "envy24control: ALSA audio device syntax expects ':' character: %s\n", optarg); exit(1); } card_number = snd_card_get_index(strchr(name, ':') + sizeof(char)); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */ fprintf(stderr, "envy24control: invalid ALSA audio device, invalid index or name for card: %s\n", optarg); exit(1); } break; case 'c': card_number = snd_card_get_index(optarg); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */ fprintf(stderr, "envy24control: invalid ALSA index or name for audio card: %s\n", optarg); exit(1); } sprintf(tmpname, "hw:%d", card_number); name = tmpname; break;
-- Niels http://nielsmayer.com

2010/8/4 Niels Mayer nielsmayer@gmail.com
On Tue, Aug 3, 2010 at 10:38 PM, Raymond Yau superquad.vortex2@gmail.com wrote:
2010/8/4 Niels Mayer nielsmayer@gmail.com
- fixed --card and --device to allow valid ALSA names and numbers ( https://bugzilla.redhat.com/show_bug.cgi?id=602900 ).
./envy24control -Ddefault
card_number = atoi(strchr(name, ':') + sizeof(char));
This bug seem still occur when name does not contain ":" since ctl device
is
"hw:n" where n is card number
I used similar code to what's in alsamixer to perform the same functions as the old broken code. Now the code behaves as follows:
gnulem-238-~> envy24control -Dhw:default envy24control: invalid ALSA audio device, invalid index or name for card: hw:default gnulem-239-~> envy24control -Dhw:M66 using --- input_channels: 4 --- output_channels: 4 --- pcm_output_channels: 8 --- spdif in/out channels: 2 gnulem-240-~> envy24control -Dhw:M66.0 envy24control: invalid ALSA audio device, invalid index or name for card: hw:M66.0 gnulem-241-~> envy24control -Dhw:M66,0 envy24control: invalid ALSA audio device, invalid index or name for card: hw:M66,0 gnulem-242-~> envy24control -DM66 envy24control: ALSA audio device syntax expects ':' character: M66
The "-D" option seem to be used similar to "amixer -Dabc"
ctl.abc {
type hw card 2 }

On Wed, Aug 4, 2010 at 1:20 AM, Raymond Yau superquad.vortex2@gmail.com wrote:
The "-D" option seem to be used similar to "amixer -Dabc" ctl.abc { type hw , card 2 }
Raymond --
Thanks for the clarification regarding the use of the -D argument for alsa control devices. I've updated my code to handle things in the same way that amixer does. The diffs for this change are at the end of this message, and attached. ALSA names for examples/tests below from http://nielsmayer.com/npm/dot-asoundrc.txt ....
......................................... gnulem-277-~> /usr/bin/envy24control -D66 ##behavior on current head and latest stable release Segmentation fault (core dumped) gnulem-278-~> envy24control -D66 ##behavior using this patch ... using --- input_channels: 4 gnulem-279-~> envy24control -D666 ALSA lib control.c:902:(snd_ctl_open_noupdate) Invalid CTL 666 envy24control: cannot open mixer: No such file or directory - '666' gnulem-280-~> envy24control -Dhw:66 envy24control: invalid ALSA audio device, invalid index or name for card: hw:66 gnulem-281-~> envy24control -Dhw:M66 using --- input_channels: 4 gnulem-282-~> envy24control -Dmulti invalid card type (driver is HDA-Intel) gnulem-283-~> envy24control -Ddefault invalid card type (driver is USB-Audio) gnulem-284-~> envy24control -c default envy24control: invalid ALSA index or name for audio card: default gnulem-285-~> envy24control -c SB invalid card type (driver is HDA-Intel) gnulem-286-~> envy24control -c multi envy24control: invalid ALSA index or name for audio card: multi gnulem-287-~> envy24control -c M66 using --- input_channels: 4 gnulem-299-~> amixer -Dhw:/dev/snd/controlC2 >! /tmp/foo gnulem-301-~> amixer -D/dev/snd/controlC2 > ! /tmp/foo ALSA lib control.c:902:(snd_ctl_open_noupdate) Invalid CTL /dev/snd/controlC2 amixer: Mixer attach /dev/snd/controlC2 error: No such file or directory gnulem-290-~> envy24control -D/dev/snd/controlC2 ALSA lib control.c:902:(snd_ctl_open_noupdate) Invalid CTL /dev/snd/controlC2 envy24control: cannot open mixer: No such file or directory - '/dev/snd/controlC2'
.........................................
diff --git a/envy24control/envy24control.c b/envy24control/envy24control.c index 0b2749e..e5d89d0 100644 --- a/envy24control/envy24control.c +++ b/envy24control/envy24control.c @@ -2084,3 +2166,3 @@ int main(int argc, char **argv) view_spdif_playback = 0; profiles_file_name = DEFAULT_PROFILERC; default_profile = NULL; while ((c = getopt_long(argc, argv, "D:c:f:i:m:Mo:p:s:w:vt:", long_options, NULL)) != -1) { switch (c) { case 'D': - name = optarg; - card_number = atoi(strchr(name, ':') + sizeof(char)); - if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", card_number); - exit(1); + /* NPM: old code assumed ':' present, e.g. "-Dhw:66", + * (w/ .asoundrc "ctl.66 {type hw, card M66}") and would + * coredump if given "-D66". Prevent the coredump and even + * handle latter case even if keying off ':' is not a + * good way to do this. Note that for snd_card_get_index() + * "The accepted format is an integer value in ASCII representation or the card + * identifier (the id parameter for sound-card drivers). The control device + * name like /dev/snd/controlC0 is accepted, too." */ + if (!index(optarg, ':')) { + /* NPM: unlike old envy24control code, but behaving like amixer et al, + "-D66" is valid. Handle it. */ + snd_mixer_t *mixer; + struct snd_mixer_selem_regopt selem_regopt = { + .ver = 1, + .abstract = SND_MIXER_SABSTRACT_NONE, + .device = optarg, + }; + if ((err = snd_mixer_open(&mixer, 0)) < 0) { + fprintf(stderr, "envy24control: cannot open mixer: %s - '%s'\n", snd_strerror(err), optarg); + exit(1); + } + if ((err = snd_mixer_selem_register(mixer, &selem_regopt, NULL)) < 0) { + fprintf(stderr, "envy24control: cannot open mixer: %s - '%s'\n", snd_strerror(err), optarg); + exit(1); + } + name = optarg; /* NPM: now that device name validated, e.g. pass "-D66" unaltered to snd_ctl_open()... */ + } + else { + /* NPM: handle e.g. optarg == "hw:M66" */ + card_number = snd_card_get_index(strchr(optarg, ':') + sizeof(char)); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ + if (card_number < 0) { + fprintf(stderr, "envy24control: invalid ALSA audio device, invalid index or name for card: %s\n", optarg); + exit(1); + } + name = optarg; /* e.g. optarg == "hw:M66" passed to snd_ctl_open() below */ } break; case 'c': - i = atoi(optarg); - if (i < 0 || i >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", i); + card_number = snd_card_get_index(optarg); /* NPM: use correct ALSA-specific call to fix https://bugzilla.redhat.com/show_bug.cgi?id=602900 */ + if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */ + fprintf(stderr, "envy24control: invalid ALSA index or name for audio card: %s\n", optarg); exit(1); } - card_number = i; - sprintf(tmpname, "hw:%d", i); + sprintf(tmpname, "hw:%d", card_number); /* e.g. "hw:M66" for arg "-cM66" passed to snd_ctl_open() below */ name = tmpname; break; case 'f':
.........................................
--Niels http://nielsmayer.com

Actually, there's a much simpler version of this patch, since the previous code provided some extra validation and pretty error messages, but no information that couldn't be provided by snd_ctl_open(), e.g.: .... gnulem-336-~> envy24control -Dfoo ALSA lib control.c:902:(snd_ctl_open_noupdate) Invalid CTL foo snd_ctl_open: No such file or directory ....
diff --git a/envy24control/envy24control.c b/envy24control/envy24control.c index 0b2749e..3798ba3 100644 --- a/envy24control/envy24control.c +++ b/envy24control/envy24control.c @@ -2084,24 +2166,50 @@ int main(int argc, char **argv) view_spdif_playback = 0; profiles_file_name = DEFAULT_PROFILERC; default_profile = NULL; while ((c = getopt_long(argc, argv, "D:c:f:i:m:Mo:p:s:w:vt:", long_options, NULL)) != -1) { switch (c) { case 'D': - name = optarg; - card_number = atoi(strchr(name, ':') + sizeof(char)); - if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", card_number); - exit(1); - } + /* + * NPM: use ALSA code to fix/validate + * https://bugzilla.redhat.com/show_bug.cgi?id=602900 + * The old code assumed ':' present, e.g. "-Dhw:66", (w/ + * .asoundrc "ctl.66 {type hw, card M66}") and would + * coredump if given "-D66". Here, by not worrying about + * "hw:" and passing "optarg" as-is via 'name' to + * snd_ctl_open() below, resolves the issue, giving similar + * behavior as 'amixer'. However, letting snd_ctl_open() + * validate gives less helpful error messages on + * failure: "envy24control -Dhw:foo" + * ==> "snd_ctl_open: No such device" + * So validate the arg as ALSA CTL, providing + * a more specific error message and fail first if not valid. + */ + name = optarg; /* NPM: e.g. pass "-D66" unaltered to snd_ctl_open() and let it validate valid ALSA CTL name */ + if (index(optarg, ':')) { /* NPM: handle e.g. optarg == "hw:M66" */ + card_number = snd_card_get_index(strchr(optarg, ':') + sizeof(char)); + if (card_number < 0) { + fprintf(stderr, "envy24control: invalid ALSA audio device, invalid index or name for card: %s\n", optarg); + exit(1); + } + } break; case 'c': - i = atoi(optarg); - if (i < 0 || i >= MAX_CARD_NUMBERS) { - fprintf(stderr, "envy24control: invalid card number %d\n", i); + /* + NPM: use snd_card_get_index() to fix/validate + https://bugzilla.redhat.com/show_bug.cgi?id=602900 + * NPM: nb :"The accepted format is + * an integer value in ASCII representation or the card + * identifier (the id parameter for sound-card + * drivers). The control device name like + * /dev/snd/controlC0 is accepted, too." + */ + card_number = snd_card_get_index(optarg); + if (card_number < 0) { /* NPM: code orig from alsa-utils/alsamixer/cli.c */ + fprintf(stderr, "envy24control: invalid ALSA index or name for audio card: %s\n", optarg); exit(1); } - card_number = i; - sprintf(tmpname, "hw:%d", i); + sprintf(tmpname, "hw:%d", card_number); /* e.g. "hw:M66" for arg "-cM66" passed to snd_ctl_open() below */ name = tmpname; break; case 'f':
...................................
Niels http://nielsmayer.com
participants (3)
-
fons@kokkinizita.net
-
Niels Mayer
-
Raymond Yau