added methods to get the audiostatus and toggle the mute status
authorLars Op den Kamp <lars@opdenkamp.eu>
Tue, 4 Dec 2012 01:29:47 +0000 (02:29 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Tue, 4 Dec 2012 01:46:05 +0000 (02:46 +0100)
include/cec.h
include/cecc.h
src/lib/CECClient.cpp
src/lib/CECClient.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/LibCECC.cpp
src/lib/devices/CECAudioSystem.cpp
src/lib/devices/CECAudioSystem.h
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/CECCommandHandler.h

index c68bba81487dbccc85a9c32f749087e7a71f4622..02450331d43c0e365ab32eed44a6e5bbc62e1ca1 100644 (file)
@@ -251,6 +251,7 @@ namespace CEC
     virtual uint8_t VolumeDown(bool bSendRelease = true) = 0;
 
     /*!
+     * @deprecated Use AudioToggleMute() instead
      * @brief Sends a mute keypress to an audiosystem if it's present.
      * @param bSendRelease Send a key release after the keypress.
      * @return The new audio status.
@@ -421,6 +422,30 @@ namespace CEC
     virtual const char *ToString(const cec_server_version version) = 0;
     virtual const char *ToString(const cec_user_control_code key) = 0;
     virtual const char *ToString(const cec_adapter_type type) = 0;
+
+    /*!
+     * @brief Toggle the mute status of the AVR (if present)
+     * @return The new audio status.
+     */
+    virtual uint8_t AudioToggleMute(void) = 0;
+
+    /*!
+     * @brief Mute the AVR (if present)
+     * @return The new audio status.
+     */
+    virtual uint8_t AudioMute(void) = 0;
+
+    /*!
+     * @brief Mute the AVR (if connected)
+     * @return The new audio status.
+     */
+    virtual uint8_t AudioUnmute(void) = 0;
+
+    /*!
+     * @brief Get the current audio status (if an AVR is connected)
+     * @return The current audio status, or cec_audio_status if unknown.
+     */
+    virtual uint8_t AudioStatus(void) = 0;
   };
 };
 
index a4892c48b045ab13d276e1e32ee69738503c0b06..2e1f9a80d8ab6f5260aa7eaf47450a9be51f238f 100644 (file)
@@ -276,6 +276,14 @@ extern DECLSPEC uint16_t cec_get_adapter_vendor_id(void);
 
 extern DECLSPEC uint16_t cec_get_adapter_product_id(void);
 
+extern DECLSPEC uint8_t cec_audio_toggle_mute(void);
+
+extern DECLSPEC uint8_t cec_audio_mute(void);
+
+extern DECLSPEC uint8_t cec_audio_unmute(void);
+
+extern DECLSPEC uint8_t cec_audio_status(void);
+
 #ifdef __cplusplus
 };
 #endif
index c1ade4ca536c5cb11310328b8e0f6781e3cf8bc5..d0699130cd303a6bc247351edd318653ce7cdd5a 100644 (file)
@@ -745,6 +745,45 @@ uint8_t CCECClient::SendMuteAudio(void)
       (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
 }
 
