Merged new-mixer branch...

This commit is contained in:
Jaroslav Kysela 1999-03-08 16:51:36 +00:00
parent e54aada1a6
commit c0e741dd8a
12 changed files with 307 additions and 19 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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);

28
include/timer.h Normal file
View file

@ -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

View file

@ -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:

View file

@ -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))

View file

@ -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);
}
}

7
src/timer/Makefile.am Normal file
View file

@ -0,0 +1,7 @@
EXTRA_LTLIBRARIES=libtimer.la
libtimer_la_SOURCES = timer.c
all: libtimer.la
INCLUDES=-I$(top_srcdir)/include

163
src/timer/timer.c Normal file
View file

@ -0,0 +1,163 @@
/*
* Timer Interface - main file
* Copyright (c) 1998 by Jaroslav Kysela <perex@jcu.cz>
*
*
* 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#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;
}

View file

@ -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

21
test/timer.c Normal file
View file

@ -0,0 +1,21 @@
#include <stdio.h>
#include <string.h>
#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);
}