libGizmod/AlsaMixer.cpp

Go to the documentation of this file.
00001 
00012 /*
00013   
00014   Copyright (c) 2007, Tim Burrell
00015   Licensed under the Apache License, Version 2.0 (the "License");
00016   you may not use this file except in compliance with the License.
00017   You may obtain a copy of the License at 
00018 
00019         http://www.apache.org/licenses/LICENSE-2.0
00020 
00021   Unless required by applicable law or agreed to in writing, software
00022   distributed under the License is distributed on an "AS IS" BASIS,
00023   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00024   See the License for the specific language governing permissions and 
00025   limitations under the License. 
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 // Callbacks
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         // grab new info from the sound card
00069         populateInfo();
00070         
00071         // fire the event
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         // remember the old state
00079         mOldState = *this;
00080         
00081         // success
00082         return 0;
00083 }
00084 
00091 int AlsaMixer::signalMixerEvent() {
00092         return mixerElemCallback(mMixerElement, 0);
00093 }
00094 
00096 // Construction
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 // Class Body
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         // fire the event
00155         static_cast<Alsa *>(mpiAlsa)->onAlsaEventMixerElementAttach(AlsaEvent(ALSAEVENT_MIXERELEMENT_ATTACH), static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);      
00156 
00157         // populate
00158         populateInfo();
00159 }
00160 
00166 void AlsaMixer::populateInfo() {
00167         // get the data
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         // Playback volume
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                         // fix for alsa bug!
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         // Playback switch
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         // Capture volume
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                         // fix for alsa bug!
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         // Capture switch
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         // fire the event
00343         static_cast<Alsa *>(mpiAlsa)->onAlsaEventMixerElementDetach(AlsaEvent(ALSAEVENT_MIXERELEMENT_DETACH), static_cast<AlsaSoundCard &>(*mpiSoundCard), *this);      
00344 }

Generated on Wed Nov 7 10:04:16 2007 for gizmod by  doxygen 1.5.3