mirror of
https://github.com/openharmony/multimedia_audio_lite.git
synced 2026-07-01 06:41:22 -04:00
1ed058e72c
Signed-off-by: liyuhang <liyuhang24@huawei.com> Change-Id: I9122303107e38757e2f2882ab4499cd597ad3f95
307 lines
9.7 KiB
C++
307 lines
9.7 KiB
C++
/*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "audio_source.h"
|
|
#include "media_log.h"
|
|
#include "securec.h"
|
|
|
|
namespace OHOS {
|
|
namespace Audio {
|
|
#define AUDIO_RETURN_VAL_IF_NULL(condition) \
|
|
do { \
|
|
if ((condition) == nullptr) { \
|
|
MEDIA_ERR_LOG("" #condition " is NULL"); \
|
|
return ERR_ILLEGAL_STATE; \
|
|
} \
|
|
} while (0)
|
|
|
|
using namespace OHOS::Media;
|
|
static AudioManager *g_audioManager = nullptr;
|
|
|
|
AudioSource::AudioSource()
|
|
: initialized_(false),
|
|
started_(false),
|
|
audioAdapter_(nullptr),
|
|
audioCapture_(nullptr)
|
|
{
|
|
if (g_audioManager == nullptr) {
|
|
g_audioManager = GetAudioManagerFuncs();
|
|
MEDIA_DEBUG_LOG("g_audioManager");
|
|
}
|
|
int size = 0;
|
|
struct AudioAdapterDescriptor *descs = nullptr;
|
|
g_audioManager->GetAllAdapters(g_audioManager, &descs, &size);
|
|
MEDIA_DEBUG_LOG("GetAllAdapters size:%d", size);
|
|
|
|
for (int index = 0; index < size; index++) {
|
|
struct AudioAdapterDescriptor *desc = &descs[index];
|
|
for (int port = 0; (desc != nullptr && port < static_cast<int>(desc->portNum)); port++) {
|
|
if ((desc->ports[port].dir != PORT_IN) ||
|
|
(g_audioManager->LoadAdapter(g_audioManager, desc, &audioAdapter_))) {
|
|
continue;
|
|
}
|
|
(void)audioAdapter_->InitAllPorts(audioAdapter_);
|
|
if (memcpy_s(&capturePort_, sizeof(struct AudioPort),
|
|
&desc->ports[port], sizeof(struct AudioPort))) {
|
|
MEDIA_WARNING_LOG("memcpy_s capturePort_ failed");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
MEDIA_DEBUG_LOG("LoadAdapter audioAdapter_");
|
|
}
|
|
|
|
AudioSource::~AudioSource()
|
|
{
|
|
MEDIA_DEBUG_LOG("in");
|
|
if (initialized_) {
|
|
Release();
|
|
}
|
|
|
|
if (audioAdapter_ != nullptr) {
|
|
MEDIA_INFO_LOG("UnloadModule audioAdapter_");
|
|
if (g_audioManager == nullptr) {
|
|
MEDIA_ERR_LOG("~AudioSource g_audioManager is nullptr");
|
|
audioAdapter_ = nullptr;
|
|
return;
|
|
}
|
|
g_audioManager->UnloadAdapter(g_audioManager, audioAdapter_);
|
|
audioAdapter_ = nullptr;
|
|
}
|
|
}
|
|
|
|
int32_t AudioSource::InitCheck()
|
|
{
|
|
if (!initialized_) {
|
|
MEDIA_ERR_LOG("not initialized");
|
|
return ERR_ILLEGAL_STATE;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
bool AudioSource::GetMinFrameCount(int32_t sampleRate, int32_t channelCount,
|
|
AudioCodecFormat audioFormat, size_t &frameCount)
|
|
{
|
|
if (sampleRate <= 0 || channelCount <= 0 || audioFormat < AUDIO_DEFAULT ||
|
|
audioFormat >= FORMAT_BUTT) {
|
|
MEDIA_ERR_LOG("invalid params sampleRate:%d channelCount:%d audioFormat:%d", sampleRate,
|
|
channelCount, audioFormat);
|
|
return false;
|
|
}
|
|
frameCount = 0;
|
|
return true;
|
|
}
|
|
|
|
uint64_t AudioSource::GetFrameCount()
|
|
{
|
|
int32_t ret;
|
|
if ((ret = InitCheck()) != SUCCESS) {
|
|
return ret;
|
|
}
|
|
AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
|
|
uint64_t frameCount = 0;
|
|
ret = audioCapture_->attr.GetFrameCount(reinterpret_cast<AudioHandle>(audioCapture_), &frameCount);
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("attr GetFrameCount failed:0x%x ", ret);
|
|
return ret;
|
|
}
|
|
return frameCount;
|
|
}
|
|
|
|
int32_t AudioSource::EnumDeviceBySourceType(AudioSourceType inputSource, std::vector<AudioDeviceDesc> &devices)
|
|
{
|
|
if (inputSource != AUDIO_MIC && inputSource != AUDIO_SOURCE_DEFAULT) {
|
|
MEDIA_ERR_LOG("AudioSource only support AUDIO_MIC");
|
|
return ERR_INVALID_PARAM;
|
|
}
|
|
AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
|
|
|
|
struct AudioPortCapability capability;
|
|
audioAdapter_->GetPortCapability(audioAdapter_, &capturePort_, &capability);
|
|
AudioDeviceDesc deviceDesc;
|
|
deviceDesc.deviceId = capability.deviceId;
|
|
deviceDesc.inputSourceType = AUDIO_MIC;
|
|
devices.push_back(deviceDesc);
|
|
return SUCCESS;
|
|
}
|
|
|
|
static bool ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat, AudioFormat *audioFormat)
|
|
{
|
|
if (audioFormat == nullptr) {
|
|
MEDIA_ERR_LOG("audioFormat is NULL");
|
|
return false;
|
|
}
|
|
|
|
switch (codecFormat) {
|
|
case AUDIO_DEFAULT:
|
|
case PCM:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_PCM_16_BIT;
|
|
break;
|
|
case AAC_LC:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_AAC_LC;
|
|
break;
|
|
case AAC_LD:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_AAC_LD;
|
|
break;
|
|
case AAC_ELD:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_AAC_ELD;
|
|
break;
|
|
case AAC_HE_V1:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V1;
|
|
break;
|
|
case AAC_HE_V2:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_AAC_HE_V2;
|
|
break;
|
|
case G711A:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_G711A;
|
|
break;
|
|
case G711U:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_G711U;
|
|
break;
|
|
case G726:
|
|
*audioFormat = AUDIO_FORMAT_TYPE_G726;
|
|
break;
|
|
default: {
|
|
MEDIA_ERR_LOG("not support this codecFormat:%d", codecFormat);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int32_t AudioSource::Initialize(const AudioSourceConfig &config)
|
|
{
|
|
AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
|
|
MEDIA_INFO_LOG("deviceId:0x%x config.sampleRate:%d", config.deviceId, config.sampleRate);
|
|
struct AudioDeviceDescriptor desc;
|
|
desc.pins = PIN_IN_MIC;
|
|
desc.desc = NULL;
|
|
struct AudioSampleAttributes attrs;
|
|
if (config.streamUsage == TYPE_MEDIA || config.streamUsage == TYPE_DEFAULT) {
|
|
attrs.type = AUDIO_IN_MEDIA;
|
|
} else if (config.streamUsage == TYPE_VOICE_COMMUNICATION) {
|
|
attrs.type = AUDIO_IN_COMMUNICATION;
|
|
}
|
|
if (config.bitWidth != BIT_WIDTH_16) {
|
|
MEDIA_ERR_LOG("not support bitWidth:%d, only support 16 bit width", config.bitWidth);
|
|
return ERR_INVALID_PARAM;
|
|
}
|
|
if (!ConvertCodecFormatToAudioFormat(config.audioFormat, &(attrs.format))) {
|
|
MEDIA_ERR_LOG("not support audioFormat:%d", config.audioFormat);
|
|
return ERR_INVALID_PARAM;
|
|
}
|
|
attrs.sampleRate = config.sampleRate;
|
|
attrs.channelCount = config.channelCount;
|
|
attrs.interleaved = config.interleaved;
|
|
int32_t ret = audioAdapter_->CreateCapture(audioAdapter_, &desc, &attrs, &audioCapture_);
|
|
if (ret != SUCCESS || audioCapture_ == nullptr) {
|
|
MEDIA_ERR_LOG("CreateCapture failed:0x%x", ret);
|
|
return ret;
|
|
}
|
|
initialized_ = true;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t AudioSource::SetInputDevice(uint32_t deviceId)
|
|
{
|
|
(void)deviceId;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t AudioSource::GetCurrentDeviceId(uint32_t &deviceId)
|
|
{
|
|
AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
|
|
int32_t ret = audioCapture_->attr.GetCurrentChannelId(reinterpret_cast<AudioHandle>(audioCapture_), &deviceId);
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("GetCurrentChannelId failed:0x%x", ret);
|
|
return ret;
|
|
}
|
|
MEDIA_INFO_LOG("deviceId:0x%x", deviceId);
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t AudioSource::Start()
|
|
{
|
|
int32_t ret;
|
|
if ((ret = InitCheck()) != SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
|
|
ret = audioCapture_->control.Start(reinterpret_cast<AudioHandle>(audioCapture_));
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("audioCapture_ Start failed:0x%x", ret);
|
|
return ret;
|
|
}
|
|
started_ = true;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t AudioSource::ReadFrame(AudioFrame &frame, bool isBlockingRead)
|
|
{
|
|
if (!started_) {
|
|
MEDIA_ERR_LOG("AudioSource not Start");
|
|
return ERR_ILLEGAL_STATE;
|
|
}
|
|
AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
|
|
uint64_t readlen = ERR_INVALID_READ;
|
|
int32_t ret = audioCapture_->CaptureFrame(audioCapture_, frame.buffer, frame.bufferLen, &readlen);
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("audioCapture_::CaptureFrame failed:0x%x", ret);
|
|
return ERR_INVALID_READ;
|
|
}
|
|
ret = audioCapture_->GetCapturePosition(audioCapture_, &frame.frames, &frame.time);
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("audioCapture_::GetCapturePosition failed:0x%x", ret);
|
|
return ERR_INVALID_READ;
|
|
}
|
|
return readlen;
|
|
}
|
|
|
|
int32_t AudioSource::Stop()
|
|
{
|
|
MEDIA_INFO_LOG("AudioSource::Stop");
|
|
if (!started_) {
|
|
MEDIA_ERR_LOG("AudioSource not Start");
|
|
return ERR_ILLEGAL_STATE;
|
|
}
|
|
|
|
AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
|
|
int32_t ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
|
|
if (ret != SUCCESS) {
|
|
MEDIA_ERR_LOG("Stop failed:0x%x", ret);
|
|
return ret;
|
|
}
|
|
started_ = false;
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t AudioSource::Release()
|
|
{
|
|
int32_t ret;
|
|
if ((ret = InitCheck()) != SUCCESS) {
|
|
return ret;
|
|
}
|
|
if (audioCapture_) {
|
|
audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
|
|
audioCapture_ = nullptr;
|
|
}
|
|
initialized_ = false;
|
|
MEDIA_INFO_LOG("AudioSource Released");
|
|
return SUCCESS;
|
|
}
|
|
} // namespace Audio
|
|
} // namespace OHOS
|