]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Changed mixer interface...
authorJaroslav Kysela <perex@perex.cz>
Sun, 1 Nov 1998 23:24:45 +0000 (23:24 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sun, 1 Nov 1998 23:24:45 +0000 (23:24 +0000)
alsactl/alsactl_lexer.l
alsactl/alsactl_parser.y
alsactl/setup.c

index a4728527e58709dfd311bd05d9e130b759e8fa58..f16c76724aa3079c1caf87585bae1c746fcdf942 100644 (file)
@@ -63,13 +63,16 @@ reset                       return L_RESET;
 user                   return L_USER;
 valid                  return L_VALID;
 data                   return L_DATA;
-protected              return L_PROTECTED;
+protected              return L_PROTECT;
 pre2                   return L_PRE2;
 fslock                 return L_FSLOCK;
 type                   return L_TYPE;
 gstatus                        return L_GSTATUS;
 enable                 return L_ENABLE;
 disable                        return L_DISABLE;
+mute                   return L_MUTE;
+swout                  return L_SWOUT;
+swin                   return L_SWIN;
 
        /* boolean */
 
@@ -79,7 +82,6 @@ true|on|yes           return L_TRUE;
        /* integers */
 
 [0-9]+                 { yylval.i_value = atoi( yytext ); return L_INTEGER; }
-"!"[0-9]+              { yylval.i_value = atoi( yytext ); yylval.i_value |= 0x80000000; return L_INTEGER; }
 0x[0-9a-f]+            { char *end;
                           yylval.i_value = strtol( yytext, &end, 0 );
                           return L_INTEGER; }
index 63395bc8838dc5d0c6b92f6c86c5d0de6063b165..f463152cc2bac8c73a7adc653c72b25916f9ba8b 100644 (file)
@@ -43,7 +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( void );
+static void set_mixer_channel_flags( unsigned int mask, unsigned int flags );
 static void set_mixer_channel_end( void );
 
 #define SWITCH_CONTROL         0
@@ -60,7 +60,7 @@ static void select_rawmidi_input_switch( char *name );
 
 static void set_switch_boolean( int val );
 static void set_switch_integer( int val );
-static void set_switch_iec958ocs_begin( void );
+static void set_switch_iec958ocs_begin( int end );
 static void set_switch_iec958ocs( int idx, unsigned short val, unsigned short mask );
 
        /* local variables */
@@ -74,6 +74,8 @@ static unsigned int Xmixerchannelflags = 0;
 static int Xswitchtype = SWITCH_CONTROL;
 static int *Xswitchchange = NULL;
 static void *Xswitch = NULL;
+static unsigned int Xswitchiec958ocs = 0;
+static unsigned short Xswitchiec958ocs1[16];
 
 %}
 
@@ -100,8 +102,8 @@ static void *Xswitch = NULL;
        /* other keywords */
 %token L_SOUNDCARD L_MIXER L_CHANNEL L_STEREO L_MONO L_SWITCH L_RAWDATA
 %token L_CONTROL L_PCM L_RAWMIDI L_PLAYBACK L_RECORD L_OUTPUT L_INPUT
-%token L_IEC958OCS L_3D L_RESET L_USER L_VALID L_DATA L_PROTECTED L_PRE2
-%token L_FSLOCK L_TYPE L_GSTATUS L_ENABLE L_DISABLE
+%token L_IEC958OCS L_3D L_RESET L_USER L_VALID L_DATA L_PROTECT L_PRE2
+%token L_FSLOCK L_TYPE L_GSTATUS L_ENABLE L_DISABLE L_MUTE L_SWOUT L_SWIN
 
 %type <b_value> boolean
 %type <i_value> integer
@@ -150,12 +152,45 @@ mvalues : mvalue
        | mvalues mvalue
        ;
 
-mvalue : L_STEREO '(' integer ',' integer ')' { set_mixer_channel( $3, $5 ); }
-       | L_MONO '(' integer ')' { set_mixer_channel( $3, $3 ); }
-       | L_RECORD              { set_mixer_channel_record(); }
+mvalue : L_STEREO '(' xmchls ',' xmchrs ')'
+       | L_MONO '(' xmchs ')'
        | error                 { yyerror( "unknown keyword in mixer channel{} level" ); }
        ;
 