+uint8_t CCECClient::AudioToggleMute(void)
+{
+  CCECBusDevice *device = GetPrimaryDevice();
+  CCECAudioSystem *audio = m_processor->GetAudioSystem();
+
+  return device && audio && audio->IsPresent() ?
+      audio->MuteAudio(device->GetLogicalAddress()) :
+      (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CCECClient::AudioMute(void)
+{
+  CCECBusDevice *device = GetPrimaryDevice();
+  CCECAudioSystem *audio = m_processor->GetAudioSystem();
+  uint8_t iStatus = device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+  if ((iStatus & CEC_AUDIO_MUTE_STATUS_MASK) != CEC_AUDIO_MUTE_STATUS_MASK)
+    iStatus = audio->MuteAudio(device->GetLogicalAddress());
+
+  return iStatus;
+}
+
+uint8_t CCECClient::AudioUnmute(void)
+{
+  CCECBusDevice *device = GetPrimaryDevice();
+  CCECAudioSystem *audio = m_processor->GetAudioSystem();
+  uint8_t iStatus = device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+  if ((iStatus & CEC_AUDIO_MUTE_STATUS_MASK) == CEC_AUDIO_MUTE_STATUS_MASK)
+    iStatus = audio->MuteAudio(device->GetLogicalAddress());
+
+  return iStatus;
+}
+
+uint8_t CCECClient::AudioStatus(void)
+{
+  CCECBusDevice *device = GetPrimaryDevice();
+  CCECAudioSystem *audio = m_processor->GetAudioSystem();
+  return device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
 bool CCECClient::SendKeypress(const cec_logical_address iDestination, const cec_user_control_code key, bool bWait /* = true */)
 {
   CCECBusDevice *dest = m_processor->GetDevice(iDestination);
index 11a6504d826aaa14b3f59e7cec1100f55bc2e249..adeaf739b22c5474ce6e9ddae15085063bbb46d2 100644 (file)
@@ -152,6 +152,10 @@ namespace CEC
     virtual uint8_t               SendVolumeUp(bool bSendRelease = true);
     virtual uint8_t               SendVolumeDown(bool bSendRelease = true);
     virtual uint8_t               SendMuteAudio(void);
+    virtual uint8_t               AudioToggleMute(void);
+    virtual uint8_t               AudioMute(void);
+    virtual uint8_t               AudioUnmute(void);
+    virtual uint8_t               AudioStatus(void);
     virtual bool                  SendKeypress(const cec_logical_address iDestination, const cec_user_control_code key, bool bWait = true);
     virtual bool                  SendKeyRelease(const cec_logical_address iDestination, bool bWait = true);
     virtual cec_osd_name          GetDeviceOSDName(const cec_logical_address iAddress);
index 2cb5b2f6ab55c000645a5114f4d3a6a56184c183..a27ad9dbc45530e02a38ed3a3b408b64db6f9955 100644 (file)
@@ -280,6 +280,7 @@ uint8_t CLibCEC::VolumeDown(bool bSendRelease /* = true */)
 
 uint8_t CLibCEC::MuteAudio(bool UNUSED(bSendRelease) /* = true */)
 {
+  AddLog(CEC_LOG_WARNING, "deprecated function called: %s", __FUNCTION__);
   return m_client ? m_client->SendMuteAudio() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
 }
 
@@ -538,3 +539,23 @@ uint16_t CLibCEC::GetAdapterProductId(void) const
 {
   return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterProductId() : 0;
 }
+
+uint8_t CLibCEC::AudioToggleMute(void)
+{
+  return m_client ? m_client->AudioToggleMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioMute(void)
+{
+  return m_client ? m_client->AudioMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioUnmute(void)
+{
+  return m_client ? m_client->AudioUnmute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioStatus(void)
+{
+  return m_client ? m_client->AudioStatus() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
index 56a112bf52e9e42ee49c45eaf05838eb6719a1ab..f65b8186b9e843d2917fa95e98be62b891a1b2a5 100644 (file)
@@ -132,6 +132,11 @@ namespace CEC
       uint16_t GetAdapterVendorId(void) const;
       uint16_t GetAdapterProductId(void) const;
 
+      uint8_t AudioToggleMute(void);
+      uint8_t AudioMute(void);
+      uint8_t AudioUnmute(void);
+      uint8_t AudioStatus(void);
+
       CCECProcessor *           m_cec;
 
     protected:
index 153668db2f6f3c1349d35fd28b0b9a7ca2431264..b53dc05f29541ef7bd3aa23553a23d0cd5efe264 100644 (file)
@@ -388,4 +388,24 @@ uint16_t cec_get_adapter_product_id(void)
   return cec_parser ? cec_parser->GetAdapterProductId() : 0;
 }
 
+uint8_t cec_audio_toggle_mute(void)
+{
+  return cec_parser ? cec_parser->AudioToggleMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_mute(void)
+{
+  return cec_parser ? cec_parser->AudioMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_unmute(void)
+{
+  return cec_parser ? cec_parser->AudioUnmute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_status(void)
+{
+  return cec_parser ? cec_parser->AudioStatus() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
 //@}
index add3e6f3f6286137370a5d53fa3982012c8ce8d9..662054f0a2b167e1d8a35754f890833e4b4a2ff8 100644 (file)
@@ -139,6 +139,40 @@ uint8_t CCECAudioSystem::MuteAudio(const cec_logical_address source)
   TransmitKeypress(source, CEC_USER_CONTROL_CODE_MUTE);
   TransmitKeyRelease(source);
 
+  return GetAudioStatus(source, true);
+}
+
+bool CCECAudioSystem::RequestAudioStatus(const cec_logical_address initiator, bool bWaitForResponse /* = true */)
+{
+  bool bReturn(false);
+
+  if (!IsHandledByLibCEC() &&
+      !IsUnsupportedFeature(CEC_OPCODE_GIVE_AUDIO_STATUS))
+  {
+    MarkBusy();
+    LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting audio status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+    bReturn = m_handler->TransmitRequestAudioStatus(initiator, m_iLogicalAddress, bWaitForResponse);
+    MarkReady();
+  }
+  return bReturn;
+}
+
+uint8_t CCECAudioSystem::GetAudioStatus(const cec_logical_address initiator, bool bUpdate /* = false */)
+{
+  bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
+  bool bRequestUpdate(false);
+  {
+    CLockObject lock(m_mutex);
+    bRequestUpdate = bIsPresent &&
+        (bUpdate || m_audioStatus == CEC_AUDIO_VOLUME_STATUS_UNKNOWN);
+  }
+
+  if (bRequestUpdate)
+  {
+    CheckVendorIdRequested(initiator);
+    RequestAudioStatus(initiator);
+  }
+
   CLockObject lock(m_mutex);
   return m_audioStatus;
 }
index 795031101223e1ff250b49fe3cb7659cc3e854d8..8ab055e0bc7a520ca207ca20afdaf1ab7727c022 100644 (file)
@@ -50,10 +50,13 @@ namespace CEC
     uint8_t VolumeUp(const cec_logical_address source, bool bSendRelease = true);
     uint8_t VolumeDown(const cec_logical_address source, bool bSendRelease = true);
     uint8_t MuteAudio(const cec_logical_address source);
+    uint8_t GetAudioStatus(const cec_logical_address initiator, bool bUpdate = false);
 
     bool TransmitActiveSource(void) { return false; }
 
   protected:
+    bool RequestAudioStatus(const cec_logical_address initiator, bool bWaitForResponse = true);
+
     cec_system_audio_status m_systemAudioStatus;
     uint8_t                 m_audioStatus;
   };
index ed5e74142e71291e6964b7ec673f2a903694c072..1274dd2e8e17e8c997a9ffd75e45a8d6a7b7d158 100644 (file)
@@ -898,6 +898,14 @@ bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iIniti
   return Transmit(command, !bWaitForResponse, false);
 }
 
+bool CCECCommandHandler::TransmitRequestAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
+{
+  cec_command command;
+  cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_AUDIO_STATUS);
+
+  return Transmit(command, !bWaitForResponse, false);
+}
+
 bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
 {
   cec_command command;
index c8430ec1e5f45b5e119f015a3a543bafe153d983..4a8dacbe7f59e25ecc400ca6763b5eb559525bfc 100644 (file)
@@ -70,6 +70,7 @@ namespace CEC
     virtual bool TransmitRequestCecVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
     virtual bool TransmitRequestMenuLanguage(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
     virtual bool TransmitRequestOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
+    virtual bool TransmitRequestAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
     virtual bool TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
     virtual bool TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
     virtual bool TransmitRequestVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);