Final polisihing for KDE4:
[kdemultimedia.git] / kmix / volume.cpp
bloba72d146b267be33d5c4bf0f7a90c0be7c594d514
1 /*
2 * KMix -- KDE's full featured mini mixer
5 * Copyright (C) 1996-2004 Christian Esken <esken@kde.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this program; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 // for operator<<()
23 #include <iostream>
25 #include <kdebug.h>
27 #include "volume.h"
30 int Volume::_channelMaskEnum[8] =
31 { MLEFT, MRIGHT, MCENTER,
32 MWOOFER,
33 MSURROUNDLEFT, MSURROUNDRIGHT,
34 MREARLEFT, MREARRIGHT,
37 Volume::Volume()
39 init( Volume::MNONE, 0, 0, false, false);
42 Volume::Volume( ChannelMask chmask, long maxVolume, long minVolume, bool hasSwitch, bool isCapture )
44 init(chmask, maxVolume, minVolume, hasSwitch, isCapture );
48 /* // @ compatibility constructor @todo remove it
49 Volume::Volume( int channels, long maxVolume ) {
50 if (channels == 1 ) {
51 init(Volume::MLEFT, maxVolume, 0, false, false);
53 else if (channels == 2) {
54 init(ChannelMask(Volume::MLEFT|Volume::MRIGHT), maxVolume, 0, false, false );
56 else {
57 init(ChannelMask(Volume::MLEFT|Volume::MRIGHT), maxVolume, 0, false, false );
58 kError(67100) << "Warning: Multi-channel Volume object created with old constructor - this will not work fully\n";
63 Volume::Volume( const Volume &v )
65 _chmask = v._chmask;
66 _maxVolume = v._maxVolume;
67 _minVolume = v._minVolume;
68 _hasSwitch = v._hasSwitch;
69 _switchActivated = v._switchActivated;
70 _isCapture = v._isCapture;
71 setVolume(v, (ChannelMask)v._chmask);
72 // kDebug(67100) << "Volume::copy-constructor initialized " << v << "\n";
75 void Volume::init( ChannelMask chmask, long maxVolume, long minVolume, bool hasSwitch, bool isCapture )
77 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
78 _volumes[i] = 0;
80 _chmask = chmask;
81 _maxVolume = maxVolume;
82 _minVolume = minVolume;
83 _hasSwitch = hasSwitch;
84 _isCapture = isCapture;
85 _muted = false;
86 _switchActivated = false;
89 // @ compatibility
90 void Volume::setAllVolumes(long vol)
92 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
93 if ( (_channelMaskEnum[i]) & _chmask ) {
94 // we are supposed to set it
95 _volumes[i] = volrange(vol);
100 // @ compatibility
101 void Volume::setVolume( ChannelID chid, long vol)
103 if ( chid>=0 && chid<=Volume::CHIDMAX ) {
104 // accepted. we don't care if we support the channel,
105 // because there is NO good action we could take.
106 // Anyway: getVolume() on an unsupported channel will return 0 all the time
107 _volumes[chid] = volrange(vol);
112 * Copy the volume elements contained in v to this Volume object.
113 * Only those elments are copied, that are supported in BOTH Volume objects.
115 void Volume::setVolume(const Volume &v)
117 setVolume(v, (ChannelMask)(v._chmask&_chmask) );
121 * Copy the volume elements contained in v to this Volume object.
122 * Only those elments are copied, that are supported in BOTH Volume objects
123 * and match the ChannelMask given by chmask.
125 void Volume::setVolume(const Volume &v, ChannelMask chmask) {
126 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
127 if ( _channelMaskEnum[i] & _chmask & (int)chmask ) {
128 // we are supposed to copy it
129 _volumes[i] = volrange(v._volumes[i]);
131 else {
132 // Safety first! Lets play safe here and put sane values in
133 _volumes[i] = 0;
139 long Volume::maxVolume() {
140 return _maxVolume;
143 long Volume::minVolume() {
144 return _minVolume;
147 int Volume::percentage(long absoluteVolume)
149 int relativeVolume = 0;
150 if ( _maxVolume == 0 )
151 return 0;
153 if ( absoluteVolume > _maxVolume )
154 relativeVolume = 100;
155 else if ( absoluteVolume < _minVolume )
156 relativeVolume = -100;
157 else if ( absoluteVolume > 0 )
158 relativeVolume = ( 100*absoluteVolume) / _maxVolume;
159 else if ( absoluteVolume < 0 )
160 relativeVolume = ( 100*absoluteVolume) / _minVolume;
162 return relativeVolume;
166 // @ compatibility
167 long Volume::operator[](int id) {
168 return getVolume( (Volume::ChannelID) id );
171 long Volume::getVolume(ChannelID chid) {
172 long vol = 0;
174 if ( chid < 0 || chid > (Volume::CHIDMAX) ) {
175 // should throw exception here. I will return 0 instead
177 else {
178 // check if channel is supported
179 int chmask = _channelMaskEnum[chid];
180 if ( (chmask & _chmask) != 0 ) {
181 // channel is supported
182 vol = _volumes[chid];
184 else {
185 // should throw exception here. I will return 0 instead
189 return vol;
192 long Volume::getAvgVolume(ChannelMask chmask) {
193 int avgVolumeCounter = 0;
194 long long sumOfActiveVolumes = 0;
195 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
196 if ( (_channelMaskEnum[i] & _chmask) & (int)chmask ) {
197 avgVolumeCounter++;
198 sumOfActiveVolumes += _volumes[i];
201 if (avgVolumeCounter != 0) {
202 sumOfActiveVolumes /= avgVolumeCounter;
204 else {
205 // just return 0;
207 return (long)sumOfActiveVolumes;
211 int Volume::count() {
212 int counter = 0;
213 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
214 if ( _channelMaskEnum[i] & _chmask ) {
215 counter++;
218 return counter;
222 * returns a "sane" volume level. This means, it is a volume level inside the
223 * valid bounds
225 long Volume::volrange( int vol )
227 if ( vol < _minVolume ) {
228 return _minVolume;
230 else if ( vol < _maxVolume ) {
231 return vol;
233 else {
234 return _maxVolume;
239 std::ostream& operator<<(std::ostream& os, const Volume& vol) {
240 os << "(";
241 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
242 if ( i != 0 ) {
243 os << ",";
245 if ( Volume::_channelMaskEnum[i] & vol._chmask ) {
246 // supported channel: Print Volume
247 os << vol._volumes[i];
249 else {
250 // unsupported channel: Print "x"
251 os << "x";
253 } // all channels
254 os << ")";
256 os << " [" << vol._minVolume << "-" << vol._maxVolume;
257 if ( vol._muted ) { os << " : muted ]"; } else { os << " : playing ]"; }
259 return os;
262 kdbgstream& operator<<(kdbgstream &os, const Volume& vol) {
263 os << "(";
264 for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
265 if ( i != 0 ) {
266 os << ",";
268 if ( Volume::_channelMaskEnum[i] & vol._chmask ) {
269 // supported channel: Print Volume
270 os << vol._volumes[i];
272 else {
273 // unsupported channel: Print "x"
274 os << "x";
276 } // all channels
277 os << ")";
279 os << " [" << vol._minVolume << "-" << vol._maxVolume;
280 if ( vol._muted ) { os << " : muted ]"; } else { os << " : playing ]"; }
282 return os;