+xmchls : xmchl
+       | xmchls xmchl
+       ;
+
+xmchl  : L_INTEGER             { set_mixer_channel( $1, -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 ); }
+       | L_SWIN                { set_mixer_channel_flags( SND_MIXER_FLG_LTOR_IN, SND_MIXER_FLG_LTOR_IN ); }
+       | error                 { yyerror( "unknown keyword in left channel section..." ); }
+       ;
+
+xmchrs : xmchr
+       | xmchrs xmchr
+       ;
+
+xmchr  : L_INTEGER             { set_mixer_channel( -1, $1 ); }
+       | 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 ); }
+       | L_SWIN                { set_mixer_channel_flags( SND_MIXER_FLG_RTOL_IN, SND_MIXER_FLG_RTOL_IN ); }
+       | error                 { yyerror( "unknown keyword in right channel section..." ); }
+       ;
+
+xmchs  : xmch
+       | xmchs xmch
+       ;
+
+xmch   : L_INTEGER             { set_mixer_channel( $1, $1 ); }
+       | 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..." ); }
+       ;
+
 pcms   : pcm
        | pcms pcm
        ;
@@ -212,7 +247,7 @@ switches : switch
 switch : L_TRUE                { set_switch_boolean( 1 ); }
        | L_FALSE               { set_switch_boolean( 0 ); }
        | L_INTEGER             { set_switch_integer( $1 ); }
-       | L_IEC958OCS '(' { set_switch_iec958ocs_begin(); } iec958ocs ')'
+       | L_IEC958OCS '(' { set_switch_iec958ocs_begin( 0 ); } iec958ocs { set_switch_iec958ocs_begin( 1 ); } ')'
        | error                 { yyerror( "unknown keyword in switch() data parameter" ); }
        ;
 
@@ -227,6 +262,7 @@ iec958ocs1 : L_ENABLE               { set_switch_iec958ocs( 0, 1, 0 ); }
        | L_USER                { set_switch_iec958ocs( 4, 0x0020, ~0x0020 ); }
        | L_VALID               { set_switch_iec958ocs( 4, 0x0010, ~0x0010 ); }
        | L_DATA                { set_switch_iec958ocs( 5, 0x0002, ~0x0002 ); }
+       | L_PROTECT             { set_switch_iec958ocs( 5, 0x0004, ~0x0004 ); }
        | L_PRE2                { set_switch_iec958ocs( 5, 0x0008, ~0x0018 ); }
        | L_FSLOCK              { set_switch_iec958ocs( 5, 0x0020, ~0x0020 ); }
        | L_TYPE '(' integer ')' { set_switch_iec958ocs( 5, ($3 & 0x7f) << 6, ~(0x7f<<6) ); }
@@ -334,6 +370,13 @@ static void select_mixer_channel( char *name )
   for ( channel = Xmixer -> channels; channel; channel = channel -> next )
     if ( !strcmp( channel -> i.name, name ) ) {
       Xmixerchannel = channel;
+      Xmixerchannelflags = Xmixerchannel -> c.flags & 
+                               ~(SND_MIXER_FLG_RECORD |
+                                 SND_MIXER_FLG_MUTE |
+                                 SND_MIXER_FLG_SWITCH_OUT |
+                                 SND_MIXER_FLG_SWITCH_IN |
+                                 SND_MIXER_FLG_DECIBEL |
+                                 SND_MIXER_FLG_FORCE);
       free( name );
       return;
     }
@@ -343,38 +386,33 @@ static void select_mixer_channel( char *name )
 
 static void set_mixer_channel( int left, int right )
 {
-  Xmixerchannelflags = Xmixerchannel -> c.flags & 
-                       ~(SND_MIXER_FLG_RECORD |
-                         SND_MIXER_FLG_MUTE |
-                         SND_MIXER_FLG_DECIBEL |
-                         SND_MIXER_FLG_FORCE);
-  if ( left & 0x80000000 ) {
-    Xmixerchannelflags |= SND_MIXER_FLG_MUTE_LEFT;
-    left &= 0x7fffffff;
+  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 -> c.left != left )
+      Xmixerchannel -> change = 1;
+    Xmixerchannel -> c.left = left;
   }
-  if ( right & 0x80000000 ) {
-    Xmixerchannelflags |= SND_MIXER_FLG_MUTE_RIGHT;
-    right &= 0x7fffffff;
+  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 -> c.right != right )
+      Xmixerchannel -> change = 1;
+    Xmixerchannel -> c.right = right;
   }
-  if ( Xmixerchannel -> i.min > left || Xmixerchannel -> i.max < left )
-    yyerror( "Value out of range (%i-%i)...", Xmixerchannel -> i.min, Xmixerchannel -> i.max );
-  if ( Xmixerchannel -> i.min > right || Xmixerchannel -> i.max < right )
-    yyerror( "Value out of range (%i-%i)...", Xmixerchannel -> i.min, Xmixerchannel -> i.max );
-  if ( Xmixerchannel -> c.left != left || Xmixerchannel -> c.right != right )
-    Xmixerchannel -> change = 1;
-  Xmixerchannel -> c.left = left;
-  Xmixerchannel -> c.right = right;
 }
 
