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.
30 int Volume::_channelMaskEnum
[8] =
31 { MLEFT
, MRIGHT
, MCENTER
,
33 MSURROUNDLEFT
, MSURROUNDRIGHT
,
34 MREARLEFT
, MREARRIGHT
,
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 ) {
51 init(Volume::MLEFT, maxVolume, 0, false, false);
53 else if (channels == 2) {
54 init(ChannelMask(Volume::MLEFT|Volume::MRIGHT), maxVolume, 0, false, false );
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
)
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
++ ) {
81 _maxVolume
= maxVolume
;
82 _minVolume
= minVolume
;
83 _hasSwitch
= hasSwitch
;
84 _isCapture
= isCapture
;
86 _switchActivated
= false;
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
);
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
]);
132 // Safety first! Lets play safe here and put sane values in
139 long Volume::maxVolume() {
143 long Volume::minVolume() {
147 int Volume::percentage(long absoluteVolume
)
149 int relativeVolume
= 0;
150 if ( _maxVolume
== 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
;
167 long Volume::operator[](int id
) {
168 return getVolume( (Volume::ChannelID
) id
);
171 long Volume::getVolume(ChannelID chid
) {
174 if ( chid
< 0 || chid
> (Volume::CHIDMAX
) ) {
175 // should throw exception here. I will return 0 instead
178 // check if channel is supported
179 int chmask
= _channelMaskEnum
[chid
];
180 if ( (chmask
& _chmask
) != 0 ) {
181 // channel is supported
182 vol
= _volumes
[chid
];
185 // should throw exception here. I will return 0 instead
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
) {
198 sumOfActiveVolumes
+= _volumes
[i
];
201 if (avgVolumeCounter
!= 0) {
202 sumOfActiveVolumes
/= avgVolumeCounter
;
207 return (long)sumOfActiveVolumes
;
211 int Volume::count() {
213 for ( int i
=0; i
<= Volume::CHIDMAX
; i
++ ) {
214 if ( _channelMaskEnum
[i
] & _chmask
) {
222 * returns a "sane" volume level. This means, it is a volume level inside the
225 long Volume::volrange( int vol
)
227 if ( vol
< _minVolume
) {
230 else if ( vol
< _maxVolume
) {
239 std::ostream
& operator<<(std::ostream
& os
, const Volume
& vol
) {
241 for ( int i
=0; i
<= Volume::CHIDMAX
; i
++ ) {
245 if ( Volume::_channelMaskEnum
[i
] & vol
._chmask
) {
246 // supported channel: Print Volume
247 os
<< vol
._volumes
[i
];
250 // unsupported channel: Print "x"
256 os
<< " [" << vol
._minVolume
<< "-" << vol
._maxVolume
;
257 if ( vol
._muted
) { os
<< " : muted ]"; } else { os
<< " : playing ]"; }
262 kdbgstream
& operator<<(kdbgstream
&os
, const Volume
& vol
) {
264 for ( int i
=0; i
<= Volume::CHIDMAX
; i
++ ) {
268 if ( Volume::_channelMaskEnum
[i
] & vol
._chmask
) {
269 // supported channel: Print Volume
270 os
<< vol
._volumes
[i
];
273 // unsupported channel: Print "x"
279 os
<< " [" << vol
._minVolume
<< "-" << vol
._maxVolume
;
280 if ( vol
._muted
) { os
<< " : muted ]"; } else { os
<< " : playing ]"; }