[mythtv] [PATCH] volume control for OSS and ALSA
David George
david at thegeorges.us
Tue Oct 26 14:29:47 UTC 2004
This is a standalone patch against CVS as of this morning (which
includes the first part of the big audio update).
Just posting it so people can try it out before it gets merged into the
big audio update. OSS and ALSA have been tested.
Just an FYI for those with Intel ICH4 sound on their motherboard and
*optical* output. It doesn't appear that the mixer settings will change
the volume. This isn't just in Myth, it affects other ALSA applications
like mplayer and aplay also (I also tested changing the mixer settings
with alsamixer and gnome-alsamixer). When I moved the cables to analog
5.1 the volume control worked. Just warning you so no-one beats there
head against the wall.
--
David
-------------- next part --------------
Index: libs/libmyth/libmyth.pro
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/libmyth.pro,v
retrieving revision 1.55
diff -u -r1.55 libmyth.pro
--- libs/libmyth/libmyth.pro 26 Oct 2004 01:16:38 -0000 1.55
+++ libs/libmyth/libmyth.pro 26 Oct 2004 14:12:51 -0000
@@ -14,7 +14,7 @@
HEADERS += volumecontrol.h uitypes.h xmlparse.h mythplugin.h mythdbcon.h
HEADERS += mythdialogs.h audiooutput.h inetcomms.h httpcomms.h mythmedia.h
HEADERS += uilistbtntype.h uiphoneentry.h generictree.h screensaver.h
-HEADERS += managedlist.h DisplayRes.h audiooutputbase.h
+HEADERS += managedlist.h DisplayRes.h audiooutputbase.h volumecontrolbase.h
SOURCES += dialogbox.cpp lcddevice.cpp mythcontext.cpp mythwidgets.cpp
SOURCES += oldsettings.cpp remotefile.cpp settings.cpp themedmenu.cpp
@@ -22,7 +22,7 @@
SOURCES += mythplugin.cpp mythdialogs.cpp audiooutput.cpp inetcomms.cpp
SOURCES += httpcomms.cpp mythmedia.cpp uilistbtntype.cpp uiphoneentry.cpp
SOURCES += generictree.cpp managedlist.cpp DisplayRes.cpp DisplayResX.cpp
-SOURCES += audiooutputbase.cpp
+SOURCES += audiooutputbase.cpp volumecontrolbase.cpp
LIBS += -L../libmythsamplerate
LIBS += -lmythsamplerate-$${LIBVERSION}
@@ -37,8 +37,9 @@
inc.files += uilistbtntype.h uiphoneentry.h generictree.h managedlist.h
using_oss {
- SOURCES += audiooutputoss.cpp
- HEADERS += audiooutputoss.h
+ DEFINES += USE_OSS
+ SOURCES += audiooutputoss.cpp volumecontroloss.cpp
+ HEADERS += audiooutputoss.h volumecontroloss.h
}
unix {
@@ -78,8 +79,8 @@
using_alsa {
DEFINES += USE_ALSA
- HEADERS += audiooutputalsa.h
- SOURCES += audiooutputalsa.cpp
+ HEADERS += audiooutputalsa.h volumecontrolalsa.h
+ SOURCES += audiooutputalsa.cpp volumecontrolalsa.cpp
LIBS += $$ALSA_LIBS
}
Index: libs/libmyth/volumecontrol.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/volumecontrol.cpp,v
retrieving revision 1.13
diff -u -r1.13 volumecontrol.cpp
--- libs/libmyth/volumecontrol.cpp 22 Oct 2004 09:32:54 -0000 1.13
+++ libs/libmyth/volumecontrol.cpp 26 Oct 2004 14:12:51 -0000
@@ -1,201 +1,34 @@
-#include "volumecontrol.h"
-
-#ifdef USING_OSS
-#include <sys/soundcard.h>
-#endif
-
-#include <sys/ioctl.h>
-#include <fcntl.h>
+#include <qstring.h>
#include <cstdio>
-#include <unistd.h>
+#include <cstdlib>
-#include <iostream>
using namespace std;
-#include "mythcontext.h"
-
-VolumeControl::VolumeControl(bool setstartingvolume)
-{
- mixerfd = -1;
- volume = 0;
-
-#ifdef USING_OSS
- mute = false;
- current_mute_state = MUTE_OFF;
-
- QString device = gContext->GetSetting("MixerDevice", "/dev/mixer");
- mixerfd = open(device.ascii(), O_RDONLY);
-
- QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
-
- if (controlLabel == "Master")
- {
- control = SOUND_MIXER_VOLUME;
- }
- else
- {
- control = SOUND_MIXER_PCM;
- }
-
- if (mixerfd < 0)
- {
- cerr << "Unable to open mixer: '" << device << "'\n";
- return;
- }
-
- int realvol;
-
- if (setstartingvolume)
- {
- volume = gContext->GetNumSetting("MasterMixerVolume", 80);
- realvol = (volume << 8) + volume;
- int ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_VOLUME), &realvol);
- if (ret < 0)
- perror("Setting master volume: ");
-
- volume = gContext->GetNumSetting("PCMMixerVolume", 80);
- realvol = (volume << 8) + volume;
- ret = ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &realvol);
- if (ret < 0)
- perror("Setting PCM volume: ");
- }
-
- internal_volume = GetCurrentVolume();
+#include "volumecontrol.h"
+#ifdef USE_OSS
+#include "volumecontroloss.h"
#endif
-}
-
-VolumeControl::~VolumeControl()
-{
- if (mixerfd >= 0)
- close(mixerfd);
-}
-
-int VolumeControl::GetCurrentVolume(void)
-{
-#ifdef USING_OSS
- int realvol;
-
- if (mute)
- {
- return internal_volume;
- }
- else
- {
- int ret = ioctl(mixerfd, MIXER_READ(control), &realvol);
- if (ret < 0)
- {
- perror("Reading PCM volume: ");
- }
- volume = realvol & 0xff; // just use the left channel
- internal_volume = volume;
- }
-#endif
-
- return volume;
-}
-
-void VolumeControl::SetCurrentVolume(int value)
-{
-#ifdef USING_OSS
- volume = value;
-
- if (volume > 100)
- volume = 100;
- if (volume < 0)
- volume = 0;
-
- internal_volume = volume;
- if (mixerfd >= 0)
- {
- if (!mute)
- {
- int realvol = (volume << 8) + volume;
- int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
- if (ret < 0)
- perror("Setting volume: ");
- }
- }
-
- //mute = false;
-
- QString controlLabel = gContext->GetSetting("MixerControl", "PCM");
- controlLabel += "MixerVolume";
- gContext->SaveSetting(controlLabel, volume);
+#ifdef USE_ALSA
+#include "volumecontrolalsa.h"
#endif
-}
-
-void VolumeControl::AdjustCurrentVolume(int change)
-{
- int newvol = GetCurrentVolume() + change;
-
- SetCurrentVolume(newvol);
-}
-void VolumeControl::SetMute(bool on)
+VolumeControl *VolumeControl::OpenVolume(QString audiodevice,
+ bool setstartingvolume)
{
-#ifdef USING_OSS
- int realvol;
-
- if (on)
+ if (audiodevice.startsWith("ALSA:"))
{
- realvol = 0;
+#ifdef USE_ALSA
+ return new VolumeControlALSA(setstartingvolume);
+#else
+ VERBOSE(VB_IMPORTANT, "Audio is set to an ALSA device "
+ "but ALSA support is not compiled in!\n");
+ return NULL;
+#endif
}
+#if defined(USE_OSS)
else
- {
- realvol = (internal_volume << 8) + internal_volume;
- }
- if (mixerfd >= 0)
- {
- int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
- if (ret < 0)
- perror("Setting mute:");
- }
-
- mute = on;
+ return new VolumeControlOSS(setstartingvolume);
#endif
-}
-
-void VolumeControl::ToggleMute(void)
-{
- SetMute(!mute);
-}
-
-kMuteState VolumeControl::IterateMutedChannels(void)
-{
-// current_mute_state is initialized to "MUTE_OFF". If individual muting
-// is enabled, each call to SetMute will advance to the next state:
-// MUTE_OFF -> MUTE_LEFT -> MUTE_RIGHT -> MUTE_BOTH -> MUTE_OFF
-#ifdef USING_OSS
- int realvol;
- switch (current_mute_state)
- {
- case MUTE_OFF:
- current_mute_state = MUTE_LEFT;
- realvol = (internal_volume << 8) + 0;
- break;
- case MUTE_LEFT:
- current_mute_state = MUTE_RIGHT;
- realvol = (0 << 8) + internal_volume;
- break;
- case MUTE_RIGHT:
- current_mute_state = MUTE_BOTH;
- realvol = 0;
- break;
- case MUTE_BOTH:
- current_mute_state = MUTE_OFF;
- realvol = (internal_volume << 8) + internal_volume;
- break;
- }
-
- if (mixerfd >= 0)
- {
- int ret = ioctl(mixerfd, MIXER_WRITE(control), &realvol);
- if (ret < 0)
- perror("IterateMutedChannels:");
- }
-
- return (current_mute_state);
-
-#endif
+ return NULL;
}
Index: libs/libmyth/volumecontrol.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/volumecontrol.h,v
retrieving revision 1.4
diff -u -r1.4 volumecontrol.h
--- libs/libmyth/volumecontrol.h 2 Mar 2004 21:00:05 -0000 1.4
+++ libs/libmyth/volumecontrol.h 26 Oct 2004 14:12:52 -0000
@@ -1,31 +1,38 @@
#ifndef VOLUMECONTROL_H_
#define VOLUMECONTROL_H_
+#include <iostream>
+
+using namespace std;
+
+#include "mythcontext.h"
+
typedef enum { MUTE_OFF=0, MUTE_LEFT, MUTE_RIGHT, MUTE_BOTH } kMuteState;
class VolumeControl
{
public:
- VolumeControl(bool setstartingvolume = true);
- ~VolumeControl();
+ static VolumeControl *OpenVolume(QString audiodevice,
+ bool setstartingvolume);
- int GetCurrentVolume(void);
- void SetCurrentVolume(int value);
- void AdjustCurrentVolume(int change);
-
- void SetMute(bool on);
- void ToggleMute(void);
- bool GetMute(void) { return mute; }
- kMuteState IterateMutedChannels(void);
+ VolumeControl() { lastError = QString::null; };
+ virtual ~VolumeControl() { };
- private:
- int mixerfd;
- int volume;
- int internal_volume;
- int control;
+ virtual void AdjustCurrentVolume(int change) = 0;
+ virtual int GetCurrentVolume(void) = 0;
+ virtual void SetMute(bool on) = 0;
+ virtual void ToggleMute(void) = 0;
+ virtual bool GetMute(void) = 0;
+ virtual kMuteState IterateMutedChannels(void) = 0;
+
+ QString GetError() { return lastError; };
+
+ protected:
+ void Error(QString msg)
+ { lastError = msg; VERBOSE(VB_ALL, lastError); };
- bool mute;
- kMuteState current_mute_state;
+ private:
+ QString lastError;
};
#endif
Index: libs/libmythtv/tv_play.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_play.cpp,v
retrieving revision 1.217
diff -u -r1.217 tv_play.cpp
--- libs/libmythtv/tv_play.cpp 25 Oct 2004 17:22:42 -0000 1.217
+++ libs/libmythtv/tv_play.cpp 26 Oct 2004 14:12:54 -0000
@@ -358,7 +358,10 @@
}
if (gContext->GetNumSetting("MythControlsVolume", 1))
- volumeControl = new VolumeControl(true);
+ {
+ QString audiodevice = gContext->GetSetting("AudioOutputDevice");
+ volumeControl = VolumeControl::OpenVolume(audiodevice, true);
+ }
pthread_create(&event, NULL, EventThread, this);
-------------- next part --------------
Index: mythmusic/playbackbox.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythmusic/mythmusic/playbackbox.cpp,v
retrieving revision 1.74
diff -u -r1.74 playbackbox.cpp
--- mythmusic/playbackbox.cpp 23 Oct 2004 20:15:06 -0000 1.74
+++ mythmusic/playbackbox.cpp 26 Oct 2004 14:19:12 -0000
@@ -75,7 +75,8 @@
volume_display_timer = new QTimer(this);
if (gContext->GetNumSetting("MythControlsVolume", 0))
{
- volume_control = new VolumeControl(true);
+ QString audiodevice = gContext->GetSetting("AudioOutputDevice");
+ volume_control = VolumeControl::OpenVolume(audiodevice, true);
volume_display_timer->start(2000);
connect(volume_display_timer, SIGNAL(timeout()), this, SLOT(hideVolume()));
}
More information about the mythtv-dev
mailing list