00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "AlsaMixer.hpp"
00030 #include "Alsa.hpp"
00031 #include "../libH/Debug.hpp"
00032 #include "../libH/Exception.hpp"
00033 #include <boost/shared_ptr.hpp>
00034
00035 using namespace std;
00036 using namespace boost;
00037 using namespace H;
00038 using namespace Gizmod;
00039
00041
00043
00052 int AlsaMixer::MixerElemCallback(snd_mixer_elem_t * MixerElement, unsigned int EventMask) {
00053 AlsaMixer * pAlsaMixer = static_cast<AlsaMixer *>(snd_mixer_elem_get_callback_private(MixerElement));
00054 if (!pAlsaMixer)
00055 return 0;
00056 return pAlsaMixer->mixerElemCallback(MixerElement, EventMask);
00057 }
00058
00067 int AlsaMixer::mixerElemCallback(snd_mixer_elem_t * MixerElement, unsigned int EventMask) {
00068
00069 populateInfo();
00070
00071
00072 AlsaEvent Event(ALSAEVENT_MIXERELEMENT_CHANGE, EventMask);
00073 AlsaMixerElements::buildEventFromMixerStates(Event, mOldState, *this);
00074 Alsa * pAlsa = static_cast<Alsa *>(mpiAlsa);
00075 pAlsa->_onAlsaEventMixerElementChange(Event, static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);
00076 pAlsa->onAlsaEventMixerElementChange(Event, static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);
00077
00078
00079 mOldState = *this;
00080
00081
00082 return 0;
00083 }
00084
00091 int AlsaMixer::signalMixerEvent() {
00092 return mixerElemCallback(mMixerElement, 0);
00093 }
00094
00096
00098
00102 AlsaMixer::AlsaMixer() {
00103 mpiAlsa = NULL;
00104 mMixerElement = NULL;
00105 mMixerID = -1;
00106 mpiSoundCard = NULL;
00107 }
00108
00112 AlsaMixer::AlsaMixer(AlsaSoundCardInterface * piSoundCard, snd_mixer_elem_t * MixerElement, std::string MixerName, std::string MixerNameUnique, unsigned int MixerID) {
00113 mpiAlsa = piSoundCard->getAlsa();
00114 mpiSoundCard = piSoundCard;
00115 mMixerElement = MixerElement;
00116 mMixerName = MixerName;
00117 mMixerNameUnique = MixerNameUnique;
00118 mMixerID = MixerID;
00119
00120 init();
00121 }
00122
00126 AlsaMixer::~AlsaMixer() {
00127 shutdown();
00128 }
00129
00131
00133
00138 std::string AlsaMixer::getName() const {
00139 return mMixerNameUnique;
00140 }
00141
00146 std::string AlsaMixer::getNameShort() const {
00147 return mMixerName;
00148 }
00149
00153 void AlsaMixer::init() {
00154
00155 static_cast<Alsa *>(mpiAlsa)->onAlsaEventMixerElementAttach(AlsaEvent(ALSAEVENT_MIXERELEMENT_ATTACH), static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);
00156
00157
00158 populateInfo();
00159 }
00160
00166 void AlsaMixer::populateInfo() {
00167
00168 long tempMin, tempMax, temp;
00169 IsActive = snd_mixer_selem_is_active(mMixerElement);
00170 HasCommonVolume = snd_mixer_selem_has_common_volume(mMixerElement);
00171 HasPlaybackVolume = snd_mixer_selem_has_playback_volume(mMixerElement);
00172 HasPlaybackVolumeJoined = snd_mixer_selem_has_playback_volume_joined(mMixerElement);
00173 HasCaptureVolume = snd_mixer_selem_has_capture_volume(mMixerElement);
00174 HasCaptureVolumeJoined = snd_mixer_selem_has_capture_volume_joined(mMixerElement);
00175 HasCommonSwitch = snd_mixer_selem_has_common_switch(mMixerElement);
00176 HasPlaybackSwitch = snd_mixer_selem_has_playback_switch(mMixerElement);
00177 HasPlaybackSwitchJoined = snd_mixer_selem_has_playback_switch_joined(mMixerElement);
00178 HasCaptureSwitch = snd_mixer_selem_has_capture_switch(mMixerElement);
00179 HasCaptureSwitchJoined = snd_mixer_selem_has_capture_switch_joined(mMixerElement);
00180 HasCaptureSwitchExclusive = snd_mixer_selem_has_capture_switch_exclusive(mMixerElement);
00181
00182
00183 if ( (HasPlaybackVolume) || (HasPlaybackVolumeJoined) || (HasCommonVolume) ) {
00184 if (snd_mixer_selem_get_playback_volume_range(mMixerElement, &tempMin, &tempMax) >= 0) {
00185 VolumePlaybackMin = tempMin;
00186 VolumePlaybackMax = tempMax;
00187 }
00188
00189 if (snd_mixer_selem_get_playback_volume(mMixerElement, SND_MIXER_SCHN_MONO, &temp) >= 0) {
00190
00191 if (temp != 0) {
00192 VolumePlayback = temp;
00193 VolumePlaybackPercent = (float) (VolumePlayback - VolumePlaybackMin) / (float) (VolumePlaybackMax - VolumePlaybackMin) * 100.0f;
00194 }
00195 }
00196 } else {
00197 VolumePlaybackMin = VolumePlaybackMax = VolumePlayback = 0;
00198 VolumePlaybackPercent = 0.0f;
00199 }
00200
00201
00202 if ( (HasPlaybackSwitch) || (HasPlaybackSwitchJoined) || (HasCommonSwitch) ) {
00203 int tVal;
00204 if (snd_mixer_selem_get_playback_switch(mMixerElement, SND_MIXER_SCHN_MONO, &tVal) >= 0)
00205 SwitchPlayback = tVal;
00206 } else {
00207 SwitchPlayback = false;
00208 }
00209
00210
00211 if ( (HasCaptureVolume) || (HasCaptureVolumeJoined) || (HasCommonVolume) ) {
00212 if (snd_mixer_selem_get_capture_volume_range(mMixerElement, &tempMin, &tempMax) >= 0) {
00213 VolumeCaptureMin = tempMin;
00214 VolumeCaptureMax = tempMax;
00215 }
00216
00217 if (snd_mixer_selem_get_capture_volume(mMixerElement, SND_MIXER_SCHN_MONO, &temp) >= 0) {
00218
00219 if (temp != 0) {
00220 VolumeCapture = temp;
00221 VolumeCapturePercent = (float) (VolumeCapture - VolumeCaptureMin) / (float) (VolumeCaptureMax - VolumeCaptureMin) * 100.0f;
00222 }
00223 }
00224 } else {
00225 VolumeCaptureMin = VolumeCaptureMax = VolumeCapture = 0;
00226 VolumeCapturePercent = 0.0f;
00227 }
00228
00229
00230 if ( (HasCaptureSwitch) || (HasCaptureSwitchJoined) || (HasCommonSwitch) ) {
00231 int tVal;
00232 if (snd_mixer_selem_get_capture_switch(mMixerElement, SND_MIXER_SCHN_MONO, &tVal) >= 0)
00233 SwitchCapture = tVal;
00234 } else {
00235 SwitchCapture = false;
00236 }
00237 }
00238
00244 bool AlsaMixer::setSwitchCapture(bool Enable) {
00245 if (snd_mixer_selem_set_capture_switch_all(mMixerElement, Enable) < 0)
00246 return false;
00247 SwitchCapture = Enable;
00248 mpiSoundCard->addManualUpdater(this);
00249 return true;
00250 }
00251
00257 bool AlsaMixer::setSwitchPlayback(bool Enable) {
00258 if (snd_mixer_selem_set_playback_switch_all(mMixerElement, Enable) < 0)
00259 return false;
00260 SwitchPlayback = Enable;
00261 mpiSoundCard->addManualUpdater(this);
00262 return true;
00263 }
00264
00270 bool AlsaMixer::setVolumeCapture(long Volume) {
00271 if (Volume < VolumeCaptureMin)
00272 Volume = VolumeCaptureMin;
00273 else if (Volume > VolumeCaptureMax)
00274 Volume = VolumeCaptureMax;
00275 if (snd_mixer_selem_set_capture_volume_all(mMixerElement, Volume) < 0)
00276 return false;
00277 VolumeCapture = Volume;
00278 VolumeCapturePercent = float(VolumeCapture - VolumeCaptureMin) / float(VolumeCaptureMax - VolumeCaptureMin) * 100.0f;
00279 mpiSoundCard->addManualUpdater(this);
00280 return true;
00281 }
00282
00288 bool AlsaMixer::setVolumeCapturePercent(float Percent) {
00289 if (Percent < 0.0f)
00290 Percent = 0.0f;
00291 else if (Percent > 100.0f)
00292 Percent = 100.0f;
00293 long NewVolume = (long) (Percent / 100.0f * (VolumeCaptureMax - VolumeCaptureMin)) + VolumeCaptureMin;
00294 if (snd_mixer_selem_set_capture_volume_all(mMixerElement, NewVolume) < 0)
00295 return false;
00296 VolumeCapturePercent = Percent;
00297 VolumeCapture = NewVolume;
00298 return true;
00299 }
00300
00306 bool AlsaMixer::setVolumePlayback(long Volume) {
00307 if (Volume < VolumePlaybackMin)
00308 Volume = VolumePlaybackMin;
00309 else if (Volume > VolumePlaybackMax)
00310 Volume = VolumePlaybackMax;
00311 if (snd_mixer_selem_set_playback_volume_all(mMixerElement, Volume) < 0)
00312 return false;
00313 VolumePlayback = Volume;
00314 VolumePlaybackPercent = float(VolumePlayback - VolumePlaybackMin) / float(VolumePlaybackMax - VolumePlaybackMin) * 100.0f;
00315 mpiSoundCard->addManualUpdater(this);
00316 return true;
00317 }
00318
00324 bool AlsaMixer::setVolumePlaybackPercent(float Percent) {
00325 if (Percent < 0.0f)
00326 Percent = 0.0f;
00327 else if (Percent > 100.0f)
00328 Percent = 100.0f;
00329 long NewVolume = (long) (Percent / 100.0f * (VolumePlaybackMax - VolumePlaybackMin)) + VolumePlaybackMin;
00330 if (snd_mixer_selem_set_playback_volume_all(mMixerElement, NewVolume) < 0)
00331 return false;
00332 VolumePlaybackPercent = Percent;
00333 VolumePlayback = NewVolume;
00334 mpiSoundCard->addManualUpdater(this);
00335 return true;
00336 }
00337
00341 void AlsaMixer::shutdown() {
00342
00343 static_cast<Alsa *>(mpiAlsa)->onAlsaEventMixerElementDetach(AlsaEvent(ALSAEVENT_MIXERELEMENT_DETACH), static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);
00344 }