tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / bin / desklink / MixerControl.cpp
blobdea3fa52e60ec99f3f79286418ee5f15a08680df
1 /*
2 * Copyright 2003-2013, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Jérôme Duval
7 * François Revol
8 * Axel Dörfler, axeld@pinc-software.de.
9 * Puck Meerburg, puck@puckipedia.nl
10 * Dario Casalinuovo, b.vitruvio@gmail.com
14 #include "MixerControl.h"
16 #include <string.h>
18 #include <Debug.h>
19 #include <ParameterWeb.h>
22 MixerControl::MixerControl(int32 volumeWhich)
24 fVolumeWhich(volumeWhich),
25 fGainMediaNode(media_node::null),
26 fParameterWeb(NULL),
27 fMixerParameter(NULL),
28 fMuteParameter(NULL),
29 fMin(0.0f),
30 fMax(0.0f),
31 fStep(0.0f)
36 MixerControl::~MixerControl()
38 _Disconnect();
42 bool
43 MixerControl::Connect(int32 volumeWhich, float* _value, const char** _error)
45 fVolumeWhich = volumeWhich;
47 _Disconnect();
49 status_t status = B_OK;
50 // BMediaRoster::Roster() doesn't set it if all is ok
51 const char* errorString = NULL;
52 BMediaRoster* roster = BMediaRoster::Roster(&status);
54 if (BMediaRoster::IsRunning() && roster != NULL
55 && status == B_OK) {
56 switch (volumeWhich) {
57 case VOLUME_USE_MIXER:
58 status = roster->GetAudioMixer(&fGainMediaNode);
59 break;
60 case VOLUME_USE_PHYS_OUTPUT:
61 status = roster->GetAudioOutput(&fGainMediaNode);
62 break;
64 if (status == B_OK) {
65 status = roster->GetParameterWebFor(fGainMediaNode, &fParameterWeb);
66 if (status == B_OK) {
67 // Finding the Mixer slider in the audio output ParameterWeb
68 int32 numParams = fParameterWeb->CountParameters();
69 BParameter* p = NULL;
70 bool foundMixerLabel = false;
71 for (int i = 0; i < numParams; i++) {
72 p = fParameterWeb->ParameterAt(i);
74 // assume the mute preceeding master gain control
75 if (!strcmp(p->Kind(), B_MUTE))
76 fMuteParameter = p;
78 PRINT(("BParameter[%i]: %s\n", i, p->Name()));
79 if (volumeWhich == VOLUME_USE_MIXER) {
80 if (!strcmp(p->Kind(), B_MASTER_GAIN))
81 break;
82 } else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) {
83 /* not all cards use the same name, and
84 * they don't seem to use Kind() == B_MASTER_GAIN
86 if (!strcmp(p->Kind(), B_MASTER_GAIN))
87 break;
88 PRINT(("not MASTER_GAIN \n"));
90 /* some audio card
92 if (!strcmp(p->Name(), "Master"))
93 break;
94 PRINT(("not 'Master' \n"));
96 /* some Ensonic card have all controls names 'Volume', so
97 * need to fint the one that has the 'Mixer' text label
99 if (foundMixerLabel && !strcmp(p->Name(), "Volume"))
100 break;
101 if (!strcmp(p->Name(), "Mixer"))
102 foundMixerLabel = true;
103 PRINT(("not 'Mixer' \n"));
105 #if 0
106 //if (!strcmp(p->Name(), "Master")) {
107 if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
108 for (; i < numParams; i++) {
109 p = fParamWeb->ParameterAt(i);
110 if (strcmp(p->Kind(), B_MASTER_GAIN))
111 p = NULL;
112 else
113 break;
115 break;
116 } else
117 p = NULL;
118 #endif
119 p = NULL;
121 if (p == NULL) {
122 errorString = volumeWhich ? "Could not find the soundcard"
123 : "Could not find the mixer";
124 } else if (p->Type() != BParameter::B_CONTINUOUS_PARAMETER) {
125 errorString = volumeWhich ? "Soundcard control unknown"
126 : "Mixer control unknown";
127 } else {
128 fMixerParameter = static_cast<BContinuousParameter*>(p);
129 fMin = fMixerParameter->MinValue();
130 fMax = fMixerParameter->MaxValue();
131 fStep = fMixerParameter->ValueStep();
133 if (_value != NULL) {
134 float volume;
135 bigtime_t lastChange;
136 size_t size = sizeof(float);
137 fMixerParameter->GetValue(&volume, &size, &lastChange);
139 *_value = volume;
142 } else {
143 errorString = "No parameter web";
144 fParameterWeb = NULL;
146 } else
147 errorString = volumeWhich ? "No Audio output" : "No Mixer";
149 } else
150 errorString = "Media services not running";
152 if (status != B_OK)
153 fGainMediaNode = media_node::null;
155 if (errorString) {
156 fprintf(stderr, "MixerControl: %s.\n", errorString);
157 if (_error)
158 *_error = errorString;
160 if (fMixerParameter == NULL && _value != NULL)
161 *_value = 0;
163 return errorString == NULL;
167 bool
168 MixerControl::Connected()
170 return fGainMediaNode != media_node::null;
174 int32
175 MixerControl::VolumeWhich() const
177 return fVolumeWhich;
181 void
182 MixerControl::SetMute(bool muted)
184 if (fMuteParameter == NULL)
185 return;
187 int32 mute = muted ? 1 : 0;
188 fMuteParameter->SetValue(&mute, sizeof(int32), system_time());
192 bool
193 MixerControl::Mute()
195 if (fMuteParameter == NULL)
196 return false;
198 int32 mute = 0;
199 bigtime_t lastChange = 0;
200 size_t size = sizeof(int32);
201 fMuteParameter->GetValue(&mute, &size, &lastChange);
202 return mute != 0;
206 float
207 MixerControl::Volume() const
209 if (fMixerParameter == NULL)
210 return 0.0f;
212 float volume = 0;
213 bigtime_t lastChange;
214 size_t size = sizeof(float);
215 fMixerParameter->GetValue(&volume, &size, &lastChange);
217 return volume;
221 void
222 MixerControl::SetVolume(float volume)
224 if (fMixerParameter == NULL)
225 return;
227 if (volume < fMin)
228 volume = fMin;
229 else if (volume > fMax)
230 volume = fMax;
232 if (volume != Volume())
233 fMixerParameter->SetValue(&volume, sizeof(float), system_time());
237 void
238 MixerControl::ChangeVolumeBy(float value)
240 if (fMixerParameter == NULL || value == 0.0f)
241 return;
243 float volume = Volume();
244 SetVolume(volume + value);
248 void
249 MixerControl::_Disconnect()
251 delete fParameterWeb;
252 fParameterWeb = NULL;
253 fMixerParameter = NULL;
255 BMediaRoster* roster = BMediaRoster::CurrentRoster();
256 if (roster != NULL && fGainMediaNode != media_node::null)
257 roster->ReleaseNode(fGainMediaNode);
259 fGainMediaNode = media_node::null;