summaryrefslogtreecommitdiffstats
path: root/kmix/volume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmix/volume.cpp')
-rw-r--r--kmix/volume.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/kmix/volume.cpp b/kmix/volume.cpp
new file mode 100644
index 00000000..20d056a4
--- /dev/null
+++ b/kmix/volume.cpp
@@ -0,0 +1,266 @@
+/*
+ * KMix -- KDE's full featured mini mixer
+ *
+ *
+ * Copyright (C) 1996-2004 Christian Esken <esken@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+// for operator<<()
+#include <iostream>
+
+#include <kdebug.h>
+
+#include "volume.h"
+
+
+int Volume::_channelMaskEnum[10] =
+ { MLEFT, MRIGHT, MCENTER,
+ MREARLEFT, MREARRIGHT, MWOOFER,
+ MLEFTREC , MRIGHTREC ,
+ MCUSTOM1, MCUSTOM2
+ };
+
+Volume::Volume( ChannelMask chmask, long maxVolume, long minVolume, bool isCapture )
+{
+ init(chmask, maxVolume, minVolume, isCapture);
+}
+
+
+// @ compatiblity constructor
+Volume::Volume( int channels, long maxVolume ) {
+ if (channels == 1 ) {
+ init(Volume::MLEFT, maxVolume, 0, false);
+ }
+ else if (channels == 2) {
+ init(ChannelMask(Volume::MLEFT|Volume::MRIGHT), maxVolume, 0, false );
+ }
+ else {
+ init(ChannelMask(Volume::MLEFT|Volume::MRIGHT), maxVolume, 0, false );
+ kdError(67100) << "Warning: Multi-channel Volume object created with old constructor - this will not work fully\n";
+ }
+}
+
+Volume::Volume( const Volume &v )
+{
+ _chmask = v._chmask;
+ _maxVolume = v._maxVolume;
+ _minVolume = v._minVolume;
+ _muted = v._muted;
+ _isCapture = v._isCapture;
+ setVolume(v, (ChannelMask)v._chmask);
+
+ // kdDebug(67100) << "Volume::copy-constructor initialized " << v << "\n";
+}
+
+void Volume::init( ChannelMask chmask, long maxVolume, long minVolume, bool isCapture )
+{
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ _volumes[i] = 0;
+ }
+ _chmask = chmask;
+ _maxVolume = maxVolume;
+ _minVolume = minVolume;
+ _isCapture = isCapture;
+ _muted = false;
+}
+
+// @ compatibility
+void Volume::setAllVolumes(long vol)
+{
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( (_channelMaskEnum[i]) & _chmask ) {
+ // we are supposed to set it
+ _volumes[i] = volrange(vol);
+ }
+ }
+}
+
+// @ compatibility
+void Volume::setVolume( ChannelID chid, long vol)
+{
+ if ( chid>=0 && chid<=Volume::CHIDMAX ) {
+ // accepted. we don't care if we support the channel,
+ // because there is NO good action we could take.
+ // Anyway: getVolume() on an unsupported channel will return 0 all the time
+ _volumes[chid] = volrange(vol);
+ }
+}
+
+/**
+ * Copy the volume elements contained in v to this Volume object.
+ * Only those elments are copied, that are supported in BOTH Volume objects.
+ */
+void Volume::setVolume(const Volume &v)
+{
+ setVolume(v, (ChannelMask)(v._chmask&_chmask) );
+}
+
+/**
+ * Copy the volume elements contained in v to this Volume object.
+ * Only those elments are copied, that are supported in BOTH Volume objects
+ * and match the ChannelMask given by chmask.
+ */
+void Volume::setVolume(const Volume &v, ChannelMask chmask) {
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( _channelMaskEnum[i] & _chmask & (int)chmask ) {
+ // we are supposed to copy it
+ _volumes[i] = volrange(v._volumes[i]);
+ }
+ else {
+ // Safety first! Lets play safe here and put sane values in
+ _volumes[i] = 0;
+ }
+ }
+
+}
+
+long Volume::maxVolume() {
+ return _maxVolume;
+}
+
+long Volume::minVolume() {
+ return _minVolume;
+}
+
+// @ compatibility
+long Volume::operator[](int id) {
+ return getVolume( (Volume::ChannelID) id );
+}
+
+long Volume::getVolume(ChannelID chid) {
+ long vol = 0;
+
+ if ( chid < 0 || chid > (Volume::CHIDMAX) ) {
+ // should throw exception here. I will return 0 instead
+ }
+ else {
+ // check if channel is supported
+ int chmask = _channelMaskEnum[chid];
+ if ( (chmask & _chmask) != 0 ) {
+ // channel is supported
+ vol = _volumes[chid];
+ }
+ else {
+ // should throw exception here. I will return 0 instead
+ }
+ }
+
+ return vol;
+}
+
+long Volume::getAvgVolume(ChannelMask chmask) {
+ int avgVolumeCounter = 0;
+ long long sumOfActiveVolumes = 0;
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( (_channelMaskEnum[i] & _chmask) & (int)chmask ) {
+ avgVolumeCounter++;
+ sumOfActiveVolumes += _volumes[i];
+ }
+ }
+ if (avgVolumeCounter != 0) {
+ sumOfActiveVolumes /= avgVolumeCounter;
+ }
+ else {
+ // just return 0;
+ }
+ return (long)sumOfActiveVolumes;
+}
+
+long Volume::getTopStereoVolume(ChannelMask chmask) {
+ long long topVolumeCount = 0;
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( (_channelMaskEnum[i] & _chmask) & (int)chmask ) {
+ if ( topVolumeCount < _volumes[i] )
+ topVolumeCount = _volumes[i];
+ }
+ }
+ return (long)topVolumeCount;
+}
+
+int Volume::count() {
+ int counter = 0;
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( _channelMaskEnum[i] & _chmask ) {
+ counter++;
+ }
+ }
+ return counter;
+}
+
+/**
+ * returns a "sane" volume level. This means, it is a volume level inside the
+ * valid bounds
+ */
+long Volume::volrange( int vol )
+{
+ if ( vol < _minVolume ) {
+ return _minVolume;
+ }
+ else if ( vol < _maxVolume ) {
+ return vol;
+ }
+ else {
+ return _maxVolume;
+ }
+}
+
+
+std::ostream& operator<<(std::ostream& os, const Volume& vol) {
+ os << "(";
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( i != 0 ) {
+ os << ",";
+ }
+ if ( Volume::_channelMaskEnum[i] & vol._chmask ) {
+ // supported channel: Print Volume
+ os << vol._volumes[i];
+ }
+ else {
+ // unsupported channel: Print "x"
+ os << "x";
+ }
+ } // all channels
+ os << ")";
+
+ os << " [" << vol._minVolume << "-" << vol._maxVolume;
+ if ( vol._muted ) { os << " : muted ]"; } else { os << " : playing ]"; }
+
+ return os;
+}
+
+kdbgstream& operator<<(kdbgstream &os, const Volume& vol) {
+ os << "(";
+ for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
+ if ( i != 0 ) {
+ os << ",";
+ }
+ if ( Volume::_channelMaskEnum[i] & vol._chmask ) {
+ // supported channel: Print Volume
+ os << vol._volumes[i];
+ }
+ else {
+ // unsupported channel: Print "x"
+ os << "x";
+ }
+ } // all channels
+ os << ")";
+
+ os << " [" << vol._minVolume << "-" << vol._maxVolume;
+ if ( vol._muted ) { os << " : muted ]"; } else { os << " : playing ]"; }
+
+ return os;
+}