wmmemload: call usleep() directly in main loop
[dockapps.git] / wmmixer / mixctl.cc
blobffea52c80615c64c8e08b6d0b4de3693036800ea
1 // mixctl.h - MixCtl class provides control of audio mixer functions
2 //
3 // Release 1.5
4 // Copyright (C) 1998 Sam Hawker <shawkie@geocities.com>
5 // Copyright (C) 2002 Gordon Fraser <gordon@debian.org>
6 // This software comes with ABSOLUTELY NO WARRANTY
7 // This software is free software, and you are welcome to redistribute it
8 // under certain conditions
9 // See the COPYING file for details.
13 #include "mixctl.h"
15 //----------------------------------------------------------------------
16 MixCtl::MixCtl(char *device_name) throw(MixerDeviceException)
18 device_ = new char[strlen(device_name)+1];
19 strcpy(device_, device_name);
21 modify_counter = -1;
23 if((mixfd = open(device_,O_RDONLY | O_NONBLOCK)) != -1)
25 num_devices_ = SOUND_MIXER_NRDEVICES;
26 const char *devnames[] = SOUND_DEVICE_NAMES;
27 const char *devlabels[] = SOUND_DEVICE_LABELS;
28 ioctl(mixfd, SOUND_MIXER_READ_DEVMASK, &devmask);
29 ioctl(mixfd, SOUND_MIXER_READ_STEREODEVS, &stmask);
30 ioctl(mixfd, SOUND_MIXER_READ_RECMASK, &recmask);
31 ioctl(mixfd, SOUND_MIXER_READ_CAPS, &caps);
33 mixer_devices_ = new MixerDevice[num_devices_];
34 int mixmask = 1;
36 for(unsigned count=0; count<num_devices_; count++)
38 mixer_devices_[count].support = devmask & mixmask;
39 mixer_devices_[count].stereo = stmask & mixmask;
40 mixer_devices_[count].records = recmask & mixmask;
41 mixer_devices_[count].mask = mixmask;
42 mixer_devices_[count].name = (char *) devnames[count];
43 mixer_devices_[count].label = (char *) devlabels[count];
44 mixer_devices_[count].muted = 0;
45 mixmask*=2;
47 doStatus();
49 else
51 throw MixerDeviceException(device_name);
55 //----------------------------------------------------------------------
56 MixCtl::~MixCtl()
58 if(mixer_devices_ != NULL)
59 delete[](mixer_devices_);
60 close(mixfd);
62 delete[] device_;
65 //----------------------------------------------------------------------
66 bool MixCtl::isMuted(int channel)
68 return mixer_devices_[channel].muted;
71 //----------------------------------------------------------------------
72 void MixCtl::mute(int channel)
74 mixer_devices_[channel].muted = mixer_devices_[channel].value;
75 mixer_devices_[channel].value = 0;
76 writeVol(channel);
79 //----------------------------------------------------------------------
80 void MixCtl::unmute(int channel)
82 mixer_devices_[channel].value = mixer_devices_[channel].muted;
83 mixer_devices_[channel].muted = 0;
84 writeVol(channel);
87 //----------------------------------------------------------------------
88 void MixCtl::doStatus()
90 ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
91 for(unsigned i=0;i<num_devices_;i++)
93 if(mixer_devices_[i].support)
95 ioctl(mixfd, MIXER_READ(i), &mixer_devices_[i].value);
97 mixer_devices_[i].recsrc=(recsrc & mixer_devices_[i].mask);
102 //----------------------------------------------------------------------
103 // Return volume for a device, optionally reading it from device first.
104 // Can be used as a way to avoid calling doStatus().
105 int MixCtl::readVol(int dev, bool read)
107 if(read)
109 ioctl(mixfd, MIXER_READ(dev), &mixer_devices_[dev].value);
111 return mixer_devices_[dev].value;
114 //----------------------------------------------------------------------
115 // Return left and right componenets of volume for a device.
116 // If you are lazy, you can call readVol to read from the device, then these
117 // to get left and right values.
118 int MixCtl::readLeft(int dev)
120 return mixer_devices_[dev].value%256;
123 //----------------------------------------------------------------------
124 int MixCtl::readRight(int dev)
126 return mixer_devices_[dev].value/256;
129 //----------------------------------------------------------------------
130 // Write volume to device. Use setVolume, setLeft and setRight first.
131 void MixCtl::writeVol(int dev)
133 ioctl(mixfd, MIXER_WRITE(dev), &mixer_devices_[dev].value);
136 //----------------------------------------------------------------------
137 // Set volume (or left or right component) for a device. You must call writeVol to write it.
138 void MixCtl::setVol(int dev, int value)
140 mixer_devices_[dev].value=value;
142 //----------------------------------------------------------------------
143 void MixCtl::setBoth(int dev, int l, int r)
145 mixer_devices_[dev].value=256*r+l;
147 //----------------------------------------------------------------------
148 void MixCtl::setLeft(int dev, int l)
150 int r;
151 if(mixer_devices_[dev].stereo)
152 r=mixer_devices_[dev].value/256;
153 else
154 r=l;
155 mixer_devices_[dev].value=256*r+l;
157 //----------------------------------------------------------------------
158 void MixCtl::setRight(int dev, int r)
160 int l;
161 if(mixer_devices_[dev].stereo)
162 l=mixer_devices_[dev].value%256;
163 else
164 l=r;
165 mixer_devices_[dev].value=256*r+l;
168 //----------------------------------------------------------------------
169 // Return record source value for a device, optionally reading it from device first.
170 bool MixCtl::readRec(int dev, bool read)
172 if(read)
174 ioctl(mixfd, SOUND_MIXER_READ_RECSRC, &recsrc);
175 mixer_devices_[dev].recsrc=(recsrc & mixer_devices_[dev].mask);
177 return mixer_devices_[dev].recsrc;
180 //----------------------------------------------------------------------
181 // Write record source values to device. Use setRec first.
182 void MixCtl::writeRec(){
183 ioctl(mixfd, SOUND_MIXER_WRITE_RECSRC, &recsrc);
186 //----------------------------------------------------------------------
187 // Make a device (not) a record source.
188 void MixCtl::setRec(int dev, bool rec)
190 if(rec)
192 if(caps & SOUND_CAP_EXCL_INPUT)
193 recsrc=mixer_devices_[dev].mask;
194 else
195 recsrc|=mixer_devices_[dev].mask;
197 else
198 recsrc&=~mixer_devices_[dev].mask;
201 //----------------------------------------------------------------------
202 // Return various other info
203 char* MixCtl::getDevName()
205 return device_;
207 //----------------------------------------------------------------------
208 unsigned MixCtl::getNrDevices()
210 return num_devices_;
212 //----------------------------------------------------------------------
213 int MixCtl::getCapabilities()
215 return caps;
217 //----------------------------------------------------------------------
218 bool MixCtl::getSupport(int dev)
220 return mixer_devices_[dev].support;
222 //----------------------------------------------------------------------
223 bool MixCtl::getStereo(int dev)
225 return mixer_devices_[dev].stereo;
227 //----------------------------------------------------------------------
228 bool MixCtl::getRecords(int dev)
230 return mixer_devices_[dev].records;
232 //----------------------------------------------------------------------
233 char* MixCtl::getName(int dev)
235 return mixer_devices_[dev].name;
237 //----------------------------------------------------------------------
238 char* MixCtl::getLabel(int dev)
240 return mixer_devices_[dev].label;
243 //----------------------------------------------------------------------
244 bool MixCtl::hasChanged()
246 struct mixer_info mixer_info1;
247 ioctl(mixfd, SOUND_MIXER_INFO, &mixer_info1);
249 if (mixer_info1.modify_counter == modify_counter)
251 return false;
253 else
255 modify_counter = mixer_info1.modify_counter;
256 return true;