From: Jaroslav Kysela Date: Thu, 12 Feb 2004 17:16:07 +0000 (+0000) Subject: - fixed oss wrapper mixer open bug (missing code) X-Git-Tag: v1.0.3~30 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=de966f7484d55459c38362275ef5a52b818e4111;p=alsa-oss.git - fixed oss wrapper mixer open bug (missing code) - added lmixer to test directory - ported mmap_test to use oss redirector - don't compile code != libalsatoss with -lasound --- diff --git a/Makefile.am b/Makefile.am index 15f8ded..0e5db3b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ else ALSA_DIR = endif -SUBDIRS = $(ALSA_DIR) oss-redir +SUBDIRS = $(ALSA_DIR) oss-redir test dist-hook: echo $(VERSION) >> version diff --git a/alsa/Makefile.am b/alsa/Makefile.am index c1fa9ff..bf47e9a 100644 --- a/alsa/Makefile.am +++ b/alsa/Makefile.am @@ -6,8 +6,10 @@ EXTRA_DIST = aoss.1 libaoss_la_SOURCES = alsa-oss.c libaoss_la_LIBADD = -ldl -lalsatoss +libalsatoss_la_CFLAGS = @ALSA_CFLAGS@ libalsatoss_la_SOURCES = pcm.c mixer.c -libalsatoss_la_LIBADD = -lasound +libalsatoss_la_LDADD = @ALSA_LDFLAGS@ +libalsatoss_la_LIBADD = @ALSA_LIBS@ clean: rm -f aoss diff --git a/alsa/alsa-oss.c b/alsa/alsa-oss.c index cd20968..8350755 100644 --- a/alsa/alsa-oss.c +++ b/alsa/alsa-oss.c @@ -71,7 +71,6 @@ typedef enum { static ops_t ops[FD_CLASSES]; typedef struct { - int count; fd_class_t class; void *mmap_area; } fd_t; @@ -205,7 +204,15 @@ int open(const char *file, int oflag, ...) } } else if (!strncmp(file, "/dev/mixer", 10)) { fd = lib_oss_mixer_open(file, oflag); - fds[fd]->class = FD_OSS_MIXER; + if (fd >= 0) { + fds[fd] = calloc(sizeof(fd_t), 1); + if (fds[fd] == NULL) { + ops[FD_OSS_MIXER].close(fd); + errno = ENOMEM; + return -1; + } + fds[fd]->class = FD_OSS_MIXER; + } } else { fd = _open(file, oflag, mode); if (fd >= 0) diff --git a/alsa/testaoss.in b/alsa/testaoss.in new file mode 100644 index 0000000..bd21825 --- /dev/null +++ b/alsa/testaoss.in @@ -0,0 +1,8 @@ +#!/bin/sh + +# A simple script to facilitate the use of the OSS compatibility library. +# Usage: +# testaoss + +prefix=@top_srcdir@ +ALSA_OSS_WRAPPER=1 LD_PRELOAD=${prefix}/alsa/.libs/libaoss.so $* diff --git a/configure.in b/configure.in index e7e9054..fef3694 100644 --- a/configure.in +++ b/configure.in @@ -21,7 +21,20 @@ fi AM_CONDITIONAL(WITH_AOSS, test x$with_aoss = xyes) if test "$with_aoss" = "yes"; then + OLD_CFLAGS=$CFLAGS ; CFLAGS="" + OLD_LDFLAGS=$LDFLAGS ; LDFLAGS="" + OLD_LIBS=$LIBS ; LIBS="" AM_PATH_ALSA(0.9.0) + ALSA_CFLAGS=$CFLAGS + ALSA_LDFLAGS=$LDFLAGS + ALSA_LIBS=$LIBS + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LDFLAGS) + AC_SUBST(ALSA_LIBS) + CFLAGS=$OLD_CFLAGS + LDFLAGS=$OLD_LDFLAGS + LIBS=$OLD_LIBS fi -AC_OUTPUT(Makefile alsa/Makefile alsa/aoss oss-redir/Makefile) +AC_OUTPUT(Makefile alsa/Makefile alsa/aoss oss-redir/Makefile test/Makefile \ + alsa/testaoss test/testaoss) diff --git a/oss-redir/Makefile.am b/oss-redir/Makefile.am index d97e4de..0b92336 100644 --- a/oss-redir/Makefile.am +++ b/oss-redir/Makefile.am @@ -1,4 +1,4 @@ -ossredirincludedir = ${includedir} +ossredirincludedir = ${includedir}/sound ossredirinclude_HEADERS = oss-redir.h diff --git a/oss-redir/oss-redir.c b/oss-redir/oss-redir.c index 4bb44ce..d3128be 100644 --- a/oss-redir/oss-redir.c +++ b/oss-redir/oss-redir.c @@ -44,6 +44,7 @@ static void initialize(void); static int (*x_oss_pcm_open)(const char *pathname, int flags); static int (*x_oss_pcm_close)(int fd); +int (*oss_pcm_nonblock)(int fd, int nonblock); ssize_t (*oss_pcm_read)(int fd, void *buf, size_t count); ssize_t (*oss_pcm_write)(int fd, const void *buf, size_t count); void * (*oss_pcm_mmap)(void *start, size_t length, int prot, int flags, int fd, off_t offset); diff --git a/oss-redir/oss-redir.h b/oss-redir/oss-redir.h index 2d821ce..53c40e4 100644 --- a/oss-redir/oss-redir.h +++ b/oss-redir/oss-redir.h @@ -29,6 +29,10 @@ struct pollfd; #define OSS_WAIT_EVENT_WRITE (1<<1) #define OSS_WAIT_EVENT_ERROR (1<<2) +#ifdef __cplusplus +extern "C" { +#endif + extern int oss_pcm_open(const char *pathname, int flags, ...); extern int oss_pcm_close(int fd); extern int (*oss_pcm_nonblock)(int fd, int nonblock); @@ -47,5 +51,8 @@ extern int oss_mixer_open(const char *pathname, int flags, ...); extern int oss_mixer_close(int fd); extern int (*oss_mixer_ioctl)(int fd, unsigned long int request, ...); +#ifdef __cplusplus +} +#endif #endif /* __OSS_REDIR_H */ diff --git a/test/Makefile.am b/test/Makefile.am index 8e9103a..db59818 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,8 @@ -check_PROGRAMS=mmap_test mmap_test_redir +check_PROGRAMS=mmap_test lmixer -mmap_test_redir_LDADD=../oss-redir/libossredir.la +mmap_test_LDADD=../oss-redir/libossredir.la +lmixer_LDADD=../oss-redir/libossredir.la +lmixer_SOURCES=lmixer.cc INCLUDES=-I$(top_srcdir)/oss-redir CFLAGS=-static -Wall -pipe -g diff --git a/test/lmixer.cc b/test/lmixer.cc new file mode 100644 index 0000000..78bc2f6 --- /dev/null +++ b/test/lmixer.cc @@ -0,0 +1,278 @@ +// lmixer +// +// Written by Brandon Zehm +// caspian@linuxfreak.com +// +// This software is released under the GNU GPL license. +// For details see http://www.gnu.org/copyleft/gpl.html +// +// If you have patches, suggestions, comments, or anything +// else to tell me, please feel free to email me. +// + +#define MIXERVERSION "1.0.7" +#define MIXERDEV "/dev/mixer" + +#include +#include +#include +#include +#include "mixctl.h" + + +// Initialize functions +void help(); +void version(); +void scanArgs(int argc, char **argv); +void ShowChannelInfo(); +int VerifyChannelName(); +int open_mixer(); + + +// Define Variables +char mixdev[256]=MIXERDEV; // The var with the mixer device +int volume=255; // Set volume to a value out of range +int channel=255; // Set channel to a value out of range +char channel_name[32]="BLANK"; // + +// Initialize interface to mixer.h +MixCtl *mixctl; + + + + + + +//////////////////////////////////////////////////////// +// Sub: main() +// Input: argc and **argv +//////////////////////////////////////////////////////// +int main(int argc, char **argv) +{ + // Get command line parameters. + scanArgs(argc, argv); + + // If neither the volume or the channel got set print help. + if ((volume == 255) && (channel == 255)) { + help(); + exit(1); + } + + // Check to see if the volume got set + if (volume == 255) { + printf ("You must set a volume!\n"); + help(); + exit(1); + } + + // Check to see if the volume got set + if(strcmp(channel_name, "BLANK")==0) { + printf ("You must set a mixer channel!\n"); + help(); + exit(1); + } + + + // If we get here we assume we are doing the defualt operation + // which is: + // 1. open mixer + // 2. write volume to a channel + // 3. quit + + + // Open the mixer or die + if (open_mixer() != 1) { + exit(1); + } + + // Verify that the incoming channel_name is valid + // and set 'channel' to the corresponding channel number. + if (VerifyChannelName() == 0) { + printf("\'%s\' is not a valid channel name!\n", channel_name); + exit(1); + } + + // Write the volume + mixctl->setBoth(channel,volume,volume); + mixctl->writeVol(channel); + + + // Exit + delete mixctl; + return 0; +} + + + + + + + + + + +//////////////////////////////////////////////////////// +// Sub: scanArgs() +// Input: argc and *argv +// Output: Sets initial variables +// Description: Receives incoming data and directs +// the flow of the program. +//////////////////////////////////////////////////////// +void scanArgs(int argc, char *argv[]){ + for(int i=1;i Mixer channel to adjust \n"); + printf(" -v,--volume Volume (1-100) \n"); + printf(" -d,--device Use specified mixer device \n"); + printf(" -i,--info Shows the volume of each mixer device \n"); + printf(" -V,--version Display version information \n"); + printf(" -h,--help Display this help screen \n"); + printf(" \n"); + printf("Typical useage: 'lmixer -c bass -v 85' \n"); + printf("\n"); +} + + + +////////////////////////////////////////////////////////// +// Sub: version() +// Input: void +// Description: Prints version informaion +///////////////////////////////////////////////////////// +void version() { + printf("lmixer version %s\n", MIXERVERSION); +} + + + + +//////////////////////////////////////////////////////// +// Sub: open_mixer() +// Input: int +// Output: Returns 1 on success 0 on failure. +// Description: Opens the mixer device or dies. +//////////////////////////////////////////////////////// +int open_mixer () { + // Open the mixer, and verify it worked. + mixctl=new MixCtl(mixdev); + if(!mixctl->openOK()) { + fprintf(stdout,"Unable to open mixer device: %s\n", mixdev); + return(0); + } + return(1); +} + + + + + + +//////////////////////////////////////////////////////// +// Sub: ShowChannelInfo() +// Input: void +// Output: STDOUT +// Description: Shows a list of channels and their +// current volumes. +//////////////////////////////////////////////////////// +void ShowChannelInfo () { + for (int i = 0; i < mixctl->getNrDevices(); i++) { // For every device, + if (mixctl->getSupport(i)) { // if the device exists, + volume = mixctl->readVol(i,1); // Get the volume + printf ("%s\t%d\n", mixctl->getName(i), volume); // and print a line. + } + } +} + + + +//////////////////////////////////////////////////////// +// Sub: VerifyChannelName() +// Input: Reads global var channel_name +// Output: returns a 1 on success 0 on failure +// Description: Checks to see if 'channel_name' is +// a valid mixer device, and if it +// is it sets 'channel' to the number of +// that device. +//////////////////////////////////////////////////////// +int VerifyChannelName () { + for (int i = 0; i < mixctl->getNrDevices(); i++) { // For every device, + if (mixctl->getSupport(i)) { // if the device exists, + if(strcmp(channel_name, mixctl->getName(i))==0) { + channel = i; + return 1; + } + } + } + return 0; +} + + + + + + + + + + diff --git a/test/mixctl.h b/test/mixctl.h new file mode 100644 index 0000000..ea6f652 --- /dev/null +++ b/test/mixctl.h @@ -0,0 +1,207 @@ +// mixctl.h - MixCtl class provides control of audio mixer functions +// 05/09/98 Release 1.0 Beta1 +// Copyright (C) 1998 Sam Hawker +// This software comes with ABSOLUTELY NO WARRANTY +// This software is free software, and you are welcome to redistribute it. + +// Although mixctl.h is an integral part of lmixer, it may also be distributed seperately. + +#include +#include +#include +#include +#include +#include +#include +#ifdef __NetBSD__ +#include +#endif +#ifdef __FreeBSD__ +#include +#endif +#ifdef __linux__ +#include +#endif +#include + +class MixCtl +{ +public: + MixCtl(char *dname){ + device=(char *)malloc(sizeof(char)*(strlen(dname)+1)); + strcpy(device,dname); + if(mixfdopen=(mixfd=oss_mixer_open(device,O_RDONLY | O_NONBLOCK))!=-1){ + nrdevices=SOUND_MIXER_NRDEVICES; + char *devnames[]=SOUND_DEVICE_NAMES; + char *devlabels[]=SOUND_DEVICE_LABELS; + if (oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_DEVMASK, &devmask)<0) + fprintf(stderr, "SOUND_MIXER_READ_DEVMASK failed\n"); + if (oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_STEREODEVS, &stmask)<0) + fprintf(stderr, "SOUND_MIXER_READ_STEREODEVS failed\n"); + if (oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_RECMASK, &recmask)<0) + fprintf(stderr, "SOUND_MIXER_READ_RECMASK failed\n"); + if (oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_CAPS, &caps)<0) + fprintf(stderr, "SOUND_MIXER_READ_CAPS failed\n"); + mixdevs=(struct MixDev *)malloc(sizeof(struct MixDev)*nrdevices); + int mixmask=1; + for(int i=0;igetSupport(dev)) { "The channel is valid" } + bool getSupport(int dev){ + return mixdevs[dev].support; + } + bool getStereo(int dev){ + return mixdevs[dev].stereo; + } + bool getRecords(int dev){ + return mixdevs[dev].records; + } + // Get the name of int dev.. + // example: printf("Channel %d's name is %s", channel, mixctl->getName(channel)); + char *getName(int dev){ + return mixdevs[dev].name; + } + char *getLabel(int dev){ + return mixdevs[dev].label; + } + +private: + int mixfd; + int mixfdopen; + char *device; + + struct MixDev{ + bool support; + bool stereo; + bool recsrc; + bool records; + char *name; + char *label; + int value; + int mask; + }; + + int nrdevices; // maximum number of devices + int devmask; // supported devices + int stmask; // stereo devices + int recmask; // devices which can be recorded from + int caps; // capabilities + int recsrc; // devices which are being recorded from + struct MixDev *mixdevs; +}; diff --git a/test/mmap_test.c b/test/mmap_test.c index 14d972e..179225a 100644 --- a/test/mmap_test.c +++ b/test/mmap_test.c @@ -43,7 +43,7 @@ main() fd_set writeset; close(0); - if ((fd=open("/dev/dsp", O_RDWR, 0))==-1) + if ((fd=oss_pcm_open("/dev/dsp", O_RDWR, 0))==-1) { perror("/dev/dsp"); exit(-1); @@ -53,7 +53,7 @@ main() */ tmp = 48000; - ioctl(fd, SNDCTL_DSP_SPEED, &tmp); + oss_pcm_ioctl(fd, SNDCTL_DSP_SPEED, &tmp); printf("Speed set to %d\n", tmp); /* @@ -69,7 +69,7 @@ main() } else perror("smpl"); - if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps)==-1) + if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETCAPS, &caps)==-1) { perror("/dev/dsp"); fprintf(stderr, "Sorry but your sound driver is too old\n"); @@ -83,7 +83,7 @@ main() * The application should also check for DSP_CAP_MMAP bit but this * version of driver doesn't have it yet. */ -/* ioctl(fd, SNDCTL_DSP_SETSYNCRO, 0); */ +/* oss_pcm_ioctl(fd, SNDCTL_DSP_SETSYNCRO, 0); */ /* * You need version 3.5-beta7 or later of the sound driver before next @@ -104,14 +104,14 @@ main() * select call returns. */ - ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag); + oss_pcm_ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag); /* * Compute total size of the buffer. It's important to use this value * in mmap() call. */ - if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)==-1) + if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)==-1) { perror("GETOSPACE"); exit(-1); @@ -172,7 +172,7 @@ main() */ tmp = 0; - ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); + oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); printf("Trigger set to %08x\n", tmp); /* @@ -180,7 +180,7 @@ main() */ tmp = PCM_ENABLE_OUTPUT; - ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); + oss_pcm_ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); printf("Trigger set to %08x\n", tmp); /* @@ -220,7 +220,7 @@ main() * the beginning of total buffer area). */ - if (ioctl(fd, SNDCTL_DSP_GETOPTR, &count)==-1) + if (oss_pcm_ioctl(fd, SNDCTL_DSP_GETOPTR, &count)==-1) { perror("GETOPTR"); exit(-1); @@ -286,7 +286,7 @@ main() printf( ">>>> open (2)\n" ); fflush( stdout ); - if ((fd=open("/dev/dsp", O_RDWR, 0))==-1) + if ((fd=oss_pcm_open("/dev/dsp", O_RDWR, 0))==-1) { perror("/dev/dsp"); exit(-1); diff --git a/test/testaoss.in b/test/testaoss.in new file mode 100644 index 0000000..bd21825 --- /dev/null +++ b/test/testaoss.in @@ -0,0 +1,8 @@ +#!/bin/sh + +# A simple script to facilitate the use of the OSS compatibility library. +# Usage: +# testaoss + +prefix=@top_srcdir@ +ALSA_OSS_WRAPPER=1 LD_PRELOAD=${prefix}/alsa/.libs/libaoss.so $*