You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
6.7 KiB
267 lines
6.7 KiB
/*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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;
|
|
}
|