]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Changes for record volume...
authorJaroslav Kysela <perex@perex.cz>
Mon, 15 Feb 1999 15:42:34 +0000 (15:42 +0000)
committerJaroslav Kysela <perex@perex.cz>
Mon, 15 Feb 1999 15:42:34 +0000 (15:42 +0000)
alsactl/alsactl.h
alsactl/alsactl_lexer.l
alsactl/alsactl_parser.y
alsactl/setup.c
alsamixer/alsamixer.1
alsamixer/alsamixer.c

index 6ed0b00fa239284484b47ea5995058aa8def795c..e17f9ef6f7fe89edcc188acb055705ade0242b85 100644 (file)
@@ -47,6 +47,7 @@ struct mixer_channel {
        int change;
        snd_mixer_channel_info_t i;
        snd_mixer_channel_t c;
+       snd_mixer_channel_t cr;
        struct mixer_channel *next;
 };
 
index 8b39d3b86e1298958ab2b5cbd13573741f6375c3..a0e37128aaad00a0ee2f32e2db9f412da7202698 100644 (file)
@@ -38,6 +38,7 @@ int linecount;
 
 "{"|"}"                        return yytext[0];
 "("|")"                        return yytext[0];
+"["|"]"                        return yytext[0];
 ")"[ \t]*"{"           return L_DOUBLE1;
 ","                    return yytext[0];
 
@@ -108,9 +109,9 @@ true|on|yes         return L_TRUE;
 \'[^\']*\'              { yytext[ strlen( yytext ) - 1 ] = 0;
                           yylval.s_value = strdup( &yytext[ 1 ] );
                           return L_STRING; }
-[a-z0-9/\~@-_\+=:\.]+  { yylval.s_value = strdup( yytext );
+[a-z0-9/\~@-Za-z_\+=:\.]+  { yylval.s_value = strdup( yytext );
                           return L_STRING; }
-$[a-z0-9/\~@-_\+=:\.]+ { yylval.s_value = strdup( getenv( &yytext[ 1 ] ) );
+$[a-z0-9/\~@-Za-z_\+=:\.]+ { yylval.s_value = strdup( getenv( &yytext[ 1 ] ) );
                           return L_STRING; }
 
        /* comments & whitespaces */
index a0bd765e0516d7160d0b83c6d3bd2223f520ccd2..5948eed1db397f3e83d575f5b506da5d458077cb 100644 (file)
@@ -43,6 +43,7 @@ static void select_rawmidi(char *name);
 
 static void select_mixer_channel(char *name);
 static void set_mixer_channel(int left, int right);
+static void set_mixer_channel_record(int left, int right);
 static void set_mixer_channel_flags(unsigned int mask, unsigned int flags);
 static void set_mixer_channel_end(void);
 
@@ -162,6 +163,7 @@ xmchls      : xmchl
        ;
 
 xmchl  : L_INTEGER             { set_mixer_channel( $1, -1 ); }
+       | '[' L_INTEGER ']'     { set_mixer_channel_record( $2, -1 ); }
        | L_MUTE                { set_mixer_channel_flags( SND_MIXER_FLG_MUTE_LEFT, SND_MIXER_FLG_MUTE_LEFT ); }
        | L_RECORD              { set_mixer_channel_flags( SND_MIXER_FLG_RECORD_LEFT, SND_MIXER_FLG_RECORD_LEFT ); }
        | L_SWOUT               { set_mixer_channel_flags( SND_MIXER_FLG_LTOR_OUT, SND_MIXER_FLG_LTOR_OUT ); }
@@ -174,6 +176,7 @@ xmchrs      : xmchr
        ;
 
 xmchr  : L_INTEGER             { set_mixer_channel( -1, $1 ); }
+       | '[' L_INTEGER ']'     { set_mixer_channel_record( -1, $2 ); }
        | L_MUTE                { set_mixer_channel_flags( SND_MIXER_FLG_MUTE_RIGHT, SND_MIXER_FLG_MUTE_RIGHT ); }
        | L_RECORD              { set_mixer_channel_flags( SND_MIXER_FLG_RECORD_RIGHT, SND_MIXER_FLG_RECORD_RIGHT ); }
        | L_SWOUT               { set_mixer_channel_flags( SND_MIXER_FLG_RTOL_OUT, SND_MIXER_FLG_RTOL_OUT ); }
@@ -186,6 +189,7 @@ xmchs       : xmch
        ;
 
 xmch   : L_INTEGER             { set_mixer_channel( $1, $1 ); }
+       | '[' L_INTEGER ']'     { set_mixer_channel_record( $2, $2 ); }
        | L_MUTE                { set_mixer_channel_flags( SND_MIXER_FLG_MUTE, SND_MIXER_FLG_MUTE ); }
        | L_RECORD              { set_mixer_channel_flags( SND_MIXER_FLG_RECORD, SND_MIXER_FLG_RECORD ); }
        | error                 { yyerror( "unknown keyword in mono channel section..." ); }
@@ -417,6 +421,24 @@ static void set_mixer_channel(int left, int right)
        }
 }
 
