Loading system/audio_bluetooth_hw/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ cc_library_shared { header_libs: ["libhardware_headers"], shared_libs: [ "android.hardware.bluetooth.audio@2.0", "libaudioutils", "libbase", "libbluetooth_audio_session", "libcutils", Loading system/audio_bluetooth_hw/device_port_proxy.cc +20 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <audio_utils/primitives.h> #include <inttypes.h> #include <log/log.h> #include <stdlib.h> Loading Loading @@ -280,7 +281,8 @@ bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const { return false; } audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate); audio_cfg->channel_mask = ChannelModeToAudioFormat(pcm_cfg.channelMode); audio_cfg->channel_mask = (is_stereo_to_mono_ ? AUDIO_CHANNEL_OUT_STEREO : ChannelModeToAudioFormat(pcm_cfg.channelMode)); audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample); return true; } Loading Loading @@ -321,7 +323,8 @@ bool BluetoothAudioPortOut::Start() { } LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " request"; << StringPrintf("%04hx", cookie_) << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " request"; bool retval = false; if (state_ == BluetoothStreamState::STANDBY) { state_ = BluetoothStreamState::STARTING; Loading @@ -335,7 +338,8 @@ bool BluetoothAudioPortOut::Start() { if (retval) { LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " done"; << StringPrintf("%04hx", cookie_) << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " done"; } else { LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " failure"; Loading Loading @@ -387,11 +391,20 @@ void BluetoothAudioPortOut::Stop() { << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " done"; } size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const { size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const { if (!in_use()) return 0; return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes); if (!is_stereo_to_mono_) { return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes); } // WAR to mix the stereo into Mono (16 bits per sample) const size_t write_frames = bytes >> 2; if (write_frames == 0) return 0; auto src = static_cast<const int16_t*>(buffer); std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]}; downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames); // a frame is 16 bits, and the size of a mono frame is equal to half a stereo. return BluetoothAudioSessionControl::OutWritePcmData(session_type_, dst.get(), write_frames * 2) * 2; } bool BluetoothAudioPortOut::GetPresentationPosition(uint64_t* delay_ns, Loading system/audio_bluetooth_hw/device_port_proxy.h +7 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,11 @@ class BluetoothAudioPortOut { // Bluetooth stack bool LoadAudioConfig(audio_config_t* audio_cfg) const; // WAR to support Mono mode / 16 bits per sample void ForcePcmStereoToMono(bool force) { is_stereo_to_mono_ = force; } // When the Audio framework / HAL wants to change the stream state, it invokes // these 3 functions to control the Bluetooth stack (Audio Control Path). // Note: Both Start() and Suspend() will return ture when there are no errors. Loading Loading @@ -85,6 +90,8 @@ class BluetoothAudioPortOut { uint16_t cookie_; mutable std::mutex cv_mutex_; std::condition_variable internal_cv_; // WR to support Mono: True if fetching Stereo and mixing into Mono bool is_stereo_to_mono_ = false; // Check and initialize session type for |devices| If failed, this // BluetoothAudioPortOut is not initialized and must be deleted. Loading system/audio_bluetooth_hw/stream_apis.cc +7 −0 Original line number Diff line number Diff line Loading @@ -644,6 +644,13 @@ int adev_open_output_stream(struct audio_hw_device* dev, LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState() << " failed to get audio config"; } // WAR to support Mono / 16 bits per sample as the Bluetooth stack required if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && config->format == AUDIO_FORMAT_PCM_16_BIT) { LOG(INFO) << __func__ << ": force channels=0x" << android::base::StringPrintf("%x", out->channel_mask_) << " to be AUDIO_CHANNEL_OUT_STEREO"; out->bluetooth_output_.ForcePcmStereoToMono(true); config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; } out->sample_rate_ = config->sample_rate; out->channel_mask_ = config->channel_mask; out->format_ = config->format; Loading Loading
system/audio_bluetooth_hw/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ cc_library_shared { header_libs: ["libhardware_headers"], shared_libs: [ "android.hardware.bluetooth.audio@2.0", "libaudioutils", "libbase", "libbluetooth_audio_session", "libcutils", Loading
system/audio_bluetooth_hw/device_port_proxy.cc +20 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <audio_utils/primitives.h> #include <inttypes.h> #include <log/log.h> #include <stdlib.h> Loading Loading @@ -280,7 +281,8 @@ bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const { return false; } audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate); audio_cfg->channel_mask = ChannelModeToAudioFormat(pcm_cfg.channelMode); audio_cfg->channel_mask = (is_stereo_to_mono_ ? AUDIO_CHANNEL_OUT_STEREO : ChannelModeToAudioFormat(pcm_cfg.channelMode)); audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample); return true; } Loading Loading @@ -321,7 +323,8 @@ bool BluetoothAudioPortOut::Start() { } LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " request"; << StringPrintf("%04hx", cookie_) << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " request"; bool retval = false; if (state_ == BluetoothStreamState::STANDBY) { state_ = BluetoothStreamState::STARTING; Loading @@ -335,7 +338,8 @@ bool BluetoothAudioPortOut::Start() { if (retval) { LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " done"; << StringPrintf("%04hx", cookie_) << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " done"; } else { LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=0x" << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " failure"; Loading Loading @@ -387,11 +391,20 @@ void BluetoothAudioPortOut::Stop() { << StringPrintf("%04hx", cookie_) << ", state=" << state_ << " done"; } size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const { size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const { if (!in_use()) return 0; return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes); if (!is_stereo_to_mono_) { return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes); } // WAR to mix the stereo into Mono (16 bits per sample) const size_t write_frames = bytes >> 2; if (write_frames == 0) return 0; auto src = static_cast<const int16_t*>(buffer); std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]}; downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames); // a frame is 16 bits, and the size of a mono frame is equal to half a stereo. return BluetoothAudioSessionControl::OutWritePcmData(session_type_, dst.get(), write_frames * 2) * 2; } bool BluetoothAudioPortOut::GetPresentationPosition(uint64_t* delay_ns, Loading
system/audio_bluetooth_hw/device_port_proxy.h +7 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,11 @@ class BluetoothAudioPortOut { // Bluetooth stack bool LoadAudioConfig(audio_config_t* audio_cfg) const; // WAR to support Mono mode / 16 bits per sample void ForcePcmStereoToMono(bool force) { is_stereo_to_mono_ = force; } // When the Audio framework / HAL wants to change the stream state, it invokes // these 3 functions to control the Bluetooth stack (Audio Control Path). // Note: Both Start() and Suspend() will return ture when there are no errors. Loading Loading @@ -85,6 +90,8 @@ class BluetoothAudioPortOut { uint16_t cookie_; mutable std::mutex cv_mutex_; std::condition_variable internal_cv_; // WR to support Mono: True if fetching Stereo and mixing into Mono bool is_stereo_to_mono_ = false; // Check and initialize session type for |devices| If failed, this // BluetoothAudioPortOut is not initialized and must be deleted. Loading
system/audio_bluetooth_hw/stream_apis.cc +7 −0 Original line number Diff line number Diff line Loading @@ -644,6 +644,13 @@ int adev_open_output_stream(struct audio_hw_device* dev, LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState() << " failed to get audio config"; } // WAR to support Mono / 16 bits per sample as the Bluetooth stack required if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && config->format == AUDIO_FORMAT_PCM_16_BIT) { LOG(INFO) << __func__ << ": force channels=0x" << android::base::StringPrintf("%x", out->channel_mask_) << " to be AUDIO_CHANNEL_OUT_STEREO"; out->bluetooth_output_.ForcePcmStereoToMono(true); config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; } out->sample_rate_ = config->sample_rate; out->channel_mask_ = config->channel_mask; out->format_ = config->format; Loading