]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Updated switches interfaces.
authorJaroslav Kysela <perex@perex.cz>
Fri, 28 Aug 1998 14:04:48 +0000 (14:04 +0000)
committerJaroslav Kysela <perex@perex.cz>
Fri, 28 Aug 1998 14:04:48 +0000 (14:04 +0000)
Makefile
include/control.h
include/header.h
include/pcm.h
include/rawmidi.h
src/control/control.c
src/pcm/pcm.c
src/rawmidi/rawmidi.c
test/Makefile
test/switches.c [new file with mode: 0644]

index 7b306702a2d5dc18bd8af31d468af666923d9509..7e467fe473a7baeefa51c6ef45fd6a26631a5f09 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ clean:
 
 cvsclean: clean
        rm -f configure config.cache config.log config.status Makefile.conf \
-              utils/alsa-lib.spec include/config.h include/soundlib.h
+              utils/alsa-lib.spec include/config.h include/soundlib.h include/version.h
 
 pack: cvsclean
        chown -R root.root ../alsa-lib
index b923ea9a10a600b1c736cc5847084232144c9338..e2e0f8b703e805f7c9c8bee7c5669c169aea7eea 100644 (file)
@@ -25,6 +25,7 @@ int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info );
 int snd_ctl_pcm_playback_info( void *handle, int dev, snd_pcm_playback_info_t *info );
 int snd_ctl_pcm_record_info( void *handle, int dev, snd_pcm_record_info_t *info );
 int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info );
+int snd_ctl_rawmidi_info( void *handle, int dev, snd_rawmidi_info_t *info );
 
 #ifdef __cplusplus
 }
index f0cab83eb4aa31da5b3ae881c34b53f60c511351..3bf1812433a5b0ba0d5848dd403c6337d4eb78b9 100644 (file)
@@ -24,4 +24,5 @@
 
 #include <linux/sound.h>
 #include <unistd.h>
+#include <fcntl.h>
 
index b90e35778b1552c6fe1ca51e9d5d36ed6c9963a2..fc55f174d5177f1c8bbf6918966021ddbd840aae 100644 (file)
@@ -20,10 +20,14 @@ int snd_pcm_block_mode( void *handle, int enable );
 int snd_pcm_info( void *handle, snd_pcm_info_t *info );
 int snd_pcm_playback_info( void *handle, snd_pcm_playback_info_t *info );
 int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info );
-int snd_pcm_switches( void *handle );
-int snd_pcm_switch( void *handle, const char *switch_id );
-int snd_pcm_switch_read( void *handle, int switchn, snd_pcm_switch_t *data );
-int snd_pcm_switch_write( void *handle, int switchn, snd_pcm_switch_t *data ); 
+int snd_pcm_playback_switches( void *handle );
+int snd_pcm_playback_switch( void *handle, const char *switch_id );
+int snd_pcm_playback_switch_read( void *handle, int switchn, snd_pcm_switch_t *data );
+int snd_pcm_playback_switch_write( void *handle, int switchn, snd_pcm_switch_t *data ); 
+int snd_pcm_record_switches( void *handle );
+int snd_pcm_record_switch( void *handle, const char *switch_id );
+int snd_pcm_record_switch_read( void *handle, int switchn, snd_pcm_switch_t *data );
+int snd_pcm_record_switch_write( void *handle, int switchn, snd_pcm_switch_t *data ); 
 int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format );
 int snd_pcm_record_format( void *handle, snd_pcm_format_t *format );
 int snd_pcm_playback_params( void *handle, snd_pcm_playback_params_t *params );
index c86e63c066b18f2581d1551858b807f1db777dea..acc391b95db001c941526ce4f79e7ad0b1c83139 100644 (file)
@@ -18,10 +18,14 @@ int snd_rawmidi_close( void *handle );
 int snd_rawmidi_file_descriptor( void *handle );
 int snd_rawmidi_block_mode( void *handle, int enable );
 int snd_rawmidi_info( void *handle, snd_rawmidi_info_t *info );
