00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #ifdef __HAVE_MIXER__
00034 #include "mmsmedia/mmsaudioctrl.h"
00035 
00036 snd_mixer_t         *MMSAudioCtrl::handle = NULL;
00037 string              MMSAudioCtrl::card = "default";
00038 int                 MMSAudioCtrl::volume = -1;      
00039 long                MMSAudioCtrl::xval = -1;         
00040 bool                MMSAudioCtrl::muteFlag = false; 
00041 long                MMSAudioCtrl::pmin;             
00042 long                MMSAudioCtrl::pmax;             
00043 string              MMSAudioCtrl::channel = "";
00044 snd_mixer_elem_t    *MMSAudioCtrl::elem = NULL;
00045 bool                MMSAudioCtrl::isSwitchable = false;
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 MMSAudioCtrl::MMSAudioCtrl(string channel) {
00058     int     err;
00059 
00060     if(this->channel=="") {
00061         this->channel=channel;
00062     }
00063 
00064     if (!this->handle) {
00065         
00066         if ((err = snd_mixer_open(&(this->handle), 0)) < 0)
00067             throw MMSAudioCtrlError(err,"snd_mixer_open() failed");
00068 
00069         
00070         if ((err = snd_mixer_attach(this->handle, this->card.c_str())) < 0) {
00071             snd_mixer_close(this->handle);
00072             throw MMSAudioCtrlError(err,"snd_mixer_attach() with card = '"
00073                                             + this->card + "' failed");
00074         }
00075 
00076         
00077         if ((err = snd_mixer_selem_register(this->handle, NULL, NULL)) < 0) {
00078             snd_mixer_close(this->handle);
00079             string s = snd_strerror(err);
00080             throw MMSAudioCtrlError(err,"snd_mixer_selem_register() failed with '" + s + "'");
00081         }
00082 
00083         
00084         if ((err = snd_mixer_load(this->handle)) < 0) {
00085             snd_mixer_close(this->handle);
00086             string s = snd_strerror(err);
00087             throw MMSAudioCtrlError(err,"snd_mixer_load() failed with '" + s + "'");
00088         }
00089     }
00090 
00091     if (!this->elem) {
00092         
00093         for (this->elem = snd_mixer_first_elem(this->handle);
00094              this->elem;
00095              this->elem = snd_mixer_elem_next(this->elem)) {
00096 
00097             string mix = snd_mixer_selem_get_name(this->elem);
00098             DEBUGMSG("MMSMedia", "got mixer channel: %s", mix.c_str());
00099             
00100             if (!snd_mixer_selem_is_active(this->elem))
00101                 continue;
00102 
00103             
00104             if (!snd_mixer_selem_has_playback_volume(this->elem))
00105                 continue;
00106 
00107             if (this->channel!="") {
00108                 if(strcmp(this->channel.c_str(),snd_mixer_selem_get_name(this->elem))!=0)
00109                     continue;
00110             }
00111 
00112             
00113             
00114             snd_mixer_selem_get_playback_volume_range(this->elem, &(this->pmin), &(this->pmax));
00115 
00116             
00117             isSwitchable = (snd_mixer_selem_has_playback_switch(elem) > 0);
00118 
00119             
00120             getVolume();
00121 
00122             return;
00123         }
00124 
00125         throw MMSAudioCtrlError(0,"no element found");
00126     }
00127 }
00128 
00129 
00130 
00131 
00132 MMSAudioCtrl::~MMSAudioCtrl() {
00133     
00134 }
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 void MMSAudioCtrl::setVolume(int count) {
00145     
00146     this->xval = -1;
00147     this->volume = count;
00148     if (this->volume < 0) this->volume = 0;
00149     if (this->volume > 100) this->volume = 100;
00150     if (this->volume == 0)
00151         this->xval = this->pmin;
00152     else
00153     if (this->volume == 100)
00154         this->xval = this->pmax;
00155     else
00156         this->xval = this->pmin + ((this->pmax - this->pmin) * (long)this->volume) / 100;
00157 
00158     
00159     snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, this->xval);
00160     snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, this->xval);
00161 
00162     
00163     this->muteFlag = false;
00164 }
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 int MMSAudioCtrl::getVolume(bool dfCard) {
00174     long    lval, rval;
00175     int     retval = this->volume;
00176 
00177     if ((!this->muteFlag)||(dfCard)) {
00178         
00179         snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &lval);
00180         snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &rval);
00181         if ((lval != this->xval)||(rval != this->xval))
00182             retval = (int)(((lval + (rval - lval) / 2) * 100) / (this->pmax - this->pmin));
00183         if (!this->muteFlag) this->volume = retval;
00184         return retval;
00185     }
00186     return this->volume;
00187 }
00188 
00189 
00190 
00191 
00192 
00193 
00194 void MMSAudioCtrl::volumeUp(int count) {
00195     setVolume(getVolume() + count);
00196 }
00197 
00198 
00199 
00200 
00201 
00202 
00203 void MMSAudioCtrl::volumeDown(int count) {
00204     setVolume(getVolume() - count);
00205 }
00206 
00207 
00208 
00209 
00210 
00211 
00212 bool MMSAudioCtrl::isMute() {
00213     if(isSwitchable) {
00214         int valL = 0;
00215         int valR = 0;
00216         snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &valL);
00217         snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, &valR);
00218         if(valL > 0 || valR > 0) {
00219             return false;
00220         }
00221         return true;
00222     }
00223 
00224     if (this->muteFlag) {
00225         if (getVolume(true) > 0) {
00226             
00227             this->muteFlag = false;
00228         }
00229     }
00230     return this->muteFlag;
00231 }
00232 
00233 
00234 
00235 
00236 void MMSAudioCtrl::mute() {
00237     if (isMute()) {
00238         
00239         if(isSwitchable) {
00240             snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, 1);
00241             snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, 1);
00242         } else {
00243             setVolume(this->volume);
00244         }
00245     } else {
00246         
00247         if(isSwitchable) {
00248             snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, 0);
00249             snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, 0);
00250         } else {
00251             snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, 0);
00252             snd_mixer_selem_set_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, 0);
00253 
00254             
00255             this->muteFlag = true;
00256         }
00257     }
00258 }
00259 
00260 #endif