mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-09 17:05:41 +01:00
Changes for record volume...
This commit is contained in:
parent
87c7c4f447
commit
88cdd83d0f
6 changed files with 132 additions and 24 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue