1d5a2a63bSopenharmony_ci/* 2d5a2a63bSopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3d5a2a63bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d5a2a63bSopenharmony_ci * you may not use this file except in compliance with the License. 5d5a2a63bSopenharmony_ci * You may obtain a copy of the License at 6d5a2a63bSopenharmony_ci * 7d5a2a63bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d5a2a63bSopenharmony_ci * 9d5a2a63bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d5a2a63bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d5a2a63bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d5a2a63bSopenharmony_ci * See the License for the specific language governing permissions and 13d5a2a63bSopenharmony_ci * limitations under the License. 14d5a2a63bSopenharmony_ci */ 15d5a2a63bSopenharmony_ci 16d5a2a63bSopenharmony_ci#include "audio_source.h" 17d5a2a63bSopenharmony_ci#include "media_log.h" 18d5a2a63bSopenharmony_ci#include "securec.h" 19d5a2a63bSopenharmony_ci 20d5a2a63bSopenharmony_cinamespace OHOS { 21d5a2a63bSopenharmony_cinamespace Audio { 22d5a2a63bSopenharmony_ci#define AUDIO_RETURN_VAL_IF_NULL(condition) \ 23d5a2a63bSopenharmony_ci do { \ 24d5a2a63bSopenharmony_ci if ((condition) == nullptr) { \ 25d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("" #condition " is NULL"); \ 26d5a2a63bSopenharmony_ci return ERR_ILLEGAL_STATE; \ 27d5a2a63bSopenharmony_ci } \ 28d5a2a63bSopenharmony_ci } while (0) 29d5a2a63bSopenharmony_ci 30d5a2a63bSopenharmony_ciusing namespace OHOS::Media; 31d5a2a63bSopenharmony_cistatic AudioManager *g_audioManager = nullptr; 32d5a2a63bSopenharmony_ci 33d5a2a63bSopenharmony_ciAudioSource::AudioSource() 34d5a2a63bSopenharmony_ci : initialized_(false), 35d5a2a63bSopenharmony_ci started_(false), 36d5a2a63bSopenharmony_ci audioAdapter_(nullptr), 37d5a2a63bSopenharmony_ci audioCapture_(nullptr) 38d5a2a63bSopenharmony_ci{ 39d5a2a63bSopenharmony_ci if (g_audioManager == nullptr) { 40d5a2a63bSopenharmony_ci g_audioManager = GetAudioManagerFuncs(); 41d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("g_audioManager"); 42d5a2a63bSopenharmony_ci } 43d5a2a63bSopenharmony_ci int size = 0; 44d5a2a63bSopenharmony_ci struct AudioAdapterDescriptor *descs = nullptr; 45d5a2a63bSopenharmony_ci g_audioManager->GetAllAdapters(g_audioManager, &descs, &size); 46d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("GetAllAdapters size:%d", size); 47d5a2a63bSopenharmony_ci 48d5a2a63bSopenharmony_ci for (int index = 0; index < size; index++) { 49d5a2a63bSopenharmony_ci struct AudioAdapterDescriptor *desc = &descs[index]; 50d5a2a63bSopenharmony_ci for (int port = 0; (desc != nullptr && port < static_cast<int>(desc->portNum)); port++) { 51d5a2a63bSopenharmony_ci if ((desc->ports[port].dir != PORT_IN) || 52d5a2a63bSopenharmony_ci (g_audioManager->LoadAdapter(g_audioManager, desc, &audioAdapter_))) { 53d5a2a63bSopenharmony_ci continue; 54d5a2a63bSopenharmony_ci } 55d5a2a63bSopenharmony_ci (void)audioAdapter_->InitAllPorts(audioAdapter_); 56d5a2a63bSopenharmony_ci if (memcpy_s(&capturePort_, sizeof(struct AudioPort), 57d5a2a63bSopenharmony_ci &desc->ports[port], sizeof(struct AudioPort))) { 58d5a2a63bSopenharmony_ci MEDIA_WARNING_LOG("memcpy_s capturePort_ failed"); 59d5a2a63bSopenharmony_ci } 60d5a2a63bSopenharmony_ci break; 61d5a2a63bSopenharmony_ci } 62d5a2a63bSopenharmony_ci } 63d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("LoadAdapter audioAdapter_"); 64d5a2a63bSopenharmony_ci} 65d5a2a63bSopenharmony_ci 66d5a2a63bSopenharmony_ciAudioSource::~AudioSource() 67d5a2a63bSopenharmony_ci{ 68d5a2a63bSopenharmony_ci MEDIA_DEBUG_LOG("in"); 69d5a2a63bSopenharmony_ci if (initialized_) { 70d5a2a63bSopenharmony_ci Release(); 71d5a2a63bSopenharmony_ci } 72d5a2a63bSopenharmony_ci 73d5a2a63bSopenharmony_ci if (audioAdapter_ != nullptr) { 74d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("UnloadModule audioAdapter_"); 75d5a2a63bSopenharmony_ci if (g_audioManager == nullptr) { 76d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("~AudioSource g_audioManager is nullptr"); 77d5a2a63bSopenharmony_ci audioAdapter_ = nullptr; 78d5a2a63bSopenharmony_ci return; 79d5a2a63bSopenharmony_ci } 80d5a2a63bSopenharmony_ci g_audioManager->UnloadAdapter(g_audioManager, audioAdapter_); 81d5a2a63bSopenharmony_ci audioAdapter_ = nullptr; 82d5a2a63bSopenharmony_ci } 83d5a2a63bSopenharmony_ci} 84d5a2a63bSopenharmony_ci 85d5a2a63bSopenharmony_ciint32_t AudioSource::InitCheck() 86d5a2a63bSopenharmony_ci{ 87d5a2a63bSopenharmony_ci if (!initialized_) { 88d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("not initialized"); 89d5a2a63bSopenharmony_ci return ERR_ILLEGAL_STATE; 90d5a2a63bSopenharmony_ci } 91d5a2a63bSopenharmony_ci return SUCCESS; 92d5a2a63bSopenharmony_ci} 93d5a2a63bSopenharmony_ci 94d5a2a63bSopenharmony_cibool AudioSource::GetMinFrameCount(int32_t sampleRate, int32_t channelCount, 95d5a2a63bSopenharmony_ci AudioCodecFormat audioFormat, size_t &frameCount) 96d5a2a63bSopenharmony_ci{ 97d5a2a63bSopenharmony_ci if (sampleRate <= 0 || channelCount <= 0 || audioFormat < AUDIO_DEFAULT || 98d5a2a63bSopenharmony_ci audioFormat >= FORMAT_BUTT) { 99d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("invalid params sampleRate:%d channelCount:%d audioFormat:%d", sampleRate, 100d5a2a63bSopenharmony_ci channelCount, audioFormat); 101d5a2a63bSopenharmony_ci return false; 102d5a2a63bSopenharmony_ci } 103d5a2a63bSopenharmony_ci frameCount = 0; 104d5a2a63bSopenharmony_ci return true; 105d5a2a63bSopenharmony_ci} 106d5a2a63bSopenharmony_ci 107d5a2a63bSopenharmony_ciuint64_t AudioSource::GetFrameCount() 108d5a2a63bSopenharmony_ci{ 109d5a2a63bSopenharmony_ci int32_t ret; 110d5a2a63bSopenharmony_ci if ((ret = InitCheck()) != SUCCESS) { 111d5a2a63bSopenharmony_ci return ret; 112d5a2a63bSopenharmony_ci } 113d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioCapture_); 114d5a2a63bSopenharmony_ci uint64_t frameCount = 0; 115d5a2a63bSopenharmony_ci ret = audioCapture_->attr.GetFrameCount(reinterpret_cast<AudioHandle>(audioCapture_), &frameCount); 116d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 117d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("attr GetFrameCount failed:0x%x ", ret); 118d5a2a63bSopenharmony_ci return ret; 119d5a2a63bSopenharmony_ci } 120d5a2a63bSopenharmony_ci return frameCount; 121d5a2a63bSopenharmony_ci} 122d5a2a63bSopenharmony_ci 123d5a2a63bSopenharmony_ciint32_t AudioSource::EnumDeviceBySourceType(AudioSourceType inputSource, std::vector<AudioDeviceDesc> &devices) 124d5a2a63bSopenharmony_ci{ 125d5a2a63bSopenharmony_ci if (inputSource != AUDIO_MIC && inputSource != AUDIO_SOURCE_DEFAULT) { 126d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("AudioSource only support AUDIO_MIC"); 127d5a2a63bSopenharmony_ci return ERR_INVALID_PARAM; 128d5a2a63bSopenharmony_ci } 129d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioAdapter_); 130d5a2a63bSopenharmony_ci 131d5a2a63bSopenharmony_ci struct AudioPortCapability capability; 132d5a2a63bSopenharmony_ci audioAdapter_->GetPortCapability(audioAdapter_, &capturePort_, &capability); 133d5a2a63bSopenharmony_ci AudioDeviceDesc deviceDesc; 134d5a2a63bSopenharmony_ci deviceDesc.deviceId = capability.deviceId; 135d5a2a63bSopenharmony_ci deviceDesc.inputSourceType = AUDIO_MIC; 136d5a2a63bSopenharmony_ci devices.push_back(deviceDesc); 137d5a2a63bSopenharmony_ci return SUCCESS; 138d5a2a63bSopenharmony_ci} 139d5a2a63bSopenharmony_ci 140d5a2a63bSopenharmony_cistatic bool ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat, AudioFormat *audioFormat) 141d5a2a63bSopenharmony_ci{ 142d5a2a63bSopenharmony_ci if (audioFormat == nullptr) { 143d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("audioFormat is NULL"); 144d5a2a63bSopenharmony_ci return false; 145d5a2a63bSopenharmony_ci } 146d5a2a63bSopenharmony_ci 147d5a2a63bSopenharmony_ci switch (codecFormat) { 148d5a2a63bSopenharmony_ci case AUDIO_DEFAULT: 149d5a2a63bSopenharmony_ci case PCM: 150d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT; 151d5a2a63bSopenharmony_ci break; 152d5a2a63bSopenharmony_ci case AAC_LC: 153d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_AAC_LC; 154d5a2a63bSopenharmony_ci break; 155d5a2a63bSopenharmony_ci case AAC_LD: 156d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_AAC_LD; 157d5a2a63bSopenharmony_ci break; 158d5a2a63bSopenharmony_ci case AAC_ELD: 159d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_AAC_ELD; 160d5a2a63bSopenharmony_ci break; 161d5a2a63bSopenharmony_ci case AAC_HE_V1: 162d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V1; 163d5a2a63bSopenharmony_ci break; 164d5a2a63bSopenharmony_ci case AAC_HE_V2: 165d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V2; 166d5a2a63bSopenharmony_ci break; 167d5a2a63bSopenharmony_ci case G711A: 168d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_G711A; 169d5a2a63bSopenharmony_ci break; 170d5a2a63bSopenharmony_ci case G711U: 171d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_G711U; 172d5a2a63bSopenharmony_ci break; 173d5a2a63bSopenharmony_ci case G726: 174d5a2a63bSopenharmony_ci *audioFormat = AUDIO_FORMAT_TYPE_G726; 175d5a2a63bSopenharmony_ci break; 176d5a2a63bSopenharmony_ci default: { 177d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("not support this codecFormat:%d", codecFormat); 178d5a2a63bSopenharmony_ci return false; 179d5a2a63bSopenharmony_ci } 180d5a2a63bSopenharmony_ci } 181d5a2a63bSopenharmony_ci return true; 182d5a2a63bSopenharmony_ci} 183d5a2a63bSopenharmony_ci 184d5a2a63bSopenharmony_ciint32_t AudioSource::Initialize(const AudioSourceConfig &config) 185d5a2a63bSopenharmony_ci{ 186d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioAdapter_); 187d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("deviceId:0x%x config.sampleRate:%d", config.deviceId, config.sampleRate); 188d5a2a63bSopenharmony_ci struct AudioDeviceDescriptor desc; 189d5a2a63bSopenharmony_ci desc.pins = PIN_IN_MIC; 190d5a2a63bSopenharmony_ci desc.desc = NULL; 191d5a2a63bSopenharmony_ci struct AudioSampleAttributes attrs; 192d5a2a63bSopenharmony_ci if (config.streamUsage == TYPE_MEDIA || config.streamUsage == TYPE_DEFAULT) { 193d5a2a63bSopenharmony_ci attrs.type = AUDIO_IN_MEDIA; 194d5a2a63bSopenharmony_ci } else if (config.streamUsage == TYPE_VOICE_COMMUNICATION) { 195d5a2a63bSopenharmony_ci attrs.type = AUDIO_IN_COMMUNICATION; 196d5a2a63bSopenharmony_ci } 197d5a2a63bSopenharmony_ci if (config.bitWidth != BIT_WIDTH_16) { 198d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("not support bitWidth:%d, only support 16 bit width", config.bitWidth); 199d5a2a63bSopenharmony_ci return ERR_INVALID_PARAM; 200d5a2a63bSopenharmony_ci } 201d5a2a63bSopenharmony_ci if (!ConvertCodecFormatToAudioFormat(config.audioFormat, &(attrs.format))) { 202d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("not support audioFormat:%d", config.audioFormat); 203d5a2a63bSopenharmony_ci return ERR_INVALID_PARAM; 204d5a2a63bSopenharmony_ci } 205d5a2a63bSopenharmony_ci attrs.sampleRate = config.sampleRate; 206d5a2a63bSopenharmony_ci attrs.channelCount = config.channelCount; 207d5a2a63bSopenharmony_ci attrs.interleaved = config.interleaved; 208d5a2a63bSopenharmony_ci int32_t ret = audioAdapter_->CreateCapture(audioAdapter_, &desc, &attrs, &audioCapture_); 209d5a2a63bSopenharmony_ci if (ret != SUCCESS || audioCapture_ == nullptr) { 210d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("CreateCapture failed:0x%x", ret); 211d5a2a63bSopenharmony_ci return ret; 212d5a2a63bSopenharmony_ci } 213d5a2a63bSopenharmony_ci initialized_ = true; 214d5a2a63bSopenharmony_ci return SUCCESS; 215d5a2a63bSopenharmony_ci} 216d5a2a63bSopenharmony_ci 217d5a2a63bSopenharmony_ciint32_t AudioSource::SetInputDevice(uint32_t deviceId) 218d5a2a63bSopenharmony_ci{ 219d5a2a63bSopenharmony_ci (void)deviceId; 220d5a2a63bSopenharmony_ci return SUCCESS; 221d5a2a63bSopenharmony_ci} 222d5a2a63bSopenharmony_ci 223d5a2a63bSopenharmony_ciint32_t AudioSource::GetCurrentDeviceId(uint32_t &deviceId) 224d5a2a63bSopenharmony_ci{ 225d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioCapture_); 226d5a2a63bSopenharmony_ci int32_t ret = audioCapture_->attr.GetCurrentChannelId(reinterpret_cast<AudioHandle>(audioCapture_), &deviceId); 227d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 228d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("GetCurrentChannelId failed:0x%x", ret); 229d5a2a63bSopenharmony_ci return ret; 230d5a2a63bSopenharmony_ci } 231d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("deviceId:0x%x", deviceId); 232d5a2a63bSopenharmony_ci return SUCCESS; 233d5a2a63bSopenharmony_ci} 234d5a2a63bSopenharmony_ci 235d5a2a63bSopenharmony_ciint32_t AudioSource::Start() 236d5a2a63bSopenharmony_ci{ 237d5a2a63bSopenharmony_ci int32_t ret; 238d5a2a63bSopenharmony_ci if ((ret = InitCheck()) != SUCCESS) { 239d5a2a63bSopenharmony_ci return ret; 240d5a2a63bSopenharmony_ci } 241d5a2a63bSopenharmony_ci 242d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioCapture_); 243d5a2a63bSopenharmony_ci ret = audioCapture_->control.Start(reinterpret_cast<AudioHandle>(audioCapture_)); 244d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 245d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("audioCapture_ Start failed:0x%x", ret); 246d5a2a63bSopenharmony_ci return ret; 247d5a2a63bSopenharmony_ci } 248d5a2a63bSopenharmony_ci started_ = true; 249d5a2a63bSopenharmony_ci return SUCCESS; 250d5a2a63bSopenharmony_ci} 251d5a2a63bSopenharmony_ci 252d5a2a63bSopenharmony_ciint32_t AudioSource::ReadFrame(AudioFrame &frame, bool isBlockingRead) 253d5a2a63bSopenharmony_ci{ 254d5a2a63bSopenharmony_ci if (!started_) { 255d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("AudioSource not Start"); 256d5a2a63bSopenharmony_ci return ERR_ILLEGAL_STATE; 257d5a2a63bSopenharmony_ci } 258d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioCapture_); 259d5a2a63bSopenharmony_ci uint64_t readlen = ERR_INVALID_READ; 260d5a2a63bSopenharmony_ci int32_t ret = audioCapture_->CaptureFrame(audioCapture_, frame.buffer, frame.bufferLen, &readlen); 261d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 262d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("audioCapture_::CaptureFrame failed:0x%x", ret); 263d5a2a63bSopenharmony_ci return ERR_INVALID_READ; 264d5a2a63bSopenharmony_ci } 265d5a2a63bSopenharmony_ci ret = audioCapture_->GetCapturePosition(audioCapture_, &frame.frames, &frame.time); 266d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 267d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("audioCapture_::GetCapturePosition failed:0x%x", ret); 268d5a2a63bSopenharmony_ci return ERR_INVALID_READ; 269d5a2a63bSopenharmony_ci } 270d5a2a63bSopenharmony_ci return readlen; 271d5a2a63bSopenharmony_ci} 272d5a2a63bSopenharmony_ci 273d5a2a63bSopenharmony_ciint32_t AudioSource::Stop() 274d5a2a63bSopenharmony_ci{ 275d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("AudioSource::Stop"); 276d5a2a63bSopenharmony_ci if (!started_) { 277d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("AudioSource not Start"); 278d5a2a63bSopenharmony_ci return ERR_ILLEGAL_STATE; 279d5a2a63bSopenharmony_ci } 280d5a2a63bSopenharmony_ci 281d5a2a63bSopenharmony_ci AUDIO_RETURN_VAL_IF_NULL(audioCapture_); 282d5a2a63bSopenharmony_ci int32_t ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_)); 283d5a2a63bSopenharmony_ci if (ret != SUCCESS) { 284d5a2a63bSopenharmony_ci MEDIA_ERR_LOG("Stop failed:0x%x", ret); 285d5a2a63bSopenharmony_ci return ret; 286d5a2a63bSopenharmony_ci } 287d5a2a63bSopenharmony_ci started_ = false; 288d5a2a63bSopenharmony_ci return SUCCESS; 289d5a2a63bSopenharmony_ci} 290d5a2a63bSopenharmony_ci 291d5a2a63bSopenharmony_ciint32_t AudioSource::Release() 292d5a2a63bSopenharmony_ci{ 293d5a2a63bSopenharmony_ci int32_t ret; 294d5a2a63bSopenharmony_ci if ((ret = InitCheck()) != SUCCESS) { 295d5a2a63bSopenharmony_ci return ret; 296d5a2a63bSopenharmony_ci } 297d5a2a63bSopenharmony_ci if (audioCapture_) { 298d5a2a63bSopenharmony_ci audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_); 299d5a2a63bSopenharmony_ci audioCapture_ = nullptr; 300d5a2a63bSopenharmony_ci } 301d5a2a63bSopenharmony_ci initialized_ = false; 302d5a2a63bSopenharmony_ci MEDIA_INFO_LOG("AudioSource Released"); 303d5a2a63bSopenharmony_ci return SUCCESS; 304d5a2a63bSopenharmony_ci} 305d5a2a63bSopenharmony_ci} // namespace Audio 306d5a2a63bSopenharmony_ci} // namespace OHOS 307