-static void set_mixer_channel_record( void )
+static void set_mixer_channel_flags( unsigned int mask, unsigned int flags )
 {
-  Xmixerchannelflags |= SND_MIXER_FLG_RECORD;
+  Xmixerchannelflags &= ~mask;
+  Xmixerchannelflags |= flags;
 }
 
 static void set_mixer_channel_end( void )
 {
-  if ( Xmixerchannel -> c.flags != Xmixerchannelflags )
+  if ( Xmixerchannel -> c.flags != Xmixerchannelflags ) {
     Xmixerchannel -> change = 1;
+  }
   Xmixerchannel -> c.flags = Xmixerchannelflags;
 }
 
@@ -458,30 +496,42 @@ static void set_switch_integer( int val )
   memcpy( &sw -> value, &xx, sizeof(xx) );
 }
 
-static void set_switch_iec958ocs_begin( void )
+static void set_switch_iec958ocs_begin( int end )
 {
   /* ok.. this is a little bit wrong, but at these times are all switches same */
   snd_ctl_switch_t *sw = (snd_ctl_switch_t *)Xswitch;
 
+  if ( !end ) {
+    if ( Xswitchiec958ocs != sw -> value.enable ) {
+      sw -> value.enable = Xswitchiec958ocs;
+      *Xswitchchange = 1;
+    }
+    if ( Xswitchiec958ocs1[4] != sw -> value.data16[4] ) {
+      sw -> value.data16[4] = Xswitchiec958ocs1[4];
+      *Xswitchchange = 1;
+    }
+    if ( Xswitchiec958ocs1[5] != sw -> value.data16[5] ) {
+      sw -> value.data16[5] = Xswitchiec958ocs1[5];
+      *Xswitchchange = 1;
+    }
+    return;
+  }
   if ( Xswitchtype != SWITCH_MIXER || sw -> type != SND_MIXER_SW_TYPE_BOOLEAN ||
-       !strcmp( sw -> name, SND_MIXER_SW_IEC958OUT ) )
+       strcmp( sw -> name, SND_MIXER_SW_IEC958OUT ) )
     yyerror( "Switch '%s' cannot store IEC958 information for Cirrus Logic chips...", sw -> name );
   if ( sw -> value.data32[1] != (('C'<<8)|'S') )
     yyerror( "Switch '%s' doesn't have Cirrus Logic signature!!!", sw -> name );
-  sw -> value.enable = 0;
-  sw -> value.data16[4] = 0x0000;
-  sw -> value.data16[5] = 0x0000;
+  Xswitchiec958ocs = 0;
+  Xswitchiec958ocs1[4] = 0x0000;
+  Xswitchiec958ocs1[5] = 0x0000;
 }
 
 static void set_switch_iec958ocs( int idx, unsigned short val, unsigned short mask )
 {
-  /* ok.. this is a little bit wrong, but at these times are all switches same */
-  snd_ctl_switch_t *sw = (snd_ctl_switch_t *)Xswitch;
-
   if ( idx == 0 ) {
-    sw -> value.enable = val ? 1 : 0;
+    Xswitchiec958ocs = val ? 1 : 0;
     return;
   }
-  sw -> value.data16[ idx ] &= ~mask;
-  sw -> value.data16[ idx ] |= val;
+  Xswitchiec958ocs1[ idx ] &= ~mask;
+  Xswitchiec958ocs1[ idx ] |= val;
 }
index df0e6e3060db203778d014e2d54a32d20e7a5727..23334f79195f9b88da332b3942607e43e1ad5708 100644 (file)
@@ -520,14 +520,13 @@ int soundcard_setup_load( const char *cfgfile )
 
 static void soundcard_setup_write_switch( FILE *out, int interface, const unsigned char *name, unsigned int type, unsigned int low, unsigned int high, void *data )
 {
-  struct data {
+  union {
     unsigned int enable;
     unsigned char data8[32];
     unsigned short data16[16];
     unsigned int data32[8];
-  };
+  } *pdata = data;
   char *s, v[16];
-  struct data *pdata = (struct data *)data;
   int idx, first, switchok = 0;
   const char *space = "    ";
   
@@ -558,10 +557,10 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
     }
     if ( !first ) fprintf( out, "\n" );
   }
