File: mixctl.h

package info (click to toggle)
alsa-oss 1.0.17-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,628 kB
  • ctags: 355
  • sloc: sh: 8,849; ansic: 3,652; cpp: 302; makefile: 101
file content (207 lines) | stat: -rw-r--r-- 6,105 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// mixctl.h - MixCtl class provides control of audio mixer functions
// 05/09/98  Release 1.0 Beta1
// Copyright (C) 1998  Sam Hawker <shawkie@geocities.com>
// 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 <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef __NetBSD__
#include <soundcard.h>
#endif
#ifdef __FreeBSD__
#include <machine/soundcard.h>
#endif
#ifdef __linux__
#include <linux/soundcard.h>
#endif
#include <oss-redir.h>

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;i<nrdevices;i++){
            mixdevs[i].support=devmask & mixmask;
            mixdevs[i].stereo=stmask & mixmask;
            mixdevs[i].records=recmask & mixmask;
            mixdevs[i].mask=mixmask;
            mixdevs[i].name=devnames[i];
            mixdevs[i].label=devlabels[i];
            mixmask*=2;
         }
         doStatus();
      }
   }
   ~MixCtl(){
      if(mixfdopen){
         if(mixdevs!=NULL)
            free(mixdevs);
         oss_mixer_close(mixfd);
      }
   }
   bool openOK(){
      return mixfdopen;
   }
   void doStatus(){
      oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
      for(int i=0;i<nrdevices;i++){
	 if(mixdevs[i].support)
	    oss_mixer_ioctl(mixfd, MIXER_READ(i), &mixdevs[i].value);
         mixdevs[i].recsrc=(recsrc & mixdevs[i].mask);
      }
   }

   // Return volume for a device, optionally reading it from device first.
   // Can be used as a way to avoid calling doStatus().
   int readVol(int dev, bool read){
      if(read)
         oss_mixer_ioctl(mixfd, MIXER_READ(dev), &mixdevs[dev].value);
      return mixdevs[dev].value/256;
   }

   // Return left and right componenets of volume for a device.
   // If you are lazy, you can call readVol to read from the device, then these
   // to get left and right values.
   int readLeft(int dev){
      return mixdevs[dev].value%256;
   }
   int readRight(int dev){
      return mixdevs[dev].value/256;
   }

   // Write volume to device. Use setVolume, setLeft and setRight first.
   void writeVol(int dev){
      oss_mixer_ioctl(mixfd, MIXER_WRITE(dev), &mixdevs[dev].value);
   }

   // Set volume (or left or right component) for a device. You must call writeVol to write it.
   void setVol(int dev, int value){
      mixdevs[dev].value=value;
   }
   void setBoth(int dev, int l, int r){
      mixdevs[dev].value=256*r+l;
   }
   void setLeft(int dev, int l){
      int r;
      if(mixdevs[dev].stereo)
         r=mixdevs[dev].value/256;
      else
         r=l;
      mixdevs[dev].value=256*r+l;
   }
   void setRight(int dev, int r){
      int l;
      if(mixdevs[dev].stereo)
         l=mixdevs[dev].value%256;
      else
         l=r;
      mixdevs[dev].value=256*r+l;
   }

   // Return record source value for a device, optionally reading it from device first.
   bool readRec(int dev, bool read){
      if(read){
	 oss_mixer_ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
         mixdevs[dev].recsrc=(recsrc & mixdevs[dev].mask);
      }
      return mixdevs[dev].recsrc;
   }

   // Write record source values to device. Use setRec first.
   void writeRec(){
      oss_mixer_ioctl(mixfd, SOUND_MIXER_WRITE_RECSRC, &recsrc);
   }

   // Make a device (not) a record source.
   void setRec(int dev, bool rec){
      if(rec){
         if(caps & SOUND_CAP_EXCL_INPUT)
            recsrc=mixdevs[dev].mask;
         else
            recsrc|=mixdevs[dev].mask;
      }
      else
         recsrc&=~mixdevs[dev].mask;
   }

   // Return various other info
   char *getDevName(){
      return device;
   }
   // Return the number of mixer devices..
   // note: check the validity of each with getSupport 
   // before using.
   int getNrDevices(){
      return nrdevices;
   }
   int getCapabilities(){
      return caps;
   }
   // Is this dev valid? 
   // Example: if (mixctl->getSupport(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;
};