-int snd_rawmidi_switches( void *handle );
-int snd_rawmidi_switch( void *handle, const char *switch_id );
-int snd_rawmidi_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data );
-int snd_rawmidi_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data );
+int snd_rawmidi_output_switches( void *handle );
+int snd_rawmidi_output_switch( void *handle, const char *switch_id );
+int snd_rawmidi_output_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data );
+int snd_rawmidi_output_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data );
+int snd_rawmidi_input_switches( void *handle );
+int snd_rawmidi_input_switch( void *handle, const char *switch_id );
+int snd_rawmidi_input_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data );
+int snd_rawmidi_input_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data );
 int snd_rawmidi_output_params( void *handle, snd_rawmidi_output_params_t *params );
 int snd_rawmidi_input_params( void *handle, snd_rawmidi_input_params_t *params );
 int snd_rawmidi_output_status( void *handle, snd_rawmidi_output_status_t *status );
index 3bb498b74e2e10b5b2ca9ba9eaf3f2a6a75cffd6..2e98b3df0c4989561b4131313b0a2ac30765815e 100644 (file)
@@ -203,3 +203,16 @@ int snd_ctl_mixer_info( void *handle, int dev, snd_mixer_info_t *info )
     return -errno;
   return 0;
 }
+
+int snd_ctl_rawmidi_info( void *handle, int dev, snd_rawmidi_info_t *info )
+{
+  snd_ctl_t *ctl;
+  
+  ctl = (snd_ctl_t *)handle;
+  if ( !ctl ) return -EINVAL;
+  if ( ioctl( ctl -> fd, SND_CTL_IOCTL_RAWMIDI_DEVICE, &dev ) < 0 )
+    return -errno;
+  if ( ioctl( ctl -> fd, SND_CTL_IOCTL_RAWMIDI_INFO, info ) < 0 )
+    return -errno;
+  return 0;
+}
index 707539140a011c3460d2f32a34adea39a124210b..15c5d9ed8091657965fe183d7143bda664347820 100644 (file)
@@ -137,19 +137,19 @@ int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info )
   return 0;
 }
 
-int snd_pcm_switches( void *handle )
+int snd_pcm_playback_switches( void *handle )
 {
   snd_pcm_t *pcm;
   int result;
 
   pcm = (snd_pcm_t *)handle;
   if ( !pcm ) return -EINVAL;
-  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_SWITCHES, &result ) < 0 )
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PSWITCHES, &result ) < 0 )
     return -errno;
   return result;
 }
 
-int snd_pcm_switch( void *handle, const char *switch_id )
+int snd_pcm_playback_switch( void *handle, const char *switch_id )
 {
   snd_pcm_t *pcm;
   snd_pcm_switch_t uswitch;
@@ -159,10 +159,10 @@ int snd_pcm_switch( void *handle, const char *switch_id )
   if ( !pcm ) return -EINVAL;
   /* bellow implementation isn't optimized for speed */
   /* info about switches should be cached in the snd_mixer_t structure */
-  if ( (switches = snd_mixer_switches( handle )) < 0 )
+  if ( (switches = snd_pcm_playback_switches( handle )) < 0 )
     return switches;
   for ( idx = 0; idx < switches; idx++ ) {
-    if ( (err = snd_pcm_switch_read( handle, idx, &uswitch )) < 0 )
+    if ( (err = snd_pcm_playback_switch_read( handle, idx, &uswitch )) < 0 )
       return err;
     if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) )
       return idx;
@@ -170,26 +170,83 @@ int snd_pcm_switch( void *handle, const char *switch_id )
   return -EINVAL;
 }
 
-int snd_pcm_switch_read( void *handle, int switchn, snd_pcm_switch_t *data )
+int snd_pcm_playback_switch_read( void *handle, int switchn, snd_pcm_switch_t *data )
 {
   snd_pcm_t *pcm;
 
   pcm = (snd_pcm_t *)handle;
   if ( !pcm ) return -EINVAL;
   data -> switchn = switchn;
-  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_SWITCH_READ, data ) < 0 )
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PSWITCH_READ, data ) < 0 )
     return -errno;
   return 0;
 }
                 
-int snd_pcm_switch_write( void *handle, int switchn, snd_pcm_switch_t *data )
+int snd_pcm_playback_switch_write( void *handle, int switchn, snd_pcm_switch_t *data )
 {
   snd_pcm_t *pcm;
 
   pcm = (snd_pcm_t *)handle;
   if ( !pcm ) return -EINVAL;
   data -> switchn = switchn;
-  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_SWITCH_WRITE, data ) < 0 )
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_PSWITCH_WRITE, data ) < 0 )
+    return -errno;
+  return 0;
+}                
+
+int snd_pcm_record_switches( void *handle )
+{
+  snd_pcm_t *pcm;
+  int result;
+
+  pcm = (snd_pcm_t *)handle;
+  if ( !pcm ) return -EINVAL;
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RSWITCHES, &result ) < 0 )
+    return -errno;
+  return result;
+}
+
+int snd_pcm_record_switch( void *handle, const char *switch_id )
+{
+  snd_pcm_t *pcm;
+  snd_pcm_switch_t uswitch;
+  int idx, switches, err;
+
+  pcm = (snd_pcm_t *)handle;
+  if ( !pcm ) return -EINVAL;
+  /* bellow implementation isn't optimized for speed */
+  /* info about switches should be cached in the snd_mixer_t structure */
+  if ( (switches = snd_pcm_record_switches( handle )) < 0 )
+    return switches;
+  for ( idx = 0; idx < switches; idx++ ) {
+    if ( (err = snd_pcm_record_switch_read( handle, idx, &uswitch )) < 0 )
+      return err;
+    if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) )
+      return idx;
+  }
+  return -EINVAL;
+}
+
+int snd_pcm_record_switch_read( void *handle, int switchn, snd_pcm_switch_t *data )
+{
+  snd_pcm_t *pcm;
+
+  pcm = (snd_pcm_t *)handle;
+  if ( !pcm ) return -EINVAL;
+  data -> switchn = switchn;
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RSWITCH_READ, data ) < 0 )
+    return -errno;
+  return 0;
+}
+                
+int snd_pcm_record_switch_write( void *handle, int switchn, snd_pcm_switch_t *data )
+{
+  snd_pcm_t *pcm;
+
+  pcm = (snd_pcm_t *)handle;
+  if ( !pcm ) return -EINVAL;
+  data -> switchn = switchn;
+  if ( ioctl( pcm -> fd, SND_PCM_IOCTL_RSWITCH_WRITE, data ) < 0 )
     return -errno;
   return 0;
 }                
index 8566c4bea17823937241aa147bd35df35a4f6ef4..016541e618fb281605d568a91b0425ceea337376 100644 (file)
@@ -28,7 +28,7 @@
 #include <sys/ioctl.h>
 #include "soundlib.h"
 
-#define SND_FILE_RAWMIDI       "/dev/snd/rawmidi%i%i"
+#define SND_FILE_RAWMIDI       "/dev/snd/midi%i%i"
 #define SND_PCM_VERSION_MAX    SND_PROTOCOL_VERSION( 1, 0, 0 )
  
 typedef struct {
@@ -47,7 +47,7 @@ int snd_rawmidi_open( void **handle, int card, int device, int mode )
   if ( card < 0 || card >= SND_CARDS ) return -EINVAL;
   sprintf( filename, SND_FILE_RAWMIDI, card, device );
   if ( (fd = open( filename, mode )) < 0 ) return -errno;
-  if ( ioctl( fd, SND_PCM_IOCTL_PVERSION, &ver ) < 0 ) {
+  if ( ioctl( fd, SND_RAWMIDI_IOCTL_PVERSION, &ver ) < 0 ) {
     close( fd );
     return -errno;
   }
@@ -115,19 +115,19 @@ int snd_rawmidi_info( void *handle, snd_rawmidi_info_t *info )
   return 0;
 }
 
-int snd_rawmidi_switches( void *handle )
+int snd_rawmidi_output_switches( void *handle )
 {
   snd_rawmidi_t *rmidi;
   int result;
 
   rmidi = (snd_rawmidi_t *)handle;
   if ( !rmidi ) return -EINVAL;
-  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_SWITCHES, &result ) < 0 )
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_OSWITCHES, &result ) < 0 )
     return -errno;
   return result;
 }
 
-int snd_rawmidi_switch( void *handle, const char *switch_id )
+int snd_rawmidi_output_switch( void *handle, const char *switch_id )
 {
   snd_rawmidi_t *rmidi;
   snd_rawmidi_switch_t uswitch;
@@ -137,10 +137,10 @@ int snd_rawmidi_switch( void *handle, const char *switch_id )
   if ( !rmidi ) return -EINVAL;
   /* bellow implementation isn't optimized for speed */
   /* info about switches should be cached in the snd_mixer_t structure */
-  if ( (switches = snd_rawmidi_switches( handle )) < 0 )
+  if ( (switches = snd_rawmidi_output_switches( handle )) < 0 )
     return switches;
   for ( idx = 0; idx < switches; idx++ ) {
-    if ( (err = snd_rawmidi_switch_read( handle, idx, &uswitch )) < 0 )
+    if ( (err = snd_rawmidi_output_switch_read( handle, idx, &uswitch )) < 0 )
       return err;
     if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) )
       return idx;
@@ -148,26 +148,83 @@ int snd_rawmidi_switch( void *handle, const char *switch_id )
   return -EINVAL;
 }
 
-int snd_rawmidi_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data )
+int snd_rawmidi_output_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data )
 {
   snd_rawmidi_t *rmidi;
 
   rmidi = (snd_rawmidi_t *)handle;
   if ( !rmidi ) return -EINVAL;
   data -> switchn = switchn;
-  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_SWITCH_READ, data ) < 0 )
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_OSWITCH_READ, data ) < 0 )
     return -errno;
   return 0;
 }
                 
-int snd_rawmidi_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data )
+int snd_rawmidi_output_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data )
 {
   snd_rawmidi_t *rmidi;
 
   rmidi = (snd_rawmidi_t *)handle;
   if ( !rmidi ) return -EINVAL;
   data -> switchn = switchn;
-  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_SWITCH_WRITE, data ) < 0 )
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_OSWITCH_WRITE, data ) < 0 )
+    return -errno;
+  return 0;
+}                
+
+int snd_rawmidi_input_switches( void *handle )
+{
+  snd_rawmidi_t *rmidi;
+  int result;
+
+  rmidi = (snd_rawmidi_t *)handle;
+  if ( !rmidi ) return -EINVAL;
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_ISWITCHES, &result ) < 0 )
+    return -errno;
+  return result;
+}
+
+int snd_rawmidi_input_switch( void *handle, const char *switch_id )
+{
+  snd_rawmidi_t *rmidi;
+  snd_rawmidi_switch_t uswitch;
+  int idx, switches, err;
+
+  rmidi = (snd_rawmidi_t *)handle;
+  if ( !rmidi ) return -EINVAL;
+  /* bellow implementation isn't optimized for speed */
+  /* info about switches should be cached in the snd_mixer_t structure */
+  if ( (switches = snd_rawmidi_input_switches( handle )) < 0 )
+    return switches;
+  for ( idx = 0; idx < switches; idx++ ) {
+    if ( (err = snd_rawmidi_input_switch_read( handle, idx, &uswitch )) < 0 )
+      return err;
+    if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) )
+      return idx;
+  }
+  return -EINVAL;
+}
+
+int snd_rawmidi_input_switch_read( void *handle, int switchn, snd_rawmidi_switch_t *data )
+{
+  snd_rawmidi_t *rmidi;
+
+  rmidi = (snd_rawmidi_t *)handle;
+  if ( !rmidi ) return -EINVAL;
+  data -> switchn = switchn;
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_ISWITCH_READ, data ) < 0 )
+    return -errno;
+  return 0;
+}
+                
+int snd_rawmidi_input_switch_write( void *handle, int switchn, snd_rawmidi_switch_t *data )
+{
+  snd_rawmidi_t *rmidi;
+
+  rmidi = (snd_rawmidi_t *)handle;
+  if ( !rmidi ) return -EINVAL;
+  data -> switchn = switchn;
+  if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_ISWITCH_WRITE, data ) < 0 )
     return -errno;
   return 0;
 }                
index 80a99a57ceef6f1c59da7d310d1ed963a7b3ad49..e4d9d68ad84ca04e6705cbea8a0550cefaafd4ca 100644 (file)
@@ -1,6 +1,6 @@
 CC             = gcc
 CFLAGS = -static -O2 -g -Wall -pipe
-TARGETS = control mixer
+TARGETS = control mixer switches
 LIB    = -L../lib -lsound
 
 all: $(TARGETS)
@@ -11,5 +11,8 @@ control: control.c
 mixer: mixer.c
        $(CC) $(CFLAGS) $(LIB) -o mixer mixer.c
 
+switches: switches.c
+       $(CC) $(CFLAGS) $(LIB) -o switches switches.c
+
 clean:
        rm -f *.o $(TARGETS) *~
diff --git a/test/switches.c b/test/switches.c
new file mode 100644 (file)
index 0000000..f8992c2
--- /dev/null
@@ -0,0 +1,224 @@
+#include <stdio.h>
+#include <string.h>
+#include "../include/soundlib.h"
+
+const char *get_type( unsigned int type )
+{
+  switch ( type ) {
+    case 0: return "Boolean";
+    case 1: return "Byte";
+    case 2: return "Word";
+    case 3: return "DWord";
+    case 4: return "User";
+    default:
+      return "Unknown";
+  }
+}
+
+void main( void )
+{
+  int cards, card, device, direction, idx, count, err;
+  void *handle, *chandle;
+  struct snd_ctl_hw_info info;
+  struct snd_ctl_switch ctl_switch;
+  snd_mixer_switch_t mixer_switch;
+  snd_pcm_info_t pcm_info;
+  snd_pcm_switch_t pcm_switch;
+  snd_rawmidi_switch_t rmidi_switch;
+  snd_rawmidi_info_t rmidi_info;
+  
+  cards = snd_cards();
+  printf( "Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "" );
+  if ( cards <= 0 ) {
+    printf( "Giving up...\n" );
+    return;
+  }
+  
+  /* control interface */
+  for ( card = 0; card < cards; card++ ) {
+    if ( (err = snd_ctl_open( &handle, card )) < 0 ) {
+      printf( "CTL open error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    if ( (err = snd_ctl_hw_info( handle, &info )) < 0 ) {
+      printf( "CTL hw info error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    if ( (count = snd_ctl_switches( handle )) < 0 ) {
+      printf( "CTL switches error: %s\n", snd_strerror( count ) );
+      continue;
+    }
+    for ( idx = 0; idx < count; idx++ ) {
+      if ( (err = snd_ctl_switch_read( handle, idx, &ctl_switch )) < 0 ) {
+        printf( "CTL switch read error: %s\n", snd_strerror( count ) );
+        continue;
+      }
+      printf( "CTL switch: '%s' %s (%i-%i)\n", ctl_switch.name, get_type( ctl_switch.type ), ctl_switch.low, ctl_switch.high );
+      if ( (err = snd_ctl_switch_write( handle, idx, &ctl_switch )) < 0 ) {
+        printf( "CTL switch write error: %s\n", snd_strerror( count ) );
+        continue;
+      }
+    }
+    if ( count <= 0 )
+      printf( "No CTL switches detected for soundcard #%i '%s'...\n", idx, info.name );
+    snd_ctl_close( handle );
+  }
+
+  /* mixer interface */
+  for ( card = 0; card < cards; card++ ) {
+    if ( (err = snd_ctl_open( &handle, card )) < 0 ) {
+      printf( "CTL open error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    if ( (err = snd_ctl_hw_info( handle, &info )) < 0 ) {
+      printf( "CTL hw info error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    snd_ctl_close( handle );
+    for ( device = 0; device < info.mixerdevs; device++ ) {
+      if ( (err = snd_mixer_open( &handle, card, device )) < 0 ) {
+        printf( "Mixer open error: %s\n", snd_strerror( err ) );
+        continue;
+      }
+      if ( (count = snd_mixer_switches( handle )) < 0 ) {
+        printf( "Mixer switches error: %s\n", snd_strerror( count ) );
+        continue;
+      }
+      for ( idx = 0; idx < count; idx++ ) {
+        if ( (err = snd_mixer_switch_read( handle, idx, &mixer_switch )) < 0 ) {
+          printf( "Mixer switch read error: %s\n", snd_strerror( count ) );
+          continue;
+        }
+        printf( "Mixer switch: '%s' %s (%i-%i)\n", mixer_switch.name, get_type( mixer_switch.type ), mixer_switch.low, mixer_switch.high );
+        if ( (err = snd_mixer_switch_write( handle, idx, &mixer_switch )) < 0 ) {
+          printf( "Mixer switch write error: %s\n", snd_strerror( count ) );
+          continue;
+        }
+      }
+      if ( count <= 0 )
+        printf( "No mixer switches detected for soundcard #%i '%s'...\n", idx, info.name );
+      snd_mixer_close( handle );
+    }
+  }
+
+  /* pcm switches */
+  for ( card = 0; card < cards; card++ ) {
+    if ( (err = snd_ctl_open( &chandle, card )) < 0 ) {
+      printf( "CTL open error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    if ( (err = snd_ctl_hw_info( chandle, &info )) < 0 ) {
+      printf( "CTL hw info error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    for ( device = 0; device < info.pcmdevs; device++ ) {
+      if ( (err = snd_ctl_pcm_info( chandle, device, &pcm_info )) < 0 ) {
+        printf( "CTL PCM info error: %s\n", snd_strerror( err ) );
+        continue;
+      }
+      for ( direction = 0; direction < 2; direction++ ) {
+        int (*switches)( void *handle );
+        int (*switch_read)( void *handle, int switchn, snd_pcm_switch_t *data );
+        int (*switch_write)( void *handle, int switchn, snd_pcm_switch_t *data );
+        char *str;
+
+        if ( !(pcm_info.flags & (!direction ? SND_PCM_INFO_PLAYBACK : SND_PCM_INFO_RECORD)) ) continue;
+        if ( (err = snd_pcm_open( &handle, card, device, !direction ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_RECORD )) < 0 ) {
+          printf( "PCM open error: %s\n", snd_strerror( err ) );
+          continue;
+        }
+        if ( !direction ) {
+          switches = snd_pcm_playback_switches;
+          switch_read = snd_pcm_playback_switch_read;
+          switch_write = snd_pcm_playback_switch_write;
+          str = "playback";
+        } else {
+          switches = snd_pcm_record_switches;
+          switch_read = snd_pcm_record_switch_read;
+          switch_write = snd_pcm_record_switch_write;
+          str = "record";
+        }
+        if ( (count = switches( handle )) < 0 ) {
+          printf( "PCM %s switches error: %s\n", str, snd_strerror( count ) );
+          continue;
+        }
+        for ( idx = 0; idx < count; idx++ ) {
+          if ( (err = switch_read( handle, idx, &pcm_switch )) < 0 ) {
+            printf( "PCM %s switch read error: %s\n", str, snd_strerror( count ) );
+            continue;
+          }
+          printf( "PCM switch: '%s' %s (%i-%i)\n", pcm_switch.name, get_type( pcm_switch.type ), pcm_switch.low, pcm_switch.high );
+          if ( (err = switch_write( handle, idx, &pcm_switch )) < 0 ) {
+            printf( "PCM %s switch write error: %s\n", str, snd_strerror( count ) );
+            continue;
+          }
+        }
+        if ( count <= 0 )
+          printf( "No PCM %s switches detected for soundcard #%i/#%i '%s'/'%s'...\n", str, idx, device, info.name, pcm_info.name );
+        snd_pcm_close( handle );
+      }
+    }
+    snd_ctl_close( chandle );
+  }  
+
+  /* rawmidi switches */
+  for ( card = 0; card < cards; card++ ) {
+    if ( (err = snd_ctl_open( &chandle, card )) < 0 ) {
+      printf( "CTL open error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    if ( (err = snd_ctl_hw_info( chandle, &info )) < 0 ) {
+      printf( "CTL hw info error: %s\n", snd_strerror( err ) );
+      continue;
+    }
+    for ( device = 0; device < info.mididevs; device++ ) {
+      if ( (err = snd_ctl_rawmidi_info( chandle, device, &rmidi_info )) < 0 ) {
+        printf( "CTL RawMIDI info error: %s\n", snd_strerror( err ) );
+        continue;
+      }
+      for ( direction = 0; direction < 2; direction++ ) {
+        int (*switches)( void *handle );
+        int (*switch_read)( void *handle, int switchn, snd_rawmidi_switch_t *data );
+        int (*switch_write)( void *handle, int switchn, snd_rawmidi_switch_t *data );
+        char *str;
+
+        if ( !(pcm_info.flags & (!direction ? SND_RAWMIDI_INFO_OUTPUT : SND_RAWMIDI_INFO_INPUT)) ) continue;
+        if ( (err = snd_rawmidi_open( &handle, card, device, !direction ? SND_RAWMIDI_OPEN_OUTPUT : SND_RAWMIDI_OPEN_INPUT )) < 0 ) {
+          printf( "RawMIDI CTL open error: %s\n", snd_strerror( err ) );
+          continue;
+        }
+        if ( !direction ) {
+          switches = snd_rawmidi_output_switches;
+          switch_read = snd_rawmidi_output_switch_read;
+          switch_write = snd_rawmidi_output_switch_write;
+          str = "output";
+        } else {
+          switches = snd_rawmidi_input_switches;
+          switch_read = snd_rawmidi_input_switch_read;
+          switch_write = snd_rawmidi_input_switch_write;
+          str = "input";
+        }
+        if ( (count = switches( handle )) < 0 ) {
+          printf( "RawMIDI %s switches error: %s\n", str, snd_strerror( count ) );
+          continue;
+        }
+        for ( idx = 0; idx < count; idx++ ) {
+          if ( (err = switch_read( handle, idx, &rmidi_switch )) < 0 ) {
+            printf( "RawMIDI %s switch read error: %s\n", str, snd_strerror( count ) );
+            continue;
+          }
+          printf( "RawMIDI switch: '%s' %s (%i-%i)\n", rmidi_switch.name, get_type( rmidi_switch.type ), rmidi_switch.low, rmidi_switch.high );
+          if ( (err = switch_write( handle, idx, &rmidi_switch )) < 0 ) {
+            printf( "RawMIDI %s switch write error: %s\n", str, snd_strerror( count ) );
+            continue;
+          }
+        }
+        if ( count <= 0 )
+          printf( "No RawMIDI %s switches detected for soundcard #%i/#%i '%s'/'%s'...\n", str, idx, device, info.name, rmidi_info.name );
+        snd_rawmidi_close( handle );
+      }
+    }
+    snd_ctl_close( chandle );
+  }  
+
+}