From c0e741dd8a33736584b8ac70b04e41c21dcb171b Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 8 Mar 1999 16:51:36 +0000 Subject: [PATCH] Merged new-mixer branch... --- acinclude.m4 | 2 +- configure.in | 2 +- include/Makefile.am | 2 +- include/mixer.h | 12 +++- include/timer.h | 28 ++++++++ src/Makefile.am | 4 +- src/control/cards.c | 7 +- src/mixer/mixer.c | 75 +++++++++++++++++-- src/timer/Makefile.am | 7 ++ src/timer/timer.c | 163 ++++++++++++++++++++++++++++++++++++++++++ test/Makefile.am | 3 +- test/timer.c | 21 ++++++ 12 files changed, 307 insertions(+), 19 deletions(-) create mode 100644 include/timer.h create mode 100644 src/timer/Makefile.am create mode 100644 src/timer/timer.c create mode 100644 test/timer.c diff --git a/acinclude.m4 b/acinclude.m4 index d38c7e97..cd289edc 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -16,7 +16,7 @@ void main(void) #if !defined(SND_PROTOCOL_VERSION) || !defined(SND_PROTOCOL_UNCOMPATIBLE) #error not found #else -#if !defined(SND_MIXER_IOCTL_CHANNEL_RREAD) +#if !defined(SND_MIXER_IOCTL_CHANNEL_IREAD) #error wrong version #endif exit(0); diff --git a/configure.in b/configure.in index 20985456..f0e940c1 100644 --- a/configure.in +++ b/configure.in @@ -30,6 +30,6 @@ SAVE_LIBRARY_VERSION AC_OUTPUT(Makefile doc/Makefile include/Makefile src/Makefile \ src/control/Makefile src/mixer/Makefile src/pcm/Makefile \ - src/rawmidi/Makefile src/seq/Makefile \ + src/rawmidi/Makefile src/timer/Makefile src/seq/Makefile \ test/Makefile utils/Makefile \ utils/alsa-lib.spec) diff --git a/include/Makefile.am b/include/Makefile.am index 5ab4ab4c..c83244d3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -4,7 +4,7 @@ sysinclude_HEADERS = asoundlib.h # This is the order they will be concatenated into asoundlib.h! # header_files=header.h version.h error.h control.h mixer.h pcm.h rawmidi.h \ - seq.h footer.h + timer.h seq.h footer.h noinst_HEADERS=$(header_files) diff --git a/include/mixer.h b/include/mixer.h index 9de2b7af..e2db9164 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -8,8 +8,10 @@ typedef struct snd_mixer_callbacks { void *private_data; /* should be used by application */ void (*channel_was_changed) (void *private_data, int channel); + void (*output_channel_was_changed) (void *private_data, int channel); + void (*input_channel_was_changed) (void *private_data, int channel); void (*switch_was_changed) (void *private_data, int switchn); - void *reserved[14]; /* reserved for future use - must be NULL!!! */ + void *reserved[15]; /* reserved for future use - must be NULL!!! */ } snd_mixer_callbacks_t; #ifdef __cplusplus @@ -24,10 +26,14 @@ int snd_mixer_info(void *handle, snd_mixer_info_t * info); int snd_mixer_exact_mode(void *handle, int enable); int snd_mixer_channel(void *handle, const char *channel_id); int snd_mixer_channel_info(void *handle, int channel, snd_mixer_channel_info_t * info); +int snd_mixer_channel_output_info(void *handle, int channel, snd_mixer_channel_direction_info_t * info); +int snd_mixer_channel_input_info(void *handle, int channel, snd_mixer_channel_direction_info_t * info); int snd_mixer_channel_read(void *handle, int channel, snd_mixer_channel_t * data); int snd_mixer_channel_write(void *handle, int channel, snd_mixer_channel_t * data); -int snd_mixer_channel_record_read(void *handle, int channel, snd_mixer_channel_t * data); -int snd_mixer_channel_record_write(void *handle, int channel, snd_mixer_channel_t * data); +int snd_mixer_channel_output_read(void *handle, int channel, snd_mixer_channel_direction_t * data); +int snd_mixer_channel_output_write(void *handle, int channel, snd_mixer_channel_direction_t * data); +int snd_mixer_channel_input_read(void *handle, int channel, snd_mixer_channel_direction_t * data); +int snd_mixer_channel_input_write(void *handle, int channel, snd_mixer_channel_direction_t * data); int snd_mixer_switches(void *handle); int snd_mixer_switch_read(void *handle, int switchn, snd_mixer_switch_t * data); int snd_mixer_switch_write(void *handle, int switchn, snd_mixer_switch_t * data); diff --git a/include/timer.h b/include/timer.h new file mode 100644 index 00000000..d0c75287 --- /dev/null +++ b/include/timer.h @@ -0,0 +1,28 @@ +/**************************************************************************** + * * + * timer.h * + * Timer interface * + * * + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +int snd_timer_open(void **handle); +int snd_timer_close(void *handle); +int snd_timer_file_descriptor(void *handle); +int snd_timer_general_info(void *handle, snd_timer_general_info_t * info); +int snd_timer_select(void *handle, snd_timer_select_t *tselect); +int snd_timer_info(void *handle, snd_timer_info_t *timer); +int snd_timer_params(void *handle, snd_timer_params_t *params); +int snd_timer_status(void *handle, snd_timer_status_t *status); +int snd_timer_start(void *handle); +int snd_timer_stop(void *handle); +int snd_timer_continue(void *handle); +ssize_t snd_timer_read(void *handle, void *buffer, size_t size); + +#ifdef __cplusplus +} +#endif + diff --git a/src/Makefile.am b/src/Makefile.am index 039fcc26..c179abc2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,9 @@ -SUBDIRS=control mixer pcm rawmidi seq +SUBDIRS=control mixer pcm rawmidi timer seq lib_LTLIBRARIES = libasound.la libasound_la_SOURCES = error.c libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \ - rawmidi/librawmidi.la seq/libseq.la + rawmidi/librawmidi.la timer/libtimer.la seq/libseq.la libasound_la_LDFLAGS = -version-info 3:0:3 control/libcontrol.la: diff --git a/src/control/cards.c b/src/control/cards.c index 6ced16b1..525e2937 100644 --- a/src/control/cards.c +++ b/src/control/cards.c @@ -37,8 +37,8 @@ int snd_card_load(int card) char control[32]; char aload[32]; - sprintf (control, SND_FILE_CONTROL, card); - sprintf (aload, SND_FILE_LOAD, card); + sprintf(control, SND_FILE_CONTROL, card); + sprintf(aload, SND_FILE_LOAD, card); if ((open_dev=open(control, O_RDONLY)) < 0) { close(open(aload, O_RDONLY)); @@ -97,7 +97,7 @@ int snd_card_name(const char *string) void *handle; struct snd_ctl_hw_info info; - if (!string) + if (!string || *string == '\0') return -EINVAL; bitmask = snd_cards_mask(); if (!bitmask) @@ -105,7 +105,6 @@ int snd_card_name(const char *string) if ((isdigit(*string) && *(string + 1) == 0) || (isdigit(*string) && isdigit(*(string + 1)) && *(string + 2) == 0)) { sscanf(string, "%i", &card); - card--; if (card < 0 || card > 31) return -EINVAL; if (card < 0 || !((1 << card) & bitmask)) diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c index 4f651b08..630e9f19 100644 --- a/src/mixer/mixer.c +++ b/src/mixer/mixer.c @@ -168,6 +168,32 @@ int snd_mixer_channel_info(void *handle, int channel, snd_mixer_channel_info_t * return 0; } +int snd_mixer_channel_output_info(void *handle, int channel, snd_mixer_channel_direction_info_t * info) +{ + snd_mixer_t *mixer; + + mixer = (snd_mixer_t *) handle; + if (!mixer || !info || channel < 0) + return -EINVAL; + info->channel = channel; + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_OINFO, info) < 0) + return -errno; + return 0; +} + +int snd_mixer_channel_input_info(void *handle, int channel, snd_mixer_channel_direction_info_t * info) +{ + snd_mixer_t *mixer; + + mixer = (snd_mixer_t *) handle; + if (!mixer || !info || channel < 0) + return -EINVAL; + info->channel = channel; + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_IINFO, info) < 0) + return -errno; + return 0; +} + int snd_mixer_channel_read(void *handle, int channel, snd_mixer_channel_t * data) { snd_mixer_t *mixer; @@ -195,7 +221,7 @@ int snd_mixer_channel_write(void *handle, int channel, snd_mixer_channel_t * dat return 0; } -int snd_mixer_channel_record_read(void *handle, int channel, snd_mixer_channel_t * data) +int snd_mixer_channel_output_read(void *handle, int channel, snd_mixer_channel_direction_t * data) { snd_mixer_t *mixer; @@ -204,12 +230,12 @@ int snd_mixer_channel_record_read(void *handle, int channel, snd_mixer_channel_t return -EINVAL; bzero(data, sizeof(snd_mixer_channel_t)); data->channel = channel; - if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_RREAD, data) < 0) + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_OREAD, data) < 0) return -errno; return 0; } -int snd_mixer_channel_record_write(void *handle, int channel, snd_mixer_channel_t * data) +int snd_mixer_channel_output_write(void *handle, int channel, snd_mixer_channel_direction_t * data) { snd_mixer_t *mixer; @@ -217,7 +243,34 @@ int snd_mixer_channel_record_write(void *handle, int channel, snd_mixer_channel_ if (!mixer || !data || channel < 0) return -EINVAL; data->channel = channel; - if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_RWRITE, data) < 0) + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_OWRITE, data) < 0) + return -errno; + return 0; +} + +int snd_mixer_channel_input_read(void *handle, int channel, snd_mixer_channel_direction_t * data) +{ + snd_mixer_t *mixer; + + mixer = (snd_mixer_t *) handle; + if (!mixer || !data || channel < 0) + return -EINVAL; + bzero(data, sizeof(snd_mixer_channel_t)); + data->channel = channel; + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_IREAD, data) < 0) + return -errno; + return 0; +} + +int snd_mixer_channel_input_write(void *handle, int channel, snd_mixer_channel_direction_t * data) +{ + snd_mixer_t *mixer; + + mixer = (snd_mixer_t *) handle; + if (!mixer || !data || channel < 0) + return -EINVAL; + data->channel = channel; + if (ioctl(mixer->fd, SND_MIXER_IOCTL_CHANNEL_IWRITE, data) < 0) return -errno; return 0; } @@ -303,10 +356,20 @@ int snd_mixer_read(void *handle, snd_mixer_callbacks_t * callbacks) for (idx = 0; idx < result; idx += 8) { cmd = *(unsigned int *) &buffer[idx]; tmp = *(unsigned int *) &buffer[idx + 4]; - if (cmd == 0 && callbacks->channel_was_changed) { + if (cmd == SND_MIXER_CHANGED && + callbacks->channel_was_changed) { callbacks->channel_was_changed(callbacks->private_data, (int) tmp); } - if (cmd == 1 && callbacks->switch_was_changed) { + if (cmd == SND_MIXER_OUTPUT_CHANGED && + callbacks->output_channel_was_changed) { + callbacks->output_channel_was_changed(callbacks->private_data, (int) tmp); + } + if (cmd == SND_MIXER_INPUT_CHANGED && + callbacks->input_channel_was_changed) { + callbacks->input_channel_was_changed(callbacks->private_data, (int) tmp); + } + if (cmd == SND_MIXER_SWITCH_CHANGED && + callbacks->switch_was_changed) { callbacks->switch_was_changed(callbacks->private_data, (int) tmp); } } diff --git a/src/timer/Makefile.am b/src/timer/Makefile.am new file mode 100644 index 00000000..f188cbfd --- /dev/null +++ b/src/timer/Makefile.am @@ -0,0 +1,7 @@ +EXTRA_LTLIBRARIES=libtimer.la + +libtimer_la_SOURCES = timer.c +all: libtimer.la + + +INCLUDES=-I$(top_srcdir)/include diff --git a/src/timer/timer.c b/src/timer/timer.c new file mode 100644 index 00000000..4158f39a --- /dev/null +++ b/src/timer/timer.c @@ -0,0 +1,163 @@ +/* + * Timer 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 "asoundlib.h" + +#define SND_FILE_TIMER "/dev/snd/timer" +#define SND_TIMER_VERSION_MAX SND_PROTOCOL_VERSION( 1, 0, 0 ) + +typedef struct { + int fd; +} snd_timer_t; + +int snd_timer_open(void **handle) +{ + int fd, ver; + snd_timer_t *tmr; + + *handle = NULL; + + if ((fd = open(SND_FILE_TIMER, O_RDONLY)) < 0) { + snd_cards_mask(); + if ((fd = open(SND_FILE_TIMER, O_RDONLY)) < 0) + return -errno; + } + if (ioctl(fd, SND_TIMER_IOCTL_PVERSION, &ver) < 0) { + close(fd); + return -errno; + } + if (SND_PROTOCOL_UNCOMPATIBLE(ver, SND_TIMER_VERSION_MAX)) { + close(fd); + return -SND_ERROR_UNCOMPATIBLE_VERSION; + } + tmr = (snd_timer_t *) calloc(1, sizeof(snd_timer_t)); + if (tmr == NULL) { + close(fd); + return -ENOMEM; + } + tmr->fd = fd; + *handle = tmr; + return 0; +} + +int snd_timer_close(void *handle) +{ + snd_timer_t *tmr; + int res; + + tmr = (snd_timer_t *) handle; + if (!tmr) + return -EINVAL; + res = close(tmr->fd) < 0 ? -errno : 0; + free(tmr); + return res; +} + +int snd_timer_file_descriptor(void *handle) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr) + return -EINVAL; + return tmr->fd; +} + +int snd_timer_general_info(void *handle, snd_timer_general_info_t * info) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr || !info) + return -EINVAL; + if (ioctl(tmr->fd, SND_TIMER_IOCTL_GINFO, info) < 0) + return -errno; + return 0; +} + +int snd_timer_select(void *handle, snd_timer_select_t * tselect) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr || !tselect) + return -EINVAL; + if (ioctl(tmr->fd, SND_TIMER_IOCTL_SELECT, tselect) < 0) + return -errno; + return 0; +} + +int snd_timer_info(void *handle, snd_timer_info_t * info) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr || !info) + return -EINVAL; + if (ioctl(tmr->fd, SND_TIMER_IOCTL_INFO, info) < 0) + return -errno; + return 0; +} + +int snd_timer_params(void *handle, snd_timer_params_t * params) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr || !params) + return -EINVAL; + if (ioctl(tmr->fd, SND_TIMER_IOCTL_PARAMS, params) < 0) + return -errno; + return 0; +} + +int snd_timer_status(void *handle, snd_timer_status_t * status) +{ + snd_timer_t *tmr; + + tmr = (snd_timer_t *) handle; + if (!tmr || !status) + return -EINVAL; + if (ioctl(tmr->fd, SND_TIMER_IOCTL_STATUS, status) < 0) + return -errno; + return 0; +} + +ssize_t snd_timer_read(void *handle, void *buffer, size_t size) +{ + snd_timer_t *tmr; + ssize_t result; + + tmr = (snd_timer_t *) handle; + if (!tmr || (!buffer && size > 0) || size < 0) + return -EINVAL; + result = read(tmr->fd, buffer, size); + if (result < 0) + return -errno; + return result; +} diff --git a/test/Makefile.am b/test/Makefile.am index 3fde7b1d..77d07d3d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,4 +1,4 @@ -check_PROGRAMS=control mixer switches pause pcm latency seq playmidi1 +check_PROGRAMS=control mixer switches pause pcm latency seq playmidi1 timer control_LDADD=../src/libasound.la mixer_LDADD=../src/libasound.la @@ -8,6 +8,7 @@ pcm_LDADD=../src/libasound.la latency_LDADD=../src/libasound.la seq_LDADD=../src/libasound.la playmidi1_LDADD=../src/libasound.la +timer_LDADD=../src/libasound.la INCLUDES=-I$(top_srcdir)/include CFLAGS=-static -Wall -pipe -g diff --git a/test/timer.c b/test/timer.c new file mode 100644 index 00000000..a791f9f5 --- /dev/null +++ b/test/timer.c @@ -0,0 +1,21 @@ +#include +#include +#include "../include/asoundlib.h" + +void main(void) +{ + int err; + void *handle; + snd_timer_general_info_t info; + + if ((err = snd_timer_open(&handle))<0) { + fprintf(stderr, "timer open %i (%s)\n", err, snd_strerror(err)); + exit(0); + } + if (snd_timer_general_info(handle, &info)<0) { + fprintf(stderr, "timer general info %i (%s)\n", err, snd_strerror(err)); + exit(0); + } + printf("global timers = %i\n", info.count); + snd_timer_close(handle); +} -- 2.47.1