00001 #include "volumecontrol.h"
00002 #include "config.h"
00003
00004 #ifdef USING_OSS
00005 #include <sys/ioctl.h>
00006 #ifdef HAVE_SYS_SOUNDCARD_H
00007 #include <sys/soundcard.h>
00008 #elif HAVE_SOUNDCARD_H
00009 #include <soundcard.h>
00010 #endif
00011 #endif
00012
00013 #include <fcntl.h>
00014 #include <cstdio>
00015 #include <unistd.h>
00016
00017 #include <iostream>
00018 using namespace std;
00019
00020 #include "mythcontext.h"
00021
00022 VolumeControl::VolumeControl(bool setstartingvolume)
00023 {
00024 (void) setstartingvolume;
00025
00026 mixerfd = -1;
00027 volume = 0;
00028
00029 #ifdef USING_OSS
00030 mute = false;
00031 current_mute_state = MUTE_OFF;
00032
00033 QString device = gContext->GetSetting("MixerDevice", "/dev/mixer");
00034 mixerfd = open(device.ascii(), O_RDONLY);
00035
00036 QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
00037
00038 if (controlLabel == "Master")
00039 {
00040 control = SOUND_MIXER_VOLUME;
00041 }
00042 else
00043 {
00044 control = SOUND_MIXER_PCM;
00045 }
00046
00047 if (mixerfd < 0)
00048 {
00049 cerr << "Unable to open mixer: '" << device << "'\n";
00050 return;
00051 }
00052
00053 int realvol;
00054
00055 if (setstartingvolume)
00056 {
00057 volume = gContext->GetNumSetting("MasterMixerVolume", 80);
00058 realvol = (volume << 8) + volume;
00059 int ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_VOLUME), &realvol);
00060 if (ret < 0)
00061 perror("Setting master volume: ");
00062
00063 volume = gContext->GetNumSetting("PCMMixerVolume", 80);
00064 realvol = (volume << 8) + volume;
00065 ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &realvol);
00066 if (ret < 0)
00067 perror("Setting PCM volume: ");
00068 }
00069
00070 internal_volume = GetCurrentVolume();
00071 #endif
00072 }
00073
00074 VolumeControl::~VolumeControl()
00075 {
00076 if (mixerfd >= 0)
00077 close(mixerfd);
00078 }
00079
00080 int VolumeControl::GetCurrentVolume(void)
00081 {
00082 #ifdef USING_OSS
00083 int realvol;
00084
00085 if (mute)
00086 {
00087 return internal_volume;
00088 }
00089 else
00090 {
00091 int ret = ioctl(mixerfd, MIXER_READ(control), &realvol);
00092 if (ret < 0)
00093 {
00094 perror("Reading PCM volume: ");
00095 }
00096 volume = realvol & 0xff;
00097 internal_volume = volume;
00098 }
00099 #endif
00100
00101 return volume;
00102 }
00103
00104 void VolumeControl::SetCurrentVolume(int value)
00105 {
00106 (void) value;
00107
00108 #ifdef USING_OSS
00109 volume = value;
00110
00111 if (volume > 100)
00112 volume = 100;
00113 if (volume < 0)
00114 volume = 0;
00115
00116 internal_volume = volume;
00117 if (mixerfd >= 0)
00118 {
00119 if (!mute)
00120 {
00121 int realvol = (volume << 8) + volume;
00122 int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
00123 if (ret < 0)
00124 perror("Setting volume: ");
00125 }
00126 }
00127
00128
00129
00130 QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
00131 controlLabel += "MixerVolume";
00132 gContext->SaveSetting(controlLabel, volume);
00133 #endif
00134 }
00135
00136 void VolumeControl::AdjustCurrentVolume(int change)
00137 {
00138 int newvol = GetCurrentVolume() + change;
00139
00140 SetCurrentVolume(newvol);
00141 }
00142
00143 void VolumeControl::SetMute(bool on)
00144 {
00145 (void) on;
00146
00147 #ifdef USING_OSS
00148 int realvol;
00149
00150 if (on)
00151 {
00152 realvol = 0;
00153 }
00154 else
00155 {
00156 realvol = (internal_volume << 8) + internal_volume;
00157 }
00158 if (mixerfd >= 0)
00159 {
00160 int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
00161 if (ret < 0)
00162 perror("Setting mute:");
00163 }
00164
00165 mute = on;
00166 #endif
00167 }
00168
00169 void VolumeControl::ToggleMute(void)
00170 {
00171 SetMute(!mute);
00172 }
00173
00174 kMuteState VolumeControl::IterateMutedChannels(void)
00175 {
00176
00177
00178
00179 #ifdef USING_OSS
00180 int realvol;
00181
00182 switch (current_mute_state)
00183 {
00184 case MUTE_OFF:
00185 current_mute_state = MUTE_LEFT;
00186 realvol = (internal_volume << 8) + 0;
00187 break;
00188 case MUTE_LEFT:
00189 current_mute_state = MUTE_RIGHT;
00190 realvol = (0 << 8) + internal_volume;
00191 break;
00192 case MUTE_RIGHT:
00193 current_mute_state = MUTE_BOTH;
00194 realvol = 0;
00195 break;
00196 case MUTE_BOTH:
00197 current_mute_state = MUTE_OFF;
00198 realvol = (internal_volume << 8) + internal_volume;
00199 break;
00200 }
00201
00202 if (mixerfd >= 0)
00203 {
00204 int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
00205 if (ret < 0)
00206 perror("IterateMutedChannels:");
00207 }
00208 #endif // USING_OSS
00209
00210 return current_mute_state;
00211 }