+static void set_mixer_channel_record(int left, int right)
+{
+       if (left >= 0) {
+               if (Xmixerchannel->i.min > left || Xmixerchannel->i.max < left)
+                       yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
+               if (Xmixerchannel->cr.left != left)
+                       Xmixerchannel->change = 1;
+               Xmixerchannel->cr.left = left;
+       }
+       if (right >= 0) {
+               if (Xmixerchannel->i.min > right || Xmixerchannel->i.max < right)
+                       yyerror("Value out of range (%i-%i)...", Xmixerchannel->i.min, Xmixerchannel->i.max);
+               if (Xmixerchannel->cr.right != right)
+                       Xmixerchannel->change = 1;
+               Xmixerchannel->cr.right = right;
+       }
+}
+
 static void set_mixer_channel_flags(unsigned int mask, unsigned int flags)
 {
        Xmixerchannelflags &= ~mask;
index 0218d0cee7462a5caa084a32ad6ec5923cd63b6d..3742017d93acd93d66cbd999532c59ad63249ea6 100644 (file)
@@ -360,6 +360,12 @@ int soundcard_setup_collect(int cardno)
                                error("MIXER channel read error (%s) - skipping", snd_strerror(err));
                                break;
                        }
+                       if ((mixerchannel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
+                           (err = snd_mixer_channel_record_read(mhandle, idx, &mixerchannel->cr)) < 0) {
+                               free(mixerchannel);
+                               error("MIXER channel record read error (%s) - skipping", snd_strerror(err));
+                               break;
+                       }
                        if (!mixerchannelprev) {
                                mixer->channels = mixerchannel;
                        } else {
@@ -645,7 +651,7 @@ static void soundcard_setup_write_switch(FILE * out, int interface, const unsign
 }
 
 
-static void soundcard_setup_write_mixer_channel(FILE * out, snd_mixer_channel_info_t * info, snd_mixer_channel_t * channel)
+static void soundcard_setup_write_mixer_channel(FILE * out, snd_mixer_channel_info_t * info, snd_mixer_channel_t * channel, snd_mixer_channel_t * record_channel)
 {
        fprintf(out, "    ; Capabilities:%s%s%s%s%s%s%s%s%s%s%s%s%s.\n",
                info->caps & SND_MIXER_CINFO_CAP_RECORD ?       " record" : "",
@@ -660,27 +666,39 @@ static void soundcard_setup_write_mixer_channel(FILE * out, snd_mixer_channel_in
                info->caps & SND_MIXER_CINFO_CAP_SWITCH_OUT ?   " switch-out" : "",
                info->caps & SND_MIXER_CINFO_CAP_LTOR_IN ?      " ltor-in" : "",
                info->caps & SND_MIXER_CINFO_CAP_RTOL_IN ?      " rtol-in" : "",
-               info->caps & SND_MIXER_CINFO_CAP_RECORDBYMUTE ? " record-by-mute" : "");
+               info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME ? " record-volume" : "");
        fprintf(out, "    ; Accepted channel range is from %i to %i.\n", info->min, info->max);
        fprintf(out, "    channel( \"%s\", ", info->name);
        if (info->caps & SND_MIXER_CINFO_CAP_STEREO) {
-               fprintf(out, "stereo( %i%s%s%s%s, %i%s%s%s%s )",
+               char bufl[16] = "";
+               char bufr[16] = "";
+               if (info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) {
+                       sprintf(bufl, " [%i]", record_channel->left);
+                       sprintf(bufr, " [%i]", record_channel->right);
+               }
+               fprintf(out, "stereo( %i%s%s%s%s%s, %i%s%s%s%s%s )",
                        channel->left,
-                channel->flags & SND_MIXER_FLG_MUTE_LEFT ? " mute" : "",
+                       channel->flags & SND_MIXER_FLG_MUTE_LEFT ? " mute" : "",
                        channel->flags & SND_MIXER_FLG_RECORD_LEFT ? " record" : "",
-                channel->flags & SND_MIXER_FLG_LTOR_OUT ? " swout" : "",
-                  channel->flags & SND_MIXER_FLG_LTOR_IN ? " swin" : "",
+                       bufl,
+                       channel->flags & SND_MIXER_FLG_LTOR_OUT ? " swout" : "",
+                       channel->flags & SND_MIXER_FLG_LTOR_IN ? " swin" : "",
                        channel->right,
-               channel->flags & SND_MIXER_FLG_MUTE_RIGHT ? " mute" : "",
+                       channel->flags & SND_MIXER_FLG_MUTE_RIGHT ? " mute" : "",
                        channel->flags & SND_MIXER_FLG_RECORD_RIGHT ? " record" : "",
-                channel->flags & SND_MIXER_FLG_RTOL_OUT ? " swout" : "",
-                   channel->flags & SND_MIXER_FLG_RTOL_IN ? " swin" : ""
+                       bufr,
+                       channel->flags & SND_MIXER_FLG_RTOL_OUT ? " swout" : "",
+                       channel->flags & SND_MIXER_FLG_RTOL_IN ? " swin" : ""
                    );
        } else {
-               fprintf(out, "mono( %i%s%s )",
+               char buf[16] = "";
+               if (info->caps & SND_MIXER_CINFO_CAP_RECORDVOLUME)
+                       sprintf(buf, " [%i]", (record_channel->left+record_channel->right) /2);
+               fprintf(out, "mono( %i%s%s%s )",
                        (channel->left + channel->right) / 2,
-                     channel->flags & SND_MIXER_FLG_MUTE ? " mute" : "",
-                  channel->flags & SND_MIXER_FLG_RECORD ? " record" : ""
+                       channel->flags & SND_MIXER_FLG_MUTE ? " mute" : "",
+                       channel->flags & SND_MIXER_FLG_RECORD ? " record" : "",
+                       buf
                    );
        }
        fprintf(out, " )\n");
@@ -717,7 +735,7 @@ int soundcard_setup_write(const char *cfgfile)
                for (mixer = first->mixers; mixer; mixer = mixer->next) {
                        fprintf(out, "  mixer( \"%s\" ) {\n", mixer->info.name);
                        for (mixerchannel = mixer->channels; mixerchannel; mixerchannel = mixerchannel->next)
-                               soundcard_setup_write_mixer_channel(out, &mixerchannel->i, &mixerchannel->c);
+                               soundcard_setup_write_mixer_channel(out, &mixerchannel->i, &mixerchannel->c, &mixerchannel->cr);
                        for (mixersw = mixer->switches; mixersw; mixersw = mixersw->next)
                                soundcard_setup_write_switch(out, SND_INTERFACE_MIXER, mixersw->s.name, mixersw->s.type, mixersw->s.low, mixersw->s.high, (void *) (&mixersw->s.value));
                        fprintf(out, "  }\n");
@@ -825,6 +843,9 @@ int soundcard_setup_process(int cardno)
                                        if (!soundcard_open_mix(&mixhandle, soundcard, mixer)) {
                                                if ((err = snd_mixer_channel_write(mixhandle, channel->no, &channel->c)) < 0)
                                                        error("Mixer channel '%s' write error: %s", channel->i.name, snd_strerror(err));
+                                               if ((channel->i.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME) &&
+                                                   (err = snd_mixer_channel_record_write(mixhandle, channel->no, &channel->cr)) < 0)
+                                                       error("Mixer channel '%s' record write error: %s", channel->i.name, snd_strerror(err));
                                        }
                        if (mixhandle) {
                                snd_mixer_close(mixhandle);
index 6c4f9aa3a85f572863015c3e8aeaaf2eba80557b..4d2a6a5b204360e4a3e239810bfc886b49021074 100644 (file)
@@ -67,6 +67,8 @@ mute left and right independently by using \fI,\fP and \fI.\fP respectively.
 removed from the sources used for recording. This only works for valid
 input channels, of course.
 
+\fIR\fP toggle display of playback or record mixer.
+
 \fIL\fP re-draws the screen.
 
 \fITAB\fP toggles the mode for volume display. See description for the
index 8b7e6f502c43d06748e388e4298ca904eda11d99..32186cad75e0e2e5c4f36b157122468294204c31 100644 (file)
@@ -97,6 +97,8 @@ static int mixer_first_vis_channel = 0;
 static int mixer_focus_channel = 0;
 static int mixer_exact = 0;
 
+static int mixer_record_volumes = 0;
+
 static int mixer_lvolume_delta = 0;
 static int mixer_rvolume_delta = 0;
 static int mixer_balance_volumes = 0;
@@ -301,9 +303,12 @@ static void mixer_update_cbar(int channel_index)
        {0};
        snd_mixer_channel_t cdata =
        {0};
+       snd_mixer_channel_t crdata =
+       {0};
        int vleft, vright;
        int x, y, i;
 
+       int channel_record_volume;
 
        /* set specified EXACT mode
         */
@@ -314,6 +319,7 @@ static void mixer_update_cbar(int channel_index)
         */
        if (snd_mixer_channel_info(mixer_handle, channel_index, &cinfo) < 0)
                mixer_abort(ERR_FCN, "snd_mixer_channel_info");
+       channel_record_volume = (cinfo.caps & SND_MIXER_CINFO_CAP_RECORDVOLUME);
 
        /* set new channel values
         */
@@ -326,14 +332,40 @@ static void mixer_update_cbar(int channel_index)
             mixer_route_rtol_in || mixer_route_ltor_in)) {
                if (snd_mixer_channel_read(mixer_handle, channel_index, &cdata) < 0)
                        mixer_abort(ERR_FCN, "snd_mixer_channel_read");
+               if (mixer_record_volumes && channel_record_volume &&
+                   snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
+                       mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
 
                cdata.flags &= ~SND_MIXER_FLG_DECIBEL;
-               cdata.left = CLAMP(cdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
-               cdata.right = CLAMP(cdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
-               mixer_lvolume_delta = mixer_rvolume_delta = 0;
+               if (mixer_lvolume_delta) {
+                       if (mixer_record_volumes) {
+                               if (channel_record_volume)
+                                       crdata.left = CLAMP(crdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
+                       }
+                       else
+                               cdata.left = CLAMP(cdata.left + mixer_lvolume_delta, cinfo.min, cinfo.max);
+                       mixer_lvolume_delta = 0;
+               }
+               if (mixer_rvolume_delta) {
+                       if (mixer_record_volumes) {
+                               if (channel_record_volume)
+                                       crdata.right = CLAMP(crdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
+                       }
+                       else
+                               cdata.right = CLAMP(cdata.right + mixer_rvolume_delta, cinfo.min, cinfo.max);
+                       mixer_rvolume_delta = 0;
+               }
                if (mixer_balance_volumes) {
-                       cdata.left = (cdata.left + cdata.right) / 2;
-                       cdata.right = cdata.left;
+                       if (mixer_record_volumes) {
+                               if (channel_record_volume) {
+                                       crdata.left = (crdata.left + crdata.right) / 2;
+                                       crdata.right = crdata.left;
+                               }
+                       }
+                       else {
+                               cdata.left = (cdata.left + cdata.right) / 2;
+                               cdata.right = cdata.left;
+                       }
                        mixer_balance_volumes = 0;
                }
                if (mixer_toggle_mute_left) {
@@ -393,14 +425,29 @@ static void mixer_update_cbar(int channel_index)
 
                if (snd_mixer_channel_write(mixer_handle, channel_index, &cdata) < 0)
                        mixer_abort(ERR_FCN, "snd_mixer_channel_write");
+               if (mixer_record_volumes && channel_record_volume &&
+                   snd_mixer_channel_record_write(mixer_handle, channel_index, &crdata) < 0)
+                       mixer_abort(ERR_FCN, "snd_mixer_channel_record_write");
        }
        /* first, read values for the numbers to be displayed in
         * specified EXACT mode
         */
        if (snd_mixer_channel_read(mixer_handle, channel_index, &cdata) < 0)
                mixer_abort(ERR_FCN, "snd_mixer_ioctl_channel_read");
-       vleft = cdata.left;
-       vright = cdata.right;
+       if (mixer_record_volumes) {
+               if (channel_record_volume) {
+                       if (snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
+                               mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
+                       vleft = crdata.left;
+                       vright = crdata.right;
+               }
+               else
+                       vleft = vright = 0;
+       }
+       else {
+               vleft = cdata.left;
+               vright = cdata.right;
+       }
 
        /* then, always use percentage values for the bars. if we don't do
         * this, we will see aliasing effects on specific circumstances.
@@ -413,6 +460,9 @@ static void mixer_update_cbar(int channel_index)
                        mixer_abort(ERR_FCN, "snd_mixer_exact");
                if (snd_mixer_channel_read(mixer_handle, channel_index, &cdata) < 0)
                        mixer_abort(ERR_FCN, "snd_mixer_channel_read");
+               if (mixer_record_volumes && channel_record_volume &&
+                   snd_mixer_channel_record_read(mixer_handle, channel_index, &crdata) < 0)
+                       mixer_abort(ERR_FCN, "snd_mixer_channel_record_read");
        }
        /* get channel bar position
         */
@@ -470,8 +520,8 @@ static void mixer_update_cbar(int channel_index)
                        dc = DC_CBAR_FULL_2;
                else
                        dc = DC_CBAR_FULL_1;
-               mvaddch(y, x + 3, mixer_dc(cdata.left > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
-               mvaddch(y, x + 4, mixer_dc(cdata.right > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
+               mvaddch(y, x + 3, mixer_dc(vleft > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
+               mvaddch(y, x + 4, mixer_dc(vright > i * 100 / mixer_cbar_height ? dc : DC_CBAR_EMPTY));
                y--;
        }
 
@@ -601,6 +651,10 @@ static void mixer_draw_frame(void)
        if (strlen(string) > max_len)
                string[max_len] = 0;
        mvaddstr(2, 2 + 6, string);
+       if (mixer_record_volumes)
+               mvaddstr(3, 2, "Record mixer");
+       else
+               mvaddstr(3, 2, "            ");
 }
 
 static void mixer_init(void)
@@ -752,6 +806,7 @@ static int mixer_iteration(void)
                break;
        case 'm':
        case 'M':
+               mixer_record_volumes = 0;
                mixer_toggle_mute_left = 1;
                mixer_toggle_mute_right = 1;
                break;
@@ -762,14 +817,18 @@ static int mixer_iteration(void)
                break;
        case '<':
        case ',':
+               mixer_record_volumes = 0;
                mixer_toggle_mute_left = 1;
                break;
        case '>':
        case '.':
+               mixer_record_volumes = 0;
                mixer_toggle_mute_right = 1;
                break;
        case 'R':
        case 'r':
+               mixer_record_volumes = !mixer_record_volumes;
+               break;
        case 'L':
        case 'l':
                mixer_clear();
@@ -786,9 +845,11 @@ static int mixer_iteration(void)
                mixer_toggle_rec_right = 1;
                break;
        case '1':
+               mixer_record_volumes = 0;
                mixer_route_rtol_in = 1;
                break;
        case '2':
+               mixer_record_volumes = 0;
                mixer_route_ltor_in = 1;
                break;
        }