From 6d2bc8defa92bf09ab5b6600a1d17b81c024b3d8 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Tue, 4 Dec 2012 02:29:47 +0100 Subject: [PATCH] added methods to get the audiostatus and toggle the mute status --- include/cec.h | 25 ++++++++++++ include/cecc.h | 8 ++++ src/lib/CECClient.cpp | 39 +++++++++++++++++++ src/lib/CECClient.h | 4 ++ src/lib/LibCEC.cpp | 21 ++++++++++ src/lib/LibCEC.h | 5 +++ src/lib/LibCECC.cpp | 20 ++++++++++ src/lib/devices/CECAudioSystem.cpp | 34 ++++++++++++++++ src/lib/devices/CECAudioSystem.h | 3 ++ src/lib/implementations/CECCommandHandler.cpp | 8 ++++ src/lib/implementations/CECCommandHandler.h | 1 + 11 files changed, 168 insertions(+) diff --git a/include/cec.h b/include/cec.h index c68bba8..0245033 100644 --- a/include/cec.h +++ b/include/cec.h @@ -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; }; }; diff --git a/include/cecc.h b/include/cecc.h index a4892c4..2e1f9a8 100644 --- a/include/cecc.h +++ b/include/cecc.h @@ -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 diff --git a/src/lib/CECClient.cpp b/src/lib/CECClient.cpp index c1ade4c..d069913 100644 --- a/src/lib/CECClient.cpp +++ b/src/lib/CECClient.cpp @@ -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); diff --git a/src/lib/CECClient.h b/src/lib/CECClient.h index 11a6504..adeaf73 100644 --- a/src/lib/CECClient.h +++ b/src/lib/CECClient.h @@ -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); diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index 2cb5b2f..a27ad9d 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -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; +} diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index 56a112b..f65b818 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -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: diff --git a/src/lib/LibCECC.cpp b/src/lib/LibCECC.cpp index 153668d..b53dc05 100644 --- a/src/lib/LibCECC.cpp +++ b/src/lib/LibCECC.cpp @@ -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; +} + //@} diff --git a/src/lib/devices/CECAudioSystem.cpp b/src/lib/devices/CECAudioSystem.cpp index add3e6f..662054f 100644 --- a/src/lib/devices/CECAudioSystem.cpp +++ b/src/lib/devices/CECAudioSystem.cpp @@ -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; } diff --git a/src/lib/devices/CECAudioSystem.h b/src/lib/devices/CECAudioSystem.h index 7950311..8ab055e 100644 --- a/src/lib/devices/CECAudioSystem.h +++ b/src/lib/devices/CECAudioSystem.h @@ -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; }; diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index ed5e741..1274dd2 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -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; diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index c8430ec..4a8dacb 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -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); -- 2.34.1