From ef615c857ffb1712c5c0c403df58a796efc41bfc Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 27 Aug 1998 20:47:51 +0000 Subject: [PATCH] Added switches API and rawmidi API... --- CHANGELOG | 6 + Makefile | 6 +- configure.in | 4 +- include/control.h | 4 + include/pcm.h | 4 + include/version.h | 4 +- src/Makefile | 12 +- src/control/control.c | 60 ++++++++- src/mixer/mixer.c | 2 +- src/pcm/pcm.c | 76 +++++++++++- src/rawmidi/Makefile | 40 ++++++ src/rawmidi/rawmidi.c | 274 ++++++++++++++++++++++++++++++++++++++++++ version | 2 +- 13 files changed, 481 insertions(+), 13 deletions(-) create mode 100644 src/rawmidi/Makefile create mode 100644 src/rawmidi/rawmidi.c diff --git a/CHANGELOG b/CHANGELOG index a5aec85f..1a1ddb8e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +0.0.9 -> 0.1.0 + +* big API changes + - added switches interfaces +* added RawMIDI API + 0.0.8 -> 0.0.9 * Makefile and configure.in changes diff --git a/Makefile b/Makefile index 36f46d31..7b306702 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,10 @@ all: include/soundlib.h @echo include/soundlib.h: include/header.h include/version.h include/error.h include/footer.h \ - include/control.h include/mixer.h include/pcm.h + include/control.h include/mixer.h include/pcm.h include/rawmidi.h cat include/header.h include/version.h include/error.h \ include/control.h include/mixer.h \ - include/pcm.h \ + include/pcm.h include/rawmidi.h \ include/footer.h > include/soundlib.h install: all @@ -46,7 +46,7 @@ clean: cvsclean: clean rm -f configure config.cache config.log config.status Makefile.conf \ - utils/alsa-lib.spec + utils/alsa-lib.spec include/config.h include/soundlib.h pack: cvsclean chown -R root.root ../alsa-lib diff --git a/configure.in b/configure.in index 8306e15e..5fb3db4e 100644 --- a/configure.in +++ b/configure.in @@ -35,7 +35,7 @@ AC_TRY_RUN([ #include void main(void) { -#ifndef SND_PROTOCOL_VERSION +#if !defined( SND_PROTOCOL_VERSION ) || !defined( SND_PROTOCOL_UNCOMPATIBLE ) exit(1); #else exit(0); @@ -43,7 +43,7 @@ void main(void) } ], AC_MSG_RESULT("present"), - AC_MSG_RESULT("not found"); echo "Fatal error: Install alsa-driver package at first..."; exit 1;, + AC_MSG_RESULT("not found"); echo "Fatal error: Install alsa-driver v0.2.0pre6+ package at first..."; exit 1;, AC_MSG_RESULT("not supported"); echo "Fatal error: Cross-compiling isn't supported..."; exit 1;, ) diff --git a/include/control.h b/include/control.h index 56114990..b923ea9a 100644 --- a/include/control.h +++ b/include/control.h @@ -17,6 +17,10 @@ int snd_ctl_open( void **handle, int card ); int snd_ctl_close( void *handle ); int snd_ctl_file_descriptor( void *handle ); int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info ); +int snd_ctl_switches( void *handle ); +int snd_ctl_switch( void *handle, const char *channel_id ); +int snd_ctl_switch_read( void *handle, int switchn, struct snd_ctl_switch *data ); +int snd_ctl_switch_write( void *handle, int switchn, struct snd_ctl_switch *data ); 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 ); diff --git a/include/pcm.h b/include/pcm.h index 6eb55f7c..b90e3577 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -20,6 +20,10 @@ 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_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/version.h b/include/version.h index 8c777ae7..a4ee0a42 100644 --- a/include/version.h +++ b/include/version.h @@ -3,7 +3,7 @@ */ #define SOUNDLIB_VERSION_MAJOR 0 -#define SOUNDLIB_VERSION_MINOR 0 -#define SOUNDLIB_VERSION_SUBMINOR 10 +#define SOUNDLIB_VERSION_MINOR 1 +#define SOUNDLIB_VERSION_SUBMINOR 0 #define SOUNDLIB_VERSION ( ( LIBULTRA_VERSION_MAJOR << 16 ) | ( LIBULTRA_VERSION_MINOR << 8 ) | LIB_ULTRA_VERSION_SUBMINOR ) diff --git a/src/Makefile b/src/Makefile index 1eadfae3..166426ca 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,10 +13,12 @@ TARGETS=$(TARGET) $(STARGET) STATIC_LIBS= control/libcontrol.a \ mixer/libmixer.a \ - pcm/libpcm.a + pcm/libpcm.a \ + rawmidi/librawmidi.a DYNAMIC_LIBS= control/libcontrol.Sa \ mixer/libmixer.Sa \ - pcm/libpcm.Sa + pcm/libpcm.Sa \ + rawmidi/librawmidi.Sa OBJECTS=error.o SOBJECTS=error.So @@ -56,10 +58,16 @@ pcm/libpcm.a: pcm/libpcm.sa: $(MAKE) -C pcm +rawmidi/librawmidi.a: + $(MAKE) -C rawmidi +rawmidi/librawmidi.sa: + $(MAKE) -C rawmidi + clean: $(MAKE) -C control clean $(MAKE) -C pcm clean $(MAKE) -C mixer clean + $(MAKE) -C rawmidi clean rm -f core .depend *.o *.So *.orig *~ rm -f ../lib/libsound.* diff --git a/src/control/control.c b/src/control/control.c index a46ca0fc..3bb498b7 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -22,12 +22,13 @@ #include #include #include +#include #include #include #include #include "soundlib.h" -#define SND_FILE_CONTROL "/dev/sndcontrol%i" +#define SND_FILE_CONTROL "/dev/snd/control%i" #define SND_CTL_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 ) typedef struct { @@ -94,6 +95,63 @@ int snd_ctl_hw_info( void *handle, struct snd_ctl_hw_info *info ) return 0; } +int snd_ctl_switches( void *handle ) +{ + snd_ctl_t *ctl; + int result; + + ctl = (snd_ctl_t *)handle; + if ( !ctl ) return -EINVAL; + if ( ioctl( ctl -> fd, SND_CTL_IOCTL_SWITCHES, &result ) < 0 ) + return -errno; + return result; +} + +int snd_ctl_switch( void *handle, const char *switch_id ) +{ + snd_ctl_t *ctl; + struct snd_ctl_switch uswitch; + int idx, switches, err; + + ctl = (snd_ctl_t *)handle; + if ( !ctl ) return -EINVAL; + /* bellow implementation isn't optimized for speed */ + /* info about switches should be cached in the snd_mixer_t structure */ + if ( (switches = snd_ctl_switches( handle )) < 0 ) + return switches; + for ( idx = 0; idx < switches; idx++ ) { + if ( (err = snd_ctl_switch_read( handle, idx, &uswitch )) < 0 ) + return err; + if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) ) + return idx; + } + return -EINVAL; +} + +int snd_ctl_switch_read( void *handle, int switchn, struct snd_ctl_switch *data ) +{ + snd_ctl_t *ctl; + + ctl = (snd_ctl_t *)handle; + if ( !ctl ) return -EINVAL; + data -> switchn = switchn; + if ( ioctl( ctl -> fd, SND_CTL_IOCTL_SWITCH_READ, data ) < 0 ) + return -errno; + return 0; +} + +int snd_ctl_switch_write( void *handle, int switchn, struct snd_ctl_switch *data ) +{ + snd_ctl_t *ctl; + + ctl = (snd_ctl_t *)handle; + if ( !ctl ) return -EINVAL; + data -> switchn = switchn; + if ( ioctl( ctl -> fd, SND_CTL_IOCTL_SWITCH_WRITE, data ) < 0 ) + return -errno; + return 0; +} + int snd_ctl_pcm_info( void *handle, int dev, snd_pcm_info_t *info ) { snd_ctl_t *ctl; diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index 1cc3aefa..430a133c 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -28,7 +28,7 @@ #include #include "soundlib.h" -#define SND_FILE_MIXER "/dev/sndmixer%i%i" +#define SND_FILE_MIXER "/dev/snd/mixer%i%i" #define SND_MIXER_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 1 ) typedef struct { diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index ffbc3658..70753914 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -1,17 +1,34 @@ /* * PCM Interface - main file * Copyright (c) 1998 by Jaroslav Kysela + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * */ #include #include #include +#include #include #include #include #include "soundlib.h" -#define SND_FILE_PCM "/dev/sndpcm%i%i" +#define SND_FILE_PCM "/dev/snd/pcm%i%i" #define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 ) typedef struct { @@ -120,6 +137,63 @@ int snd_pcm_record_info( void *handle, snd_pcm_record_info_t *info ) return 0; } +int snd_pcm_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 ) + return -errno; + return result; +} + +int snd_pcm_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_mixer_switches( handle )) < 0 ) + return switches; + for ( idx = 0; idx < switches; idx++ ) { + if ( (err = snd_pcm_switch_read( handle, idx, &uswitch )) < 0 ) + return err; + if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) ) + return idx; + } + return -EINVAL; +} + +int snd_pcm_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 ) + return -errno; + return 0; +} + +int snd_pcm_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 ) + return -errno; + return 0; +} + int snd_pcm_playback_format( void *handle, snd_pcm_format_t *format ) { snd_pcm_t *pcm; diff --git a/src/rawmidi/Makefile b/src/rawmidi/Makefile new file mode 100644 index 00000000..c675bf4a --- /dev/null +++ b/src/rawmidi/Makefile @@ -0,0 +1,40 @@ +# +# Makefile for ALSA library +# Copyright (c) 1994-98 by Jaroslav Kysela +# + +include ../../Makefile.conf + +TARGET=librawmidi.a +STARGET=librawmidi.Sa +OBJECTS=rawmidi.o +SOBJECTS=rawmidi.So +TARGETS=$(TARGET) $(STARGET) + +.SUFFIXES: .c .s .S .o .So .a .Sa + +.c.o: + $(CC) $(COPTS) $(INCLUDE) -c -o $*.o $< +.c.So: + $(CC) $(COPTS) $(INCLUDE) -fPIC -c -o $*.So $< + +all: $(TARGETS) + +$(TARGET): .depend $(OBJECTS) + $(LINKER) -r -o $@ $(OBJECTS) + +$(STARGET): .depend $(SOBJECTS) + $(LINKER) -r -o $@ $(SOBJECTS) + +clean: + rm -f core .depend *.o *.So *.a *.Sa *.orig *~ + +.depend: + $(CPP) $(COPTS) $(INCLUDE) -M *.c > .depend + +# +# include a dependency file if one exists +# +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c new file mode 100644 index 00000000..8566c4be --- /dev/null +++ b/src/rawmidi/rawmidi.c @@ -0,0 +1,274 @@ +/* + * RawMIDI Interface - main file + * Copyright (c) 1998 by Jaroslav Kysela + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "soundlib.h" + +#define SND_FILE_RAWMIDI "/dev/snd/rawmidi%i%i" +#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 ) + +typedef struct { + int card; + int device; + int fd; +} snd_rawmidi_t; + +int snd_rawmidi_open( void **handle, int card, int device, int mode ) +{ + int fd, ver; + char filename[32]; + snd_rawmidi_t *rmidi; + + *handle = NULL; + 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 ) { + close( fd ); + return -errno; + } + if ( SND_PROTOCOL_UNCOMPATIBLE( ver, SND_PCM_VERSION_MAX ) ) + return -SND_ERROR_UNCOMPATIBLE_VERSION; + rmidi = (snd_rawmidi_t *)calloc( 1, sizeof( snd_rawmidi_t ) ); + if ( rmidi == NULL ) { + close( fd ); + return -ENOMEM; + } + rmidi -> card = card; + rmidi -> device = device; + rmidi -> fd = fd; + *handle = rmidi; + return 0; +} + +int snd_rawmidi_close( void *handle ) +{ + snd_rawmidi_t *rmidi; + int res; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + res = close( rmidi -> fd ) < 0 ? -errno : 0; + free( rmidi ); + return res; +} + +int snd_rawmidi_file_descriptor( void *handle ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + return rmidi -> fd; +} + +int snd_rawmidi_block_mode( void *handle, int enable ) +{ + snd_rawmidi_t *rmidi; + long flags; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( fcntl( rmidi -> fd, F_GETFL, &flags ) < 0 ) + return -errno; + if ( enable ) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + if ( fcntl( rmidi -> fd, F_SETFL, &flags ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_info( void *handle, snd_rawmidi_info_t *info ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_INFO, info ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_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 ) + return -errno; + return result; +} + +int snd_rawmidi_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_switches( handle )) < 0 ) + return switches; + for ( idx = 0; idx < switches; idx++ ) { + if ( (err = snd_rawmidi_switch_read( handle, idx, &uswitch )) < 0 ) + return err; + if ( !strncmp( switch_id, uswitch.name, sizeof( uswitch.name ) ) ) + return idx; + } + return -EINVAL; +} + +int snd_rawmidi_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 ) + return -errno; + return 0; +} + +int snd_rawmidi_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 ) + return -errno; + return 0; +} + +int snd_rawmidi_output_params( void *handle, snd_rawmidi_output_params_t *params ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_OUTPUT_PARAMS, params ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_input_params( void *handle, snd_rawmidi_input_params_t *params ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_INPUT_PARAMS, params ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_output_status( void *handle, snd_rawmidi_output_status_t *status ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_OUTPUT_STATUS, status ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_input_status( void *handle, snd_rawmidi_input_status_t *status ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_INPUT_STATUS, status ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_drain_output( void *handle ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_DRAIN_OUTPUT ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_flush_output( void *handle ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_FLUSH_OUTPUT ) < 0 ) + return -errno; + return 0; +} + +int snd_rawmidi_flush_input( void *handle ) +{ + snd_rawmidi_t *rmidi; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + if ( ioctl( rmidi -> fd, SND_RAWMIDI_IOCTL_FLUSH_INPUT ) < 0 ) + return -errno; + return 0; +} + +ssize_t snd_rawmidi_write( void *handle, const void *buffer, size_t size ) +{ + snd_rawmidi_t *rmidi; + ssize_t result; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + result = write( rmidi -> fd, buffer, size ); + if ( result < 0 ) return -errno; + return result; +} + +ssize_t snd_rawmidi_read( void *handle, void *buffer, size_t size ) +{ + snd_rawmidi_t *rmidi; + ssize_t result; + + rmidi = (snd_rawmidi_t *)handle; + if ( !rmidi ) return -EINVAL; + result = read( rmidi -> fd, buffer, size ); + if ( result < 0 ) return -errno; + return result; +} diff --git a/version b/version index 7c1886bb..6e8bf73a 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.0.10 +0.1.0 -- 2.47.1