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.
25
#include "core/mixdevice.h"
26
#include "gui/guiprofile.h"
27
#include "core/volume.h"
29
static const QString channelTypeToIconName( MixDevice::ChannelType type )
32
case MixDevice::AUDIO:
35
case MixDevice::SURROUND_LFE: // "LFE" SHOULD have an own icon
39
case MixDevice::EXTERNAL:
41
case MixDevice::MICROPHONE:
42
return "mixer-microphone";
45
case MixDevice::RECMONITOR:
46
return "mixer-capture";
47
case MixDevice::TREBLE:
48
return "mixer-pcm-default";
49
case MixDevice::UNKNOWN:
51
case MixDevice::VOLUME:
52
return "mixer-master";
53
case MixDevice::VIDEO:
55
case MixDevice::SURROUND:
56
case MixDevice::SURROUND_BACK:
57
return "mixer-surround";
58
case MixDevice::SURROUND_CENTERFRONT:
59
case MixDevice::SURROUND_CENTERBACK:
60
return "mixer-surround-center";
61
case MixDevice::HEADPHONE:
62
return "mixer-headset";
63
case MixDevice::DIGITAL:
64
return "mixer-digital";
67
case MixDevice::SPEAKER:
68
return "mixer-pc-speaker";
69
case MixDevice::MICROPHONE_BOOST:
70
return "mixer-microphone-boost";
71
case MixDevice::MICROPHONE_FRONT_BOOST:
72
return "mixer-microphone-front-boost";
73
case MixDevice::MICROPHONE_FRONT:
74
return "mixer-microphone-front";
75
case MixDevice::KMIX_COMPOSITE:
83
* Constructs a MixDevice. A MixDevice represents one channel or control of
84
* the mixer hardware. A MixDevice has a type (e.g. PCM), a descriptive name
85
* (for example "Master" or "Headphone" or "IEC 958 Output"),
86
* can have a volume level (2 when stereo), can be recordable and muted.
87
* The category tells which kind of control the MixDevice is.
89
* Hints: Meaning of "category" has changed. In future the MixDevice might contain two
90
* Volume objects, one for Output (Playback volume) and one for Input (Record volume).
92
MixDevice::MixDevice( Mixer* mixer, const QString& id, const QString& name, ChannelType type )
94
init(mixer, id, name, channelTypeToIconName(type), (MixSet*)0);
97
MixDevice::MixDevice( Mixer* mixer, const QString& id, const QString& name, const QString& iconName, MixSet* moveDestinationMixSet )
99
// doNotRestore is superseded by the more generic concepts isEthereal(), isArtificial()
100
init(mixer, id, name, iconName, moveDestinationMixSet);
103
void MixDevice::init( Mixer* mixer, const QString& id, const QString& name, const QString& iconName, MixSet* moveDestinationMixSet )
110
_name = i18n("unknown");
113
if ( iconName.isEmpty() )
114
_iconName = "mixer-front";
116
_iconName = iconName;
117
_moveDestinationMixSet = moveDestinationMixSet;
118
if ( _id.contains(' ') ) {
119
// The key is used in the config file. It MUST NOT contain spaces
120
kError(67100) << "MixDevice::setId(\"" << id << "\") . Invalid key - it might not contain spaces" << endl;
121
_id.replace(' ', '_');
125
void MixDevice::addPlaybackVolume(Volume &playbackVol)
127
// Hint: "_playbackVolume" gets COPIED from "playbackVol", because the copy-constructor actually copies the volume levels.
128
_playbackVolume = playbackVol;
129
_playbackVolume.setSwitchType(Volume::PlaybackSwitch);
132
void MixDevice::addCaptureVolume (Volume &captureVol)
134
_captureVolume = captureVol;
135
_captureVolume.setSwitchType(Volume::CaptureSwitch);
138
void MixDevice::addEnums(QList<QString*>& ref_enumList)
140
if ( ref_enumList.count() > 0 ) {
141
int maxEnumId = ref_enumList.count();
142
for (int i=0; i<maxEnumId; i++ ) {
143
// we have an enum. Lets set the names of the enum items in the MixDevice
144
// the enum names are assumed to be static!
145
_enumValues.append( *(ref_enumList.at(i)) );
151
MixDevice::~MixDevice() {
152
_enumValues.clear(); // The QString's inside will be auto-deleted, as they get unref'ed
155
Volume& MixDevice::playbackVolume()
157
return _playbackVolume;
160
Volume& MixDevice::captureVolume()
162
return _captureVolume;
166
void MixDevice::setEnumId(int enumId)
168
if ( enumId < _enumValues.count() ) {
169
_enumCurrentId = enumId;
173
unsigned int MixDevice::enumId()
175
return _enumCurrentId;
178
QList<QString>& MixDevice::enumValues() {
183
const QString& MixDevice::id() const {
188
bool MixDevice::isMuted() { return ( _playbackVolume.hasSwitch() && ! _playbackVolume.isSwitchActivated() ); }
189
void MixDevice::setMuted(bool value) { _playbackVolume.setSwitch( ! value ); }
190
bool MixDevice::isRecSource() { return ( _captureVolume.hasSwitch() && _captureVolume.isSwitchActivated() ); }
191
void MixDevice::setRecSource(bool value) { _captureVolume.setSwitch( value ); }
192
bool MixDevice::isEnum() { return ( ! _enumValues.empty() ); }
196
bool MixDevice::operator==(const MixDevice& other) const
198
return ( _id == other._id );
201
void MixDevice::setControlProfile(ProfControl* control)
203
_profControl = control;
206
ProfControl* MixDevice::controlProfile() {
211
* This method is currently only called on "kmixctrl --restore"
213
* Normally we have a working _volume object already, which is very important,
214
* because we need to read the minimum and maximum volume levels.
215
* (Another solution would be to "equip" volFromConfig with maxInt and minInt values).
217
void MixDevice::read( KConfig *config, const QString& grp )
219
if ( isEthereal() || isArtificial() ) {
220
kDebug(67100) << "MixDevice::read(): This MixDevice does not permit volume restoration (i.e. because it is handled lower down in the audio stack). Ignoring.";
223
devgrp.sprintf( "%s.Dev%s", grp.toAscii().data(), _id.toAscii().data() );
224
KConfigGroup cg = config->group( devgrp );
225
//kDebug(67100) << "MixDevice::read() of group devgrp=" << devgrp;
227
readPlaybackOrCapture(cg, false);
228
readPlaybackOrCapture(cg, true );
230
bool mute = cg.readEntry("is_muted", false);
233
bool recsrc = cg.readEntry("is_recsrc", false);
234
setRecSource( recsrc );
236
int enumId = cg.readEntry("enum_id", -1);
237
if ( enumId != -1 ) {
243
void MixDevice::readPlaybackOrCapture(const KConfigGroup& config, bool capture)
245
//Volume::ChannelMask chMask = Volume::MNONE;
247
Volume& volume = capture ? captureVolume() : playbackVolume();
249
for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
250
Volume::ChannelID chid = (Volume::ChannelID)i;
251
QString volstr (Volume::ChannelNameForPersistence[ chid ]);
252
if ( capture ) volstr += "Capture";
253
if ( config.hasKey(volstr) ) {
254
long volCfg = config.readEntry(volstr, 0);
255
//chMask |= _channelMaskEnum[i];
257
volume.setVolume(chid, volCfg);
258
} // if saved channel exists
259
} // for all channels
263
* called on "kmixctrl --save" and from the GUI's (currently only on exit)
265
void MixDevice::write( KConfig *config, const QString& grp )
267
if (isEthereal() || isArtificial()) {
268
kDebug(67100) << "MixDevice::write(): This MixDevice does not permit volume saving (i.e. because it is handled lower down in the audio stack). Ignoring.";
271
devgrp.sprintf( "%s.Dev%s", grp.toAscii().data(), _id.toAscii().data() );
272
KConfigGroup cg = config->group(devgrp);
273
// kDebug(67100) << "MixDevice::write() of group devgrp=" << devgrp;
275
writePlaybackOrCapture(cg, false);
276
writePlaybackOrCapture(cg, true );
278
cg.writeEntry("is_muted" , isMuted() );
279
cg.writeEntry("is_recsrc", isRecSource() );
280
cg.writeEntry("name", _name);
282
cg.writeEntry("enum_id", enumId() );
287
void MixDevice::writePlaybackOrCapture(KConfigGroup& config, bool capture)
289
Volume& volume = capture ? captureVolume() : playbackVolume();
291
for ( int i=0; i<= Volume::CHIDMAX; i++ ) {
292
if ( volume._chmask & Volume::_channelMaskEnum[i] ) {
293
Volume::ChannelID chid = (Volume::ChannelID)i;
295
volume.getVolume( chid );
296
QString volstr (Volume::ChannelNameForPersistence[ chid ]);
297
if ( capture ) volstr += "Capture";
298
config.writeEntry(volstr , (int)volume.getVolume( chid ) );
299
} // if supported channel
300
} // for all channels
305
#include "mixdevice.moc"