-  fprintf( out, "%sswitch( \"%s\", ", space, name );
   if ( interface == SND_INTERFACE_MIXER && type == SND_MIXER_SW_TYPE_BOOLEAN &&
        !strcmp( name, SND_MIXER_SW_IEC958OUT ) ) {
-    if ( pdata -> data16[0] == (('C'<<8)|'S') ) {      /* Cirrus Crystal */
+    fprintf( out, "%sswitch( \"%s\", ", space, name );
+    if ( pdata -> data32[1] == (('C'<<8)|'S') ) {      /* Cirrus Crystal */
       switchok = 0;
       fprintf( out, "iec958ocs( %s", pdata -> enable ? "enable" : "disable" );
       if ( pdata -> data16[4] & 0x2000 ) fprintf( out, " 3d" );
@@ -577,9 +576,11 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
       if ( pdata -> data16[5] & 0x0020 ) fprintf( out, " fslock" );
       fprintf( out, " type( 0x%x )", (pdata -> data16[5] >> 6) & 0x7f );
       if ( pdata -> data16[5] & 0x2000 ) fprintf( out, " gstatus" );
-      fprintf( out, ")" );
+      fprintf( out, " )" );
+      goto __end;
     }
   }
+  fprintf( out, "%sswitch( \"%s\", ", space, name );
   if ( !switchok ) {
     fprintf( out, v );
     if ( type < 0 || type > SND_CTL_SW_TYPE_DWORD ) {
@@ -591,28 +592,50 @@ static void soundcard_setup_write_switch( FILE *out, int interface, const unsign
       fprintf( out, "%02x@ )\n", pdata -> data8[31] );
     }
   }
+  __end:
   fprintf( out, " )\n" );
 }
 
 
 static void soundcard_setup_write_mixer_channel( FILE *out, snd_mixer_channel_info_t *info, snd_mixer_channel_t *channel )
 {
-  fprintf( out, "    ; Capabilities:%s%s%s%s%s%s.\n",
+  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" : "",
+       info -> caps & SND_MIXER_CINFO_CAP_JOINRECORD ? " join-record" : "",
        info -> caps & SND_MIXER_CINFO_CAP_STEREO ? " stereo" : "",
        info -> caps & SND_MIXER_CINFO_CAP_HWMUTE ? " hardware-mute" : "",
-       info -> caps & SND_MIXER_CINFO_CAP_MONOMUTE ? " mono-mute" : "",
+       info -> caps & SND_MIXER_CINFO_CAP_JOINMUTE ? " join-mute" : "",
        info -> caps & SND_MIXER_CINFO_CAP_DIGITAL ? " digital" : "",
-       info -> caps & SND_MIXER_CINFO_CAP_INPUT ? " external-input" : "" );
+       info -> caps & SND_MIXER_CINFO_CAP_INPUT ? " external-input" : "",
+       info -> caps & SND_MIXER_CINFO_CAP_LTOR_OUT ? " ltor-out" : "",
+       info -> caps & SND_MIXER_CINFO_CAP_RTOL_OUT ? " rtol-out" : "",
+       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" : "" );
   fprintf( out, "    ; Accepted channel range is from %i to %i.\n", info -> min, info -> max );
   fprintf( out, "    channel( \"%s\", ", info -> name );
+  printf( "flags = 0x%x\n", channel -> flags );
   if ( info -> caps & SND_MIXER_CINFO_CAP_STEREO ) {
-    fprintf( out, "stereo( %s%i, %s%i )", channel -> flags & SND_MIXER_FLG_MUTE_LEFT ? "!" : "", channel -> left, channel -> flags & SND_MIXER_FLG_MUTE_RIGHT ? "!" : "", channel -> right );
+    fprintf( out, "stereo( %i%s%s%s%s, %i%s%s%s%s )",
+      channel -> left,
+      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" : "",
+      channel -> right,
+      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" : ""
+    );
   } else {
-    fprintf( out, "mono( %s%i )", channel -> flags & SND_MIXER_FLG_MUTE ? "!" : "", channel -> left );
+    fprintf( out, "mono( %i%s%s )", 
+      (channel -> left + channel -> right) / 2,
+      channel -> flags & SND_MIXER_FLG_MUTE ? " mute" : "",
+      channel -> flags & SND_MIXER_FLG_RECORD ? " record" : ""
+    );
   }
-  if ( channel -> flags & SND_MIXER_FLG_RECORD )
-    fprintf( out, " record" );
   fprintf( out, " )\n" );
 }
 
@@ -649,7 +672,7 @@ int soundcard_setup_write( const char *cfgfile )
       for ( mixerchannel = mixer -> channels; mixerchannel; mixerchannel = mixerchannel -> next )
         soundcard_setup_write_mixer_channel( out, &mixerchannel -> i, &mixerchannel -> c );
       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 );
+        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" );
     }
     for ( pcm = first -> pcms; pcm; pcm = pcm -> next ) {