Audio-Mixer-0.7/0000755000175000017500000000000010175245635012525 5ustar hehe00000000000000Audio-Mixer-0.7/Changes0000644000175000017500000000070707640507631014024 0ustar hehe00000000000000Revision history for Perl extension Mixer. 0.01 Wed Mar 14 18:32:54 2001 - original version; created by h2xs 1.19 0.4 Mon Apr 29 20:46:35 2002 - bug with close_mixer() is fixed. 0.5 Sat Jan 11 09:35:00 EST 2003 - added set_mixer_dev() function to set a different device name than /dev/mixer 0.6 Fri Jan 17 13:34:09 EST 2003 - some cleanup 0.7 Wed Mar 12 13:56:16 SAST 2003 - added record source control - Mike Yudaken Audio-Mixer-0.7/MANIFEST0000644000175000017500000000012407640507557013662 0ustar hehe00000000000000Changes MANIFEST Makefile.PL Mix.c Mix.h Mixer.pm Mixer.xs test.pl volume.pl README Audio-Mixer-0.7/Makefile.PL0000644000175000017500000000102207640507557014501 0ustar hehe00000000000000use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Audio::Mixer', 'VERSION_FROM' => 'Mixer.pm', # finds $VERSION 'LIBS' => [''], # e.g., '-lm' 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' 'INC' => '', # e.g., '-I/usr/include/other' clean => {'FILES' => 'Mix.o'}, 'MYEXTLIB' => 'Mix.o', AUTHOR => "Sergey Gribov ", ABSTRACT_FROM => "Mixer.pm", ); Audio-Mixer-0.7/Mix.c0000644000175000017500000001317007640507557013437 0ustar hehe00000000000000/* * Library to query / set various sound mixer parameters. * * This code is based on setmixer program by Michal Jaegermann * * Copyright (c) 2000 Sergey Gribov * This is free software with ABSOLUTELY NO WARRANTY. * You can redistribute and modify it freely, but please leave * this message attached to this file. * * Subject to terms of GNU General Public License (www.gnu.org) * * Last update: $Date: 2002/04/30 00:48:21 $ by $Author: sergey $ * Revision: $Revision: 1.5 $ * */ #include #include #include #include #include #include #include #include "Mix.h" #define BUFSIZE 512 const char * dname[] = SOUND_DEVICE_NAMES; static int devmask, stereod, recmask, mixer_fd = -1, init_flag = 0; static char dev_fname[BUFSIZE] = ""; int set_mixer_dev(char *fname) { #ifdef DEBUG fprintf(stderr, "set_mixer_dev(%s)\n", fname); #endif strncpy(dev_fname, fname, BUFSIZE-1); return(0); } int open_mixer() { #ifdef DEBUG fprintf(stderr, "open_mixer()\n"); #endif if (dev_fname[0] == '\0') { strncpy(dev_fname, MIXER, BUFSIZE-1); } if ((mixer_fd = open(dev_fname, O_RDWR)) < 0) { fprintf(stderr, "Error opening %s.", MIXER); return(-1); } if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { perror("SOUND_MIXER_READ_DEVMASK"); return(-1); } if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereod) == -1) { perror("SOUND_MIXER_READ_STEREODEVS"); return(-1); } if (ioctl(mixer_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) { perror("SOUND_MIXER_READ_RECMASK"); return(-1); } if (!devmask) { fprintf(stderr, "No device found."); return(-1); } return(0); } int close_mixer() { #ifdef DEBUG fprintf(stderr, "close_mixer()\n"); #endif if (mixer_fd < 0) return; close(mixer_fd); init_flag = 0; mixer_fd = -1; return(0); } /* * Get parameter value * Parameter: * cntrl - name of parameter * Returns: * integer value, which will be constructed as follows: * lower byte (x & 0xff) - value of the left channel (or whole value) * next byte (x & 0xff00) - value of the right channel * third byte (x & 0xff0000) - flags (if x & 0x10000 then 2 channels exist) */ int get_param_val(char *cntrl) { int i, d, len, lcval, ret = 0; #ifdef DEBUG fprintf(stderr, "get_param_val(%s)\n", cntrl); #endif if (!init_flag) { if (open_mixer()) { return(-1); } } len = strlen(cntrl); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { d = (1 << i); if ((0 == strncmp(dname[i], cntrl, len)) && (0 != (devmask & d))) { if (-1 == ioctl(mixer_fd, MIXER_READ(i), &lcval)) { perror("MIXER_READ"); if (!init_flag) close_mixer(); return(-1); } else { ret = lcval & 0x7f; if (d & stereod) { ret = ret | 0x10000; ret = ret | (lcval & 0x7f00); if (!init_flag) close_mixer(); return(ret); } } } } if (!init_flag) close_mixer(); return(-1); } char * get_source() { int j; unsigned int source = 0; if (!init_flag){ if (open_mixer()) return(""); } if (-1 == ioctl(mixer_fd, SOUND_MIXER_READ_RECSRC, &source)){ perror("MIXER_READ_RECSRC"); if (!init_flag) close_mixer(); return(""); } if (!init_flag) close_mixer(); source &= recmask; for (j = 0; source; source >>= 1, j++){ if (source & 1) return((char *) dname[j]); } return(""); } int set_source(char *cntrl) { int i, d, len, ret = 0; #ifdef DEBUG fprintf(stderr, "set_recsrc(%s)\n", cntrl); #endif if (!init_flag) { if (open_mixer()) { return(-1); } } len = strlen(cntrl); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { d = (1 << i); if ((0 == strncmp(dname[i], cntrl, len)) && (0 != (recmask & d))) { if (-1 == ioctl(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &d)) { perror("MIXER_WRITE_RECSRC"); if (!init_flag) close_mixer(); return(-1); } else { if (!init_flag) close_mixer(); return(0); } } } d = 0; if (-1 == ioctl(mixer_fd, SOUND_MIXER_WRITE_RECSRC, &d)) { perror("MIXER_WRITE_RECSRC"); if (!init_flag) close_mixer(); return(-1); } if (!init_flag) close_mixer(); return(0); } /* * Set parameter value. * Parameters: * cntrl - name of parameter * lcval - left channel value * rcval - right channel value * Returns 0 if Ok, -1 if failed */ int set_param_val(char *cntrl, int lcval, int rcval) { int len, i, d; #ifdef DEBUG fprintf(stderr, "set_param_val(%s, %d, %d)\n", cntrl, lcval, rcval); #endif if (!init_flag) { if (open_mixer()) { return(-1); } } len = strlen(cntrl); for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { if (0 == strncmp(dname[i], cntrl, len)) { d = (1 << i); if (0 != (devmask & d)) { lcval = (lcval < 0 ? 0 : (lcval > 100 ? 100 : lcval)); if (d & stereod) { rcval = (rcval < 0 ? 0 : (rcval > 100 ? 100 : rcval)); lcval |= (rcval << 8); } if (-1 == ioctl(mixer_fd, MIXER_WRITE(i), &lcval)) { perror("MIXER_WRITE"); if (!init_flag) close_mixer(); return(-1); } } break; } } if (!init_flag) close_mixer(); return(0); } int init_mixer() { if (open_mixer()) { return(-1); } init_flag = 1; return(0); } int get_params_num() { return(SOUND_MIXER_NRDEVICES); } char * get_params_list() { static char buf[BUFSIZE]; int i, l, len = 0; buf[0] = '\0'; for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { l = strlen(dname[i]); if ((len >= (BUFSIZE - 2)) || ((len + l + 3) >= BUFSIZE)) { buf[len] = '\0'; return(buf); } strcat(buf, dname[i]); strcat(buf, " "); len += l + 1; } buf[len] = '\0'; return(buf); } Audio-Mixer-0.7/Mix.h0000644000175000017500000000144407640507557013445 0ustar hehe00000000000000/* * Library to query / set various sound mixer parameters. * * This code is based on setmixer program by Michal Jaegermann * * Copyright (c) 2000 Sergey Gribov * This is free software with ABSOLUTELY NO WARRANTY. * You can redistribute and modify it freely, but please leave * this message attached to this file. * * Subject to terms of GNU General Public License (www.gnu.org) * * Last update: $Date: 2002/04/30 00:48:21 $ by $Author: sergey $ * Revision: $Revision: 1.3 $ * */ #define MIXER "/dev/mixer" int get_param_val(char *cntrl); int set_param_val(char *cntrl, int lcval, int rcval); int init_mixer(); int close_mixer(); int get_params_num(); char *get_params_list(); int set_mixer_dev(char *fname); char *get_source(); int set_source(char *cntrl); Audio-Mixer-0.7/Mixer.pm0000644000175000017500000001205107640507664014154 0ustar hehe00000000000000package Audio::Mixer; # # Library to query / set various sound mixer parameters. # See POD documentation below for more info. # # Copyright (c) 2000 Sergey Gribov # This is free software with ABSOLUTELY NO WARRANTY. # You can redistribute and modify it freely, but please leave # this message attached to this file. # # Subject to terms of GNU General Public License (www.gnu.org) # # Last update: $Date: 2002/04/30 00:48:21 $ by $Author: sergey $ # Revision: $Revision: 1.4 $ use strict; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); require Exporter; require DynaLoader; require AutoLoader; @ISA = qw(Exporter DynaLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT = qw(); @EXPORT_OK = qw( MIXER ); $VERSION = '0.7'; sub AUTOLOAD { # This AUTOLOAD is used to 'autoload' constants from the constant() # XS function. If a constant is not found then control is passed # to the AUTOLOAD in AutoLoader. my $constname; ($constname = $AUTOLOAD) =~ s/.*:://; croak "& not defined" if $constname eq 'constant'; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { croak "Your vendor has not defined Audio::Mixer macro $constname"; } } no strict 'refs'; *$AUTOLOAD = sub () { $val }; goto &$AUTOLOAD; } bootstrap Audio::Mixer $VERSION; # Preloaded methods go here. # Autoload methods go after =cut, and are processed by the autosplit program. sub get_cval { my $channel = shift; my ($val, $lcval, $rcval); $val = get_param_val($channel); $lcval = $val & 0xff; $rcval = $val & 0x10000 ? ($val & 0xff00) >> 8 : $lcval; return wantarray ? ($lcval, $rcval) : $val; } sub set_cval { my ($channel, $lcval, $rcval) = @_; $lcval = 0 unless $lcval; $rcval = $lcval unless $rcval; return set_param_val($channel, $lcval, $rcval); } sub get_mixer_params { return(split(/ /, get_params_list())); } 1; __END__ # Below is the stub of documentation for your module. You better edit it! =head1 NAME Audio::Mixer - Perl extension for Sound Mixer control =head1 SYNOPSIS use Audio::Mixer; $volume = Audio::Mixer::get_cval('vol'); if (Audio::Mixer::set_cval('vol', 50, 40)) { die("Can't set volume..."); } =head1 DESCRIPTION Library to query / set various sound mixer parameters. This is just a very simple Perl interface which allows to set various sound mixer parameters. The most important probably 'vol' (volume). The list of all mixer parameters can be obtained using get_mixer_params() function. All values (lcval, rcval) are numbers in 0-100 range. =head1 FUNCTIONS get_cval(cntrl) - Get parameter value Parameters: cntrl - name of parameter Returns: in array context: (lcval, rcval), where: lcval - left channel value rcval - right channel value in scalar context returns value of get_param_val() (see below) set_cval(cntrl, lcval, rcval) - Set parameter value Parameters: cntrl - name of parameter lcval - left channel value rcval - right channel value (optional, if not supplied will be equal to lcval) Returns: 0 if Ok, -1 if failed set_source(cntrl) - set record source Parameters: cntrl - name of channel to record from Returns: 0 if Ok, -1 if failed get_source(cntrl) - get record source Returns: name of channel to record from set_mixer_dev(fname) - Set mixer device name (optional), /dev/mixer is used by default fname - device name Returns: 0 if Ok init_mixer() - Initialize mixer (open it) set_cval() / get_cval() opens / closes the mixer each time they called unless init_mixer() called before. In case if init_mixer() called before all other functions will use already opened device instead of opening it each time. close_mixer() - Close device. Should be called only if init_mixer() was used. get_mixer_params() - Get list of mixer parameters Returns: list of parameters names. LOW LEVEL FUNCTIONS: get_param_val(cntrl) - Get parameter value Parameter: cntrl - name of parameter Returns: integer value, which will be constructed as follows: lower byte (x & 0xff) - value of the left channel (or whole value) next byte (x & 0xff00) - value of the right channel third byte (x & 0xff0000) - flags (if x & 0x10000 then 2 channels exist) or -1 in case of failure. set_param_val(cntrl, lcval, rcval) - Set parameter value. Here all parameters are mandatory (in contrast to set_cval()). Parameters: cntrl - name of parameter lcval - left channel value rcval - right channel value Returns: 0 if Ok, -1 if failed =head1 AUTHOR Sergey Gribov, sergey@sergey.com =head1 LICENSE Copyright (c) 2001 Sergey Gribov. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO perl(1). =cut Audio-Mixer-0.7/Mixer.xs0000644000175000017500000000317307640507557014200 0ustar hehe00000000000000#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "Mix.h" static int not_here(char *s) { croak("%s not implemented on this architecture", s); return -1; } static char * constant(char *name, int arg) { errno = 0; switch (*name) { case 'A': break; case 'B': break; case 'C': break; case 'D': break; case 'E': break; case 'F': break; case 'G': break; case 'H': break; case 'I': break; case 'J': break; case 'K': break; case 'L': break; case 'M': if (strEQ(name, "MIXER")) #ifdef MIXER return MIXER; #else goto not_there; #endif break; case 'N': break; case 'O': break; case 'P': break; case 'Q': break; case 'R': break; case 'S': break; case 'T': break; case 'U': break; case 'V': break; case 'W': break; case 'X': break; case 'Y': break; case 'Z': break; } errno = EINVAL; return 0; not_there: errno = ENOENT; return 0; } MODULE = Audio::Mixer PACKAGE = Audio::Mixer char * constant(name,arg) char * name int arg int get_param_val(cntrl) char * cntrl OUTPUT: RETVAL int set_param_val(cntrl, lcval, rcval) char * cntrl int lcval int rcval OUTPUT: RETVAL int init_mixer() OUTPUT: RETVAL int close_mixer() OUTPUT: RETVAL int get_params_num() OUTPUT: RETVAL char * get_params_list() OUTPUT: RETVAL int set_mixer_dev(fname) char * fname OUTPUT: RETVAL char * get_source() OUTPUT: RETVAL int set_source(cntrl) char * cntrl OUTPUT: RETVAL Audio-Mixer-0.7/README0000644000175000017500000000220707640507557013415 0ustar hehe00000000000000 Mixer - Perl extension for Sound Mixer control ============================================== Library to query / set various sound mixer parameters. This is just a very simple Perl interface which allows to set various sound mixer parameters. The most important probably 'vol' (volume). The list of all mixer parameters can be obtained using get_mixer_params() function. Library includes application volume.pl, which is a simple Perl/Tk volume control application. Installation ============ The installation of Mixer module is the same as you would install any perl module library, by running these commands: perl Makefile.PL make make test make install Platforms ========= Linux Documentation ============= See POD doumentation in Mixer.pm (after installation, just use perldoc Mixer). Questions, bug reports, useful code bits, and suggestions should just be sent to me at sergey@sergey.com Availability ============ The latest version can be found on http://www.sergey.com/soft/Mixer/ Copyright ========= Copyright 2001 by Sergey Gribov , all rights reserved. Audio-Mixer-0.7/test.pl0000644000175000017500000000355007640507557014053 0ustar hehe00000000000000# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..1\n"; } END {print "not ok 1\n" unless $loaded;} use Audio::Mixer; $loaded = 1; print "ok 1\n"; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): print STDERR "Opening mixer... "; $ret = Audio::Mixer::init_mixer(); print STDERR $ret ? "FAILED.\n" : "Ok.\n"; print STDERR "Getting the volume... "; my @old = Audio::Mixer::get_cval('vol'); print STDERR join(', ', @old)." Ok.\nSetting to 50... "; Audio::Mixer::set_cval('vol', 50); my @ret = Audio::Mixer::get_cval('vol'); print STDERR ($ret[0] == 50 && $ret[1] == 50) ? "Ok.\nResetting back... " : "FAILED.\nTrying to reset back... "; Audio::Mixer::set_cval('vol', $old[0], $old[1]); @ret = Audio::Mixer::get_cval('vol'); print STDERR ($ret[0] == $old[0] && $ret[1] == $old[1]) ? "Ok.\n" : "FAILED.\n"; #my $ret = Mixer::get_cval('vol'); #printf "get_cval() vol=0x%x\n", $ret; #$ret = Mixer::set_cval('vol', 50); #print "set_cval returns $ret\n"; #@ret = Mixer::get_cval('vol'); #print "get_cval() vol=".join(', ', @ret)."\n"; #$ret = Mixer::get_cval('vol'); #printf "get_cval() vol=0x%x\n", $ret; #$ret = Mixer::get_param_val('vol'); #printf "get_param_val() vol=0x%x\n", $ret; #$ret = Mixer::set_param_val('vol', 20, 50); #print "set_param_val returns $ret\n"; #$ret = Mixer::get_param_val('vol'); #printf "get_param_val() vol=0x%x\n", $ret; #@ret = Mixer::get_mixer_params(); #print "== ".join(',', @ret)." ==\n"; Audio-Mixer-0.7/volume.pl0000755000175000017500000000261307640507557014405 0ustar hehe00000000000000#!/usr/bin/perl # -d:ptkdb # # Volume control application. # It's a very simple application which uses Mixer.pm to control # the sound volume. It's written to be used inside the # FVWM FvwmButtons panel. # # Copyright (c) 2001 Sergey Gribov # This is free software with ABSOLUTELY NO WARRANTY. # You can redistribute and modify it freely, but please leave # this message attached to this file. # # Subject to terms of GNU General Public License (www.gnu.org) # # Last update: $Date: 2001/03/20 00:20:50 $ by $Author: sergey $ # Revision: $Revision: 1.3 $ use Tk; use Audio::Mixer; use strict; $| = 1; my $debug = 0; my $win_h = 69; my $win_w = 62; Audio::Mixer::set_mixer_dev("/dev/mixer"); my $ret = Audio::Mixer::init_mixer(); die("Can't open sound mixer...") if $ret; my @vol = Audio::Mixer::get_cval('vol'); my $volume = ($vol[0] + $vol[1]) / 2; my $main = MainWindow->new; $main->geometry($win_w.'x'.$win_h.'+0-0'); my $sb = $main->Scale(-orient => 'vertical', -resolution => 1, -from => 100, -to => 0, -sliderlength => 10, -showvalue => 0, -variable => \$volume, -command => sub{change_volume();} ); $sb->pack(-fill => 'y', ); MainLoop; print "Should never end up here... :)\n"; exit; ################################################################### sub change_volume { print "$volume\n" if $debug; Audio::Mixer::set_cval('vol', $volume); }