OSDN Git Service

ee5784f70f3d7a00a56d373d9ba4b6b2770b49c5
[kde/kde-extraapps.git] / kmix / core / mixdevice.h
1 //-*-C++-*-
2 /*
3  * KMix -- KDE's full featured mini mixer
4  *
5  * Copyright Christian Esken <esken@kde.org>
6  *
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.
11  *
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.
16  *
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.
20  */
21 #ifndef MixDevice_h
22 #define MixDevice_h
23
24 #include <memory>
25
26 //KMix
27 #include "core/MediaController.h"
28 #include "core/volume.h"
29
30 class Mixer;
31 class MixSet;
32 class ProfControl;
33 class DBusControlWrapper;
34
35 // KDE
36 #include <kconfig.h>
37 #include <kconfiggroup.h>
38
39 // Qt
40 #include <QList>
41 #include <QObject>
42 #include <QString>
43
44 /**
45  * This is the abstraction of a single control of a sound card, e.g. the PCM control. A control
46  * can contain the 5 following subcontrols: playback-volume, capture-volume, playback-switch,
47  * capture-switch and enumeration.
48
49    The class is called MixDevice for historical reasons. Today it is just the Synonym for "Control".
50
51    Design hint: In the past I (esken) considered merging the MixDevice and Volume classes.
52                 I finally decided against it, as it seems better to have the MixDevice being the container
53                 for the embedded subcontrol(s). These could be either Volume, Enum or some virtual MixDevice.
54  */
55 class MixDevice : public QObject
56 {
57 Q_OBJECT
58
59 public:
60     // For each ChannelType a special icon exists
61     enum ChannelType { AUDIO = 1,
62                        BASS,
63                        CD,
64                        EXTERNAL,
65                        MICROPHONE,
66                        MIDI,
67                        RECMONITOR,
68                        TREBLE,
69                        UNKNOWN,
70                        VOLUME,
71                        VIDEO,
72                        SURROUND,
73                        HEADPHONE,
74                        DIGITAL,
75                        AC97,
76                        SURROUND_BACK,
77                        SURROUND_LFE,
78                        SURROUND_CENTERFRONT,
79                        SURROUND_CENTERBACK,
80                        SPEAKER,
81                        MICROPHONE_BOOST,
82                        MICROPHONE_FRONT_BOOST,
83                        MICROPHONE_FRONT,
84                        KMIX_COMPOSITE,
85                        
86                        APPLICATION_STREAM,
87                        // Some specific applications
88                        APPLICATION_AMAROK,
89                        APPLICATION_BANSHEE,
90                        APPLICATION_XMM2,
91                        APPLICATION_TOMAHAWK,
92                        APPLICATION_CLEMENTINE,
93                        // Hint: VLC still has compatibility problems:
94                        //  2.0 is not detected
95                        //  2.2-nightly has volume issues (total overdrive)
96                        APPLICATION_VLC,
97                      };
98
99    enum SwitchType { OnOff, Mute, Capture, Activator };
100
101    /**
102     * Constructor for a MixDevice.
103     * After having constructed a MixDevice, you <b>must</b> add it to the ControlPool
104     * by calling addToPool(). You may then <b>not</b> delete this object.
105     *
106     * @par mixer The mixer this control belongs to
107     * @par id  Defines the ID, e.g. used in looking up the keys in kmixrc. Also it is used heavily inside KMix as unique key. 
108     *      It is advised to set a nice name, like 'PCM:2', which would  mean 
109     *      "2nd PCM device of the sound card". The ID's may NOT contain whitespace.
110     *       The Creator (normally the backend) MUST pass distinct ID's for each MixDevices of one card.
111     *
112     *      Virtual Controls (controls not created by a backend) are prefixed with "KMix::", e.g.
113     *      "KMix::RecSelector:0"
114     *  @par name is the readable name. This one is presented to the user in the GUI
115     *  @par type The control type. It is only used to find an appropriate icon
116     */
117    MixDevice( Mixer* mixer, const QString& id, const QString& name, ChannelType type );
118    MixDevice( Mixer* mixer, const QString& id, const QString& name, const QString& iconName = "", MixSet* moveDestinationMixSet = 0 );
119    ~MixDevice();
120
121    void close();
122
123    std::shared_ptr<MixDevice> addToPool();
124
125    const QString& iconName() const { return _iconName; }
126
127    void addPlaybackVolume(Volume &playbackVol);
128    void addCaptureVolume (Volume &captureVol);
129    void addEnums (QList<QString*>& ref_enumList);
130    
131    // Media controls. New for KMix 4.0
132    MediaController* getMediaController();
133    // TODO move all media player controls to the MediaController class
134    int mediaPlay();
135    int mediaPrev();
136    int mediaNext();
137
138    // Returns a user readable name of the control.
139    QString   readableName()         { return _name; }
140    // Sets a user readable name for the control.
141    void      setReadableName(QString& name)      { _name = name; }
142
143    QString configGroupName(QString prefix);
144
145    /**
146     * Returns an ID of this MixDevice, as passed in the constructor. The Creator (normally the backend) 
147     * MUST ensure that all MixDevices's of one card have unique ID's.
148     * The ID is used through the whole KMix application (including the config file) for identifying controls.
149     */
150  
151    const QString& id() const;
152    QString getFullyQualifiedId();
153
154    /**
155     * Returns the DBus path for this MixDevice
156     */
157    const QString dbusPath();
158
159    // Returns the associated mixer
160    Mixer* mixer() { return _mixer; }
161
162    // operator==() is used currently only for duplicate detection with QList's contains() method
163    bool operator==(const MixDevice& other) const;
164
165    // Methods for handling the switches. This methods are useful, because the Switch in the Volume object
166    // is an abstract concept. It places no interpretation on the meaning of the switch (e.g. does "switch set" mean
167    // "mute on", or does it mean "playback on", or "Capture active", or ...
168    virtual bool isMuted();
169    virtual bool isVirtuallyMuted();
170    virtual void setMuted(bool value);
171    virtual bool hasMuteSwitch();
172    virtual void toggleMute();
173    virtual bool isRecSource();
174    virtual bool isNotRecSource();
175    virtual void setRecSource(bool value);
176    virtual bool isEnum();
177    /**
178     * Returns whether this is an application stream.
179     */
180    virtual bool isApplicationStream() const { return _applicationStream; };
181    /**
182     * Mark this MixDevice as application stream
183     */
184     void setApplicationStream(bool applicationStream) { _applicationStream = applicationStream; }
185    
186    bool isMovable() const
187    {
188        return (0 != _moveDestinationMixSet);
189    }
190    MixSet *getMoveDestinationMixSet() const
191    {
192        return _moveDestinationMixSet;
193    }
194
195    bool isArtificial()  const
196    {
197        return _artificial;
198    }
199    void setArtificial(bool artificial)
200    {
201        _artificial = artificial;
202    }
203
204    void setControlProfile(ProfControl* control);
205    ProfControl* controlProfile();
206    
207    virtual Volume& playbackVolume();
208    virtual Volume& captureVolume();
209
210    void setEnumId(int);
211    unsigned int enumId();
212    QList<QString>& enumValues();
213
214    bool hasPhysicalMuteSwitch();
215    
216    bool read( KConfig *config, const QString& grp );
217    bool write( KConfig *config, const QString& grp );
218    int getUserfriendlyVolumeLevel();
219
220    void increaseOrDecreaseVolume(bool decrease, Volume::VolumeTypeFlag volumeType);
221
222 protected:
223    void init( Mixer* mixer, const QString& id, const QString& name, const QString& iconName, MixSet* moveDestinationMixSet );
224
225 private:
226   QString getVolString(Volume::ChannelID chid, bool capture);
227    Mixer *_mixer;
228    Volume _playbackVolume;
229    Volume _captureVolume;
230    int _enumCurrentId;
231    QList<QString> _enumValues; // A MixDevice, that is an ENUM, has these _enumValues
232
233    DBusControlWrapper *_dbusControlWrapper;
234    MediaController* mediaController;
235
236    // A virtual control. It will not be saved/restored and/or doesn't get shortcuts
237    // Actually we discriminate those "virtual" controls in artificial controls and dynamic controls:
238    // Type        Shortcut  Restore
239    // Artificial:    yes       no    Virtual::GlobalMaster or Virtual::CaptureGroup_3   (controls that are constructed artificially from other controls)
240    // Dynamic   :     no       no    Controls that come and go, like Pulse Stream controls
241    bool _artificial;
242    MixSet *_moveDestinationMixSet;
243    QString _iconName;
244    bool _applicationStream;
245
246    QString _name;   // Channel name
247    QString _id;     // Primary key, used as part in config file keys
248    ProfControl *_profControl;
249
250    void readPlaybackOrCapture(const KConfigGroup& config, bool capture);
251    void writePlaybackOrCapture(KConfigGroup& config, bool capture);
252 };
253
254 #endif