add ability to selecte the audio channel (mono left, stereo, mono right) from python
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 16 May 2006 14:58:11 +0000 (14:58 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 16 May 2006 14:58:11 +0000 (14:58 +0000)
store the current selected audio channel then per service in servicelist
TODO: extend the audio track selection screen to make audio channel selection usable :)

12 files changed:
lib/dvb/db.cpp
lib/dvb/decoder.cpp
lib/dvb/decoder.h
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/python/Components/ChoiceList.py
lib/python/Screens/InfoBarGenerics.py
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.h

index 64ef6ed7bf818ecb7068c1ddedb8420eee130849..9b2324a6e8c12ca445941a392141909cbaad2eee 100644 (file)
@@ -232,14 +232,14 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ
                return res;
 }
 
-int eDVBService::getCachePID(cacheID id)
+int eDVBService::getCacheEntry(cacheID id)
 {
        if (id >= cacheMax)
                return -1;
        return m_cache[id];
 }
 
-void eDVBService::setCachePID(cacheID id, int pid)
+void eDVBService::setCacheEntry(cacheID id, int pid)
 {
        if (id < cacheMax)
                m_cache[id] = pid;
index 1bec997d856d69d80da12a535a5bd9ca7921ae1e..76d0f50493be89b823c73283d7cfae3a8fb5fdc1 100644 (file)
@@ -137,6 +137,22 @@ void eDVBAudio::unfreeze()
                eDebug("video: AUDIO_CONTINUE: %m");
 }
 
+void eDVBAudio::setChannel(int channel)
+{
+       int val = AUDIO_STEREO;
+       switch (channel)
+       {
+       case aMonoLeft: val = AUDIO_MONO_LEFT; break;
+       case aMonoRight: val = AUDIO_MONO_RIGHT; break;
+       default:
+               break;
+       }
+       if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
+               eDebug("video: AUDIO_CHANNEL_SELECT: %m");
+       else
+               eDebug("AUDIO_CHANNEL_SELECT ok");
+}
+
 int eDVBAudio::getPTS(pts_t &now)
 {
        return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
@@ -552,6 +568,15 @@ RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
        return 0;
 }
 
+RESULT eTSMPEGDecoder::setAudioChannel(int channel)
+{
+       if (m_audio)
+               m_audio->setChannel(channel);
+       else
+               eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
+       return 0;
+}
+
 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
 {
        if (m_pcrpid != pcrpid)
index 834499b0c01ccc5c17a73a1d9727b0fc3aff0ff9..f8719869b859fa00ce1110ea5075b9eba1f6d13d 100644 (file)
@@ -14,6 +14,8 @@ public:
        enum { aMPEG, aAC3, aDTS, aAAC };
        eDVBAudio(eDVBDemux *demux, int dev);
        int startPid(int pid, int type);
+       enum { aMonoLeft, aStereo, aMonoRight };
+       void setChannel(int channel);
        void stop();
 #if HAVE_DVB_API_VERSION < 3
        void start();
@@ -107,6 +109,7 @@ public:
        virtual ~eTSMPEGDecoder();
        RESULT setVideoPID(int vpid, int type);
        RESULT setAudioPID(int apid, int type);
+       RESULT setAudioChannel(int channel);
        RESULT setSyncPCR(int pcrpid);
        RESULT setTextPID(int textpid);
        RESULT setSyncMaster(int who);
index ecf8bb92e1f331266195440c290b01b3f0ef05aa..dff543ca39d7340f63af5a467410003d48888486 100644 (file)
@@ -223,11 +223,11 @@ class eDVBService: public iStaticServiceInformation
 public:
        enum cacheID
        {
-               cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cVTYPE, cacheMax
+               cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cVTYPE, cACHANNEL, cacheMax
        };
 
-       int getCachePID(cacheID);
-       void setCachePID(cacheID, int);
+       int getCacheEntry(cacheID);
+       void setCacheEntry(cacheID, int);
 
        bool cacheEmpty();
 
@@ -577,10 +577,14 @@ public:
                /** Set Displayed Video PID and type */
        virtual RESULT setVideoPID(int vpid, int type)=0;
 
-       enum { af_MPEG, af_AC3, af_DTS };
+       enum { af_MPEG, af_AC3, af_DTS, af_AAC };
                /** Set Displayed Audio PID and type */
        virtual RESULT setAudioPID(int apid, int type)=0;
 
+       enum { ac_left, ac_stereo, ac_right };
+               /** Set Displayed Audio Channel */
+       virtual RESULT setAudioChannel(int channel)=0;
+
                /** Set Displayed Videotext PID */
        virtual RESULT setTextPID(int vpid)=0;
 
index 11cda12593a991dea742de32285ef228d00b4502..1032267d7cab7daa96fc1a7636716a15ec326bb9 100644 (file)
@@ -216,6 +216,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
        program.isCrypted = false;
        program.pmtPid = -1;
        program.textPid = -1;
+       program.audioChannel = m_service ? m_service->getCacheEntry(eDVBService::cACHANNEL) : -1;
 
        if ( ((m_service && m_service->usePMT()) || !m_service) && !m_PMT.getCurrent(ptr))
        {
@@ -225,10 +226,10 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                int cached_tpid = -1;
                if ( m_service && !m_service->cacheEmpty() )
                {
-                       cached_vpid = m_service->getCachePID(eDVBService::cVPID);
-                       cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID);
-                       cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID);
-                       cached_tpid = m_service->getCachePID(eDVBService::cTPID);
+                       cached_vpid = m_service->getCacheEntry(eDVBService::cVPID);
+                       cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAC3PID);
+                       cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAPID);
+                       cached_tpid = m_service->getCacheEntry(eDVBService::cTPID);
                }
                eDVBTableSpec table_spec;
                ptr->getSpec(table_spec);
@@ -359,12 +360,12 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                return 0;
        } else if ( m_service && !m_service->cacheEmpty() )
        {
-               int vpid = m_service->getCachePID(eDVBService::cVPID),
-                       apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID),
-                       apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
-                       pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
-                       tpid = m_service->getCachePID(eDVBService::cTPID),
-                       vpidtype = m_service->getCachePID(eDVBService::cVTYPE),
+               int vpid = m_service->getCacheEntry(eDVBService::cVPID),
+                       apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID),
+                       apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID),
+                       pcrpid = m_service->getCacheEntry(eDVBService::cPCRPID),
+                       tpid = m_service->getCacheEntry(eDVBService::cTPID),
+                       vpidtype = m_service->getCacheEntry(eDVBService::cVTYPE),
                        cnt=0;
                if ( vpidtype == -1 )
                        vpidtype = videoStream::vtMPEG2;
index b6a3743fa88d68fe6987e121331f33115d108d4d..f4e99a57b5ba5f8175b528a87ce2ee4e6c88d8e8 100644 (file)
@@ -122,6 +122,7 @@ public:
                int pmtPid;
                int textPid;
                bool isCrypted;
+               int audioChannel;
        };
        
        int getProgramInfo(struct program &program);
index ca58ecd6b7bb3f559619dbad7027ef1e7a381941..fe3e60085afa0d6778054efa4d8f325050cbda57 100644 (file)
@@ -18,7 +18,7 @@ RT_VALIGN_BOTTOM = 16
 
 def ChoiceEntryComponent(key, text):
        res = [ text ]
-       res.append((eListboxPythonMultiContent.TYPE_TEXT, 32, 00, 800,25, 0, RT_HALIGN_LEFT, text[0]))
+       res.append((eListboxPythonMultiContent.TYPE_TEXT, 32, 00, 800, 25, 0, RT_HALIGN_LEFT, text[0]))
 
        png = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "key_" + key + "-fs8.png"))
        if png is not None:
index c3c6e21abd6ce0d94d65f53278f4f0c3bcd61cb1..67212656c57660e0a88f48703ddc23a08691e1d0 100644 (file)
@@ -13,7 +13,7 @@ from Components.PluginComponent import plugins
 from Components.ProgressBar import *
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.ServiceName import ServiceName
-from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean
+from Components.config import config, configElement, ConfigSubsection, configSequence, configElementBoolean, configSelection, configElement_nonSave, getConfigListEntry
 from Components.config import configfile, configsequencearg
 from Components.TimerList import TimerEntryComponent
 from Components.TunerInfo import TunerInfo
@@ -1192,9 +1192,11 @@ class InfoBarAudioSelection:
        def audioSelection(self):
                service = self.session.nav.getCurrentService()
                audio = service.audioTracks()
-               self.audio = audio
+               self.audioTracks = audio
                n = audio.getNumberOfTracks()
                if n > 0:
+#                      self.audioChannel = service.audioChannel()
+#                      config.audio.audiochannel = configElement_nonSave("config.audio.audiochannel", configSelection, self.audioChannel.getCurrentChannel(), (("left", _("Left  >")), ("stereo", _("<  Stereo  >")), ("right", _("<  Right"))))
                        tlist = []
                        for x in range(n):
                                i = audio.getTrackInfo(x)
@@ -1214,6 +1216,9 @@ class InfoBarAudioSelection:
                        
                        selectedAudio = tlist[0][1]
                        tlist.sort(lambda x,y : cmp(x[0], y[0]))
+
+#                      tlist.insert(0, getConfigListEntry(_("Audio Channel"), config.audio.audiochannel))
+
                        selection = 0
                        for x in tlist:
                                if x[1] != selectedAudio:
@@ -1222,11 +1227,15 @@ class InfoBarAudioSelection:
                                        break
                        
                        self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection)
+               else:
+                       del self.audioTracks
 
        def audioSelected(self, audio):
                if audio is not None:
-                       self.audio.selectTrack(audio[1])
-               del self.audio
+                       self.audioTracks.selectTrack(audio[1])
+               del self.audioTracks
+#              del self.audioChannel
+#              del config.audio.audiochannel
 
 class InfoBarSubserviceSelection:
        def __init__(self):
index c93c84a547fa26ce7de16a4085145ac4609be472..a24b8b2151f334fedcad00a11b8ba19f66136dc8 100644 (file)
@@ -374,6 +374,20 @@ public:
 
 TEMPLATE_TYPEDEF(ePtr<iAudioTrackSelection>, iAudioTrackSelectionPtr);
 
+class iAudioChannelSelection: public iObject
+{
+#ifdef SWIG
+       iAudioChannelSelection();
+       ~iAudioChannelSelection();
+#endif
+public:
+       enum { LEFT, STEREO, RIGHT };
+       virtual int getCurrentChannel()=0;
+       virtual RESULT selectChannel(int i)=0;
+};
+
+TEMPLATE_TYPEDEF(ePtr<iAudioChannelSelection>, iAudioChannelSelectionPtr);
+
 class iSubserviceList: public iObject
 {
 #ifdef SWIG
@@ -459,6 +473,7 @@ public:
        virtual SWIG_VOID(RESULT) pause(ePtr<iPauseableService> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) info(ePtr<iServiceInformation> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
+       virtual SWIG_VOID(RESULT) audioChannel(ePtr<iAudioChannelSelection> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) frontendStatusInfo(ePtr<iFrontendStatusInformation> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
index e9aeb8a9545758998eff1e0fadca0e5f52c4db34..0ec488fe501f931de7cd2a6d17c013028a065df6 100644 (file)
@@ -997,6 +997,12 @@ RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
        return 0;
 }
 
+RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
+{
+       ptr = this;
+       return 0;
+}
+
 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
 {
        ptr = this;
@@ -1239,12 +1245,12 @@ int eDVBServicePlay::selectAudioStream(int i)
        {
                if (program.audioStreams[i].type == eDVBAudio::aMPEG)
                {
-                       m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
-                       m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+                       m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
+                       m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
                }       else
                {
-                       m_dvb_service->setCachePID(eDVBService::cAPID, -1);
-                       m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
+                       m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
+                       m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
                }
        }
 
@@ -1253,6 +1259,24 @@ int eDVBServicePlay::selectAudioStream(int i)
        return 0;
 }
 
+int eDVBServicePlay::getCurrentChannel()
+{
+       int curChannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
+       return curChannel == -1 ? STEREO : curChannel;
+}
+
+RESULT eDVBServicePlay::selectChannel(int i)
+{
+       if (i < iAudioChannelSelection::LEFT || i > iAudioChannelSelection::RIGHT)
+               i = -1;  // Stereo
+       if (m_dvb_service->getCacheEntry(eDVBService::cACHANNEL) != i)
+       {
+               m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+               if (m_decoder)
+                       m_decoder->setAudioChannel(i);
+       }
+}
+
 int eDVBServicePlay::getFrontendInfo(int w)
 {
        if (m_is_pvr)
@@ -1560,7 +1584,7 @@ void eDVBServicePlay::switchToTimeshift()
 
 void eDVBServicePlay::updateDecoder()
 {
-       int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1;
+       int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1;
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
 
        bool defaultac3=false;
@@ -1619,6 +1643,7 @@ void eDVBServicePlay::updateDecoder()
                pcrpid = program.pcrPid;
                eDebug(", and the text pid is %04x", program.textPid);
                tpid = program.textPid;
+               achannel = program.audioChannel;
        }
 
        if (!m_decoder)
@@ -1651,7 +1676,11 @@ void eDVBServicePlay::updateDecoder()
 
                if (!m_is_primary)
                        m_decoder->setTrickmode(1);
+
                m_decoder->start();
+
+               m_decoder->setAudioChannel(achannel);
+
 // how we can do this better?
 // update cache pid when the user changed the audio track or video track
 // TODO handling of difference audio types.. default audio types..
@@ -1661,18 +1690,18 @@ void eDVBServicePlay::updateDecoder()
                {
                        if (apidtype == eDVBAudio::aMPEG)
                        {
-                               m_dvb_service->setCachePID(eDVBService::cAPID, apid);
-                               m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+                               m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
+                               m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
                        }
                        else
                        {
-                               m_dvb_service->setCachePID(eDVBService::cAPID, -1);
-                               m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
+                               m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
+                               m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
                        }
-                       m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
-                       m_dvb_service->setCachePID(eDVBService::cVTYPE, vpidtype);
-                       m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
-                       m_dvb_service->setCachePID(eDVBService::cTPID, tpid);
+                       m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
+                       m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype);
+                       m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
+                       m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
                }
        }
 }
index 01eb049756a6301505d54a3e169d8db1d8dfbc17..79e8d5404bf1ff23aa1f9eadf48edcc5895494ef 100644 (file)
@@ -58,7 +58,8 @@ private:
 
 class eDVBServicePlay: public iPlayableService, public iPauseableService, 
                public iSeekableService, public Object, public iServiceInformation, 
-               public iAudioTrackSelection, public iFrontendStatusInformation,
+               public iAudioTrackSelection, public iAudioChannelSelection,
+               public iFrontendStatusInformation,
                public iSubserviceList, public iTimeshiftService,
                public iCueSheet
 {
@@ -75,6 +76,7 @@ public:
        RESULT seek(ePtr<iSeekableService> &ptr);
        RESULT pause(ePtr<iPauseableService> &ptr);
        RESULT info(ePtr<iServiceInformation> &ptr);
+       RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr);
        RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
        RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr);
        RESULT subServices(ePtr<iSubserviceList> &ptr);
@@ -107,6 +109,10 @@ public:
        RESULT selectTrack(unsigned int i);
        RESULT getTrackInfo(struct iAudioTrackInfo &, unsigned int n);
 
+               // iAudioChannelSelection       
+       int getCurrentChannel();
+       RESULT selectChannel(int i);
+
                // iFrontendStatusInformation
        int getFrontendInfo(int w);
        PyObject *getFrontendData(bool);
index cb400cc6789536cd1b708267be51a26b691a5e31..c6a0df062c443a231a07a8a5a6a5b4bef924f609 100644 (file)
@@ -58,6 +58,7 @@ public:
        RESULT seek(ePtr<iSeekableService> &ptr);
 
                // not implemented (yet)
+       RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr) { ptr = 0; return -1; }
        RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
        RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr) { ptr = 0; return -1; }
        RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }