From e3aad51c38f8e3b483a0bba7154d9c1417dcc090 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 28 Aug 1998 14:04:48 +0000 Subject: [PATCH] Updated switches interfaces. --- Makefile | 2 +- include/control.h | 1 + include/header.h | 1 + include/pcm.h | 12 ++- include/rawmidi.h | 12 ++- src/control/control.c | 13 +++ src/pcm/pcm.c | 75 ++++++++++++-- src/rawmidi/rawmidi.c | 79 ++++++++++++--- test/Makefile | 5 +- test/switches.c | 224 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 394 insertions(+), 30 deletions(-) create mode 100644 test/switches.c diff --git a/Makefile b/Makefile index 7b306702..7e467fe4 100644 --- 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 diff --git a/include/control.h b/include/control.h index b923ea9a..e2e0f8b7 100644 --- a/include/control.h +++ b/include/control.h @@ -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 } diff --git a/include/header.h b/include/header.h index f0cab83e..3bf18124 100644 --- a/include/header.h +++ b/include/header.h @@ -24,4 +24,5 @@ #include #include +#include diff --git a/include/pcm.h b/include/pcm.h index b90e3577..fc55f174 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -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 ); diff --git a/include/rawmidi.h b/include/rawmidi.h index c86e63c0..acc391b9 100644 --- a/include/rawmidi.h +++ b/include/rawmidi.h @@ -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 ); diff --git a/src/control/control.c b/src/control/control.c index 3bb498b7..2e98b3df 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -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; +} diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 70753914..15c5d9ed 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -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; } diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c index 8566c4be..016541e6 100644 --- a/src/rawmidi/rawmidi.c +++ b/src/rawmidi/rawmidi.c @@ -28,7 +28,7 @@ #include #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; } diff --git a/test/Makefile b/test/Makefile index 80a99a57..e4d9d68a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -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 index 00000000..f8992c28 --- /dev/null +++ b/test/switches.c @@ -0,0 +1,224 @@ +#include +#include +#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 ); + } + +} -- 2.47.1