2
* KMix -- KDE's full featured mini mixer
4
* Copyright 2006-2007 Christian Esken <esken@kde.org>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Library General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Library General Public License for more details.
16
* You should have received a copy of the GNU Library General Public
17
* License along with this program; if not, write to the Free
18
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
#include "mixer_backend.h"
24
// for the "ERR_" declartions, #include mixer.h
25
#include "core/mixer.h"
28
#include "mixer_backend_i18n.cpp"
30
Mixer_Backend::Mixer_Backend(Mixer *mixer, int device) :
31
m_devnum (device) , m_isOpen(false), m_recommendedMaster(0), _mixer(mixer), _pollingTimer(0)
34
// In all cases create a QTimer. We will use it once as a singleShot(), even if something smart
35
// like ::select() is possible (as in ALSA).
36
_pollingTimer = new QTimer(); // will be started on open() and stopped on close()
37
connect( _pollingTimer, SIGNAL(timeout()), this, SLOT(readSetFromHW()));
40
Mixer_Backend::~Mixer_Backend()
43
qDeleteAll(m_mixDevices);
48
bool Mixer_Backend::openIfValid() {
51
if ( ret == 0 && (m_mixDevices.count() > 0 || _mixer->isDynamic())) {
53
// A better ID is now calculated in mixertoolbox.cpp, and set via setID(),
54
// but we want a somehow usable fallback just in case.
56
if ( needsPolling() ) {
57
_pollingTimer->start(50);
60
// The initial state must be read manually
61
QTimer::singleShot( 50, this, SLOT( readSetFromHW() ) );
70
bool Mixer_Backend::isOpen() {
75
* Queries the backend driver whether there are new changes in any of the controls.
76
* If you cannot find out for a backend, return "true" - this is also the default implementation.
77
* @return true, if there are changes. Otherwise false is returned.
79
bool Mixer_Backend::prepareUpdateFromHW() {
85
* After calling this, readSetFromHW() will do a complete update. This will
86
* trigger emitting the appropriate signals like controlChanged().
88
* This method is useful, if you need to get a "refresh signal" - used at:
89
* 1) Start of KMix - so that we can be sure an initial signal is emitted
90
* 2) When reconstructing any MixerWidget (e.g. DockIcon after applying preferences)
92
void Mixer_Backend::readSetFromHWforceUpdate() const {
93
_readSetFromHWforceUpdate = true;
98
You can call this to retrieve the freshest information from the mixer HW.
99
This method is also called regulary by the mixer timer.
101
void Mixer_Backend::readSetFromHW()
103
bool updated = prepareUpdateFromHW();
104
if ( (! updated) && (! _readSetFromHWforceUpdate) ) {
105
// Some drivers (ALSA) are smart. We don't need to run the following
106
// time-consuming update loop if there was no change
107
kDebug(67100) << "Mixer::readSetFromHW(): smart-update-tick";
110
_readSetFromHWforceUpdate = false;
112
int mdCount = m_mixDevices.count();
113
for(int i=0; i<mdCount ; ++i )
115
MixDevice *md = m_mixDevices[i];
116
readVolumeFromHW( md->id(), md );
119
* This could be reworked:
120
* Plan: Read everything (incuding enum's) in readVolumeFromHW().
121
* readVolumeFromHW() should then be renamed to readHW().
123
md->setEnumId( enumIdHW(md->id()) );
126
emit controlChanged();
130
* Return the MixDevice, that would qualify best as MasterDevice. The default is to return the
131
* first device in the device list. Backends can override this (i.e. the ALSA Backend does so).
132
* The users preference is NOT returned by this method - see the Mixer class for that.
134
MixDevice* Mixer_Backend::recommendedMaster() {
135
if ( m_recommendedMaster != 0 ) {
136
return m_recommendedMaster; // Backend has set a recommended master. Thats fine.
137
} // recommendation from Backend
138
else if ( m_mixDevices.count() > 0 ) {
139
return m_mixDevices.at(0); // Backend has NOT set a recommended master. Evil backend => lets help out.
140
} //first device (if exists)
142
if ( !_mixer->isDynamic()) {
143
// This should never ever happen, as KMix doe NOT accept soundcards without controls
144
kError(67100) << "Mixer_Backend::recommendedMaster(): returning invalid master. This is a bug in KMix. Please file a bug report stating how you produced this." << endl;
146
return (MixDevice*)0;
151
* Sets the ID of the currently selected Enum entry.
152
* This is a dummy implementation - if the Mixer backend
153
* wants to support it, it must implement the driver specific
154
* code in its subclass (see Mixer_ALSA.cpp for an example).
156
void Mixer_Backend::setEnumIdHW(const QString& , unsigned int) {
161
* Return the ID of the currently selected Enum entry.
162
* This is a dummy implementation - if the Mixer backend
163
* wants to support it, it must implement the driver specific
164
* code in its subclass (see Mixer_ALSA.cpp for an example).
166
unsigned int Mixer_Backend::enumIdHW(const QString& ) {
171
* Move the stream to a new destination
173
bool Mixer_Backend::moveStream( const QString& id, const QString& destId ) {
179
void Mixer_Backend::errormsg(int mixer_error)
182
l_s_errText = errorText(mixer_error);
183
kError() << l_s_errText << "\n";
186
int Mixer_Backend::id2num(const QString& id)
191
QString Mixer_Backend::errorText(int mixer_error)
196
case Mixer::ERR_PERM:
197
l_s_errmsg = i18n("kmix:You do not have permission to access the mixer device.\n" \
198
"Please check your operating systems manual to allow the access.");
200
case Mixer::ERR_WRITE:
201
l_s_errmsg = i18n("kmix: Could not write to mixer.");
203
case Mixer::ERR_READ:
204
l_s_errmsg = i18n("kmix: Could not read from mixer.");
206
case Mixer::ERR_OPEN:
207
l_s_errmsg = i18n("kmix: Mixer cannot be found.\n" \
208
"Please check that the soundcard is installed and that\n" \
209
"the soundcard driver is loaded.\n");
212
l_s_errmsg = i18n("kmix: Unknown error. Please report how you produced this error.");
221
#include "mixer_backend.moc"