音频录音流程和napi
·
录音模块流程分为以下部分:
1.AudioCapturer:音频捕获的调用入口。
2.AudioService:处理分布式音频服务的音效添加事件
3.AudioPolicy:录音设备的选择,音频策略。
4.Audio_capture:HDF中用于从麦克风或其他音频输入设备中捕获音频数据,并将其保存到文件中。
5.pulseaudio:是一个声音服务器,一个后台进程,它从一个或多个音源(进程或输入设备)接受声音输入,然后重定向声音到一个或多个槽(声卡、远程网络PulseAudio服务或其他进程)。PulseAudio的主要目的是重定向所有声音流。
对应用层提供的napi外部接口与能力。
InitAudioCapturer:初始化音频捕获器的构造函数。它负责设置音频捕获器的初始状态,并将其与JavaScript环境中的构造函数相关联。
CreateAudioCapturerWrapper:创建一个音频捕获器封装的辅助函数,可能用于内部处理或特定的初始化选项。
CreateAudioCapturer、CreateAudioCapturerSync:异步和同步创建音频捕获器的函数。
GetCapturerInfo、GetCapturerInfoSync:异步和同步获取音频捕获器信息的函数。这可能包括捕获器的状态、配置等。
GetStreamInfo、GetStreamInfoSync:异步和同步获取音频流信息的函数。这可能包括音频流的格式、状态等。
Start:开始音频捕获的函数。调用后,音频捕获器将开始捕获音频数据。
Read:读取音频数据的函数。返回捕获的音频数据或提供某种方式来访问这些数据。
GetAudioTime、GetAudioTimeSync:异步和同步获取音频时间的函数。这可能用于同步或其他时间相关的操作。
Stop:停止音频捕获的函数。调用后,音频捕获器将停止捕获音频数据。
Release:释放或关闭音频捕获器的函数。这可能用于清理资源或确保捕获器正确关闭。
GetBufferSize、GetBufferSizeSync:异步和同步获取音频缓冲区大小的函数。
GetAudioStreamId、GetAudioStreamIdSync:异步和同步获取音频流ID的函数。
On、Off:开启或关闭事件的监听。这可能用于处理音频捕获器的事件,如音频数据到达、错误等。
GetCurrentInputDevices:获取当前输入设备的函数。这可能用于选择或显示可用的音频输入设备。
GetCurrentAudioCapturerChangeInfo:获取当前音频捕获器变化信息的函数。这可能用于响应捕获器状态的更改。
GetCurrentMicrophones:获取当前麦克风的函数。这与获取输入设备类似,但可能更专注于麦克风设备。
GetState:获取音频捕获器状态的函数。
GetOverflowCount、GetOverflowCountSync:异步和同步获取溢出计数的函数.
RegisterCallback:注册回调函数的函数。这可能用于处理异步事件或操作的结果。
HDF提供给录音的接口以及能力
AudioCaptureStart:开始音频捕获。给定一个音频句柄(AudioHandle),此函数将启动与该句柄关联的音频捕获设备。
AudioCaptureStop:停止音频捕获。使用与AudioCaptureStart相同的句柄来停止音频捕获。
AudioCapturePause:暂停音频捕获。允许在不停止捕获设备的情况下暂时停止捕获音频数据。
AudioCaptureResume:恢复音频捕获。在暂停后继续捕获音频数据。
AudioCaptureFlush:刷新音频捕获缓冲区。这可能会丢弃缓冲区中的任何未处理数据。
AudioCaptureGetFrameSize:获取音频帧的大小。给定句柄,此函数返回每个音频帧的字节大小。
AudioCaptureGetFrameCount:获取音频帧的数量。返回捕获设备缓冲区中当前存储的音频帧数量。
AudioCaptureSetSampleAttributes / AudioCaptureGetSampleAttributes:设置/获取样本属性。
AudioCaptureGetCurrentChannelId:获取当前音频通道ID。这可能用于多通道音频捕获场景。
AudioCaptureCheckSceneCapability:检查场景功能。给定一个音频场景描述符,此函数检查捕获设备是否支持该场景。
AudioCaptureSelectScene:选择音频场景。根据提供的场景描述符配置捕获设备。
AudioCaptureSetMute / AudioCaptureGetMute:设置/获取静音状态。
AudioCaptureSetVolume / AudioCaptureGetVolume:设置/获取音量级别。
AudioCaptureGetGainThreshold / AudioCaptureGetGain / AudioCaptureSetGain:获取增益阈值、当前增益值或设置增益值。
AudioCaptureCaptureFrame:捕获单个音频帧。此函数可能用于低级音频处理或调试。
AudioCaptureGetCapturePosition:获取捕获位置。返回已捕获音频帧的数量和相关的时间戳。
AudioCaptureSetExtraParams / AudioCaptureGetExtraParams:设置/获取额外参数。这些参数可能用于配置捕获设备的特定行为或特性。
AudioCaptureReqMmapBuffer:请求内存映射缓冲区。此函数可能用于通过内存映射IO(MMIO)直接访问音频数据。
AudioCaptureGetMmapPosition:获取内存映射缓冲区的位置。返回已捕获音频帧的数量和相关的时间戳,类似于AudioCaptureGetCapturePosition,但特定于内存映射缓冲区。
AudioCaptureAddEffect / AudioCaptureRemoveEffect:添加/移除音频效果。这些效果可能包括回声消除、噪声抑制等。
AudioCaptureTurnStandbyMode:将音频捕获设备置于待机模式。这可能用于在不完全关闭设备的情况下减少功耗。
AudioCaptureAudioDevDump:音频设备转储。此函数可能用于调试或收集有关音频捕获设备的详细信息。
start部分
AudioCapturerPrivate::Start()作为start流程的入口,先调用AudioPolicyManager的**ActivateAudioInterrupt()方法,触发音频中断并修改音频场景和路由,再调用audioStream_对象的StartAudioStream()**启动音频流。
bool AudioCapturerPrivate::Start() const
{
Trace trace("AudioCapturer::Start");
AUDIO_INFO_LOG("StreamClientState for Capturer::Start. id %{public}u, sourceType: %{public}d",
sessionID_, audioInterrupt_.audioFocusType.sourceType);
CHECK_AND_RETURN_RET_LOG(!isSwitching_, false, "Operation failed, in switching");
CHECK_AND_RETURN_RET(audioInterrupt_.audioFocusType.sourceType != SOURCE_TYPE_INVALID &&
audioInterrupt_.sessionId != INVALID_SESSION_ID, false);
int32_t ret = AudioPolicyManager::GetInstance().ActivateAudioInterrupt(audioInterrupt_);
CHECK_AND_RETURN_RET_LOG(ret == 0, false, "ActivateAudioInterrupt Failed");
// When the cellular call stream is starting, only need to activate audio interrupt.
CHECK_AND_RETURN_RET(!isVoiceCallCapturer_, true);
bool result = audioStream_->StartAudioStream();
if (!result) {
AUDIO_ERR_LOG("Start audio stream failed");
ret = AudioPolicyManager::GetInstance().DeactivateAudioInterrupt(audioInterrupt_);
if (ret != 0) {
AUDIO_WARNING_LOG("DeactivateAudioInterrupt Failed");
}
}
return result;
}
进入HDF层的start
/* add For Capture Bytes To Frames */
int32_t AudioCaptureStart(struct IAudioCapture *handle)
{
AUDIO_FUNC_LOGI("AudioCaptureStart Enter.");
struct AudioHwCapture *hwCapture = (struct AudioHwCapture *)handle;
if (hwCapture == NULL) {
AUDIO_FUNC_LOGE("The hwCapture is NULL");
return AUDIO_ERR_INVALID_PARAM;
}
InterfaceLibModeCapturePassthrough *pInterfaceLibModeCapture = AudioPassthroughGetInterfaceLibModeCapture();
if (pInterfaceLibModeCapture == NULL || *pInterfaceLibModeCapture == NULL) {
AUDIO_FUNC_LOGE("pInterfaceLibModeCapture Fail!");
return AUDIO_ERR_INTERNAL;
}
pthread_mutex_lock(&hwCapture->captureParam.frameCaptureMode.mutex);
if (hwCapture->captureParam.frameCaptureMode.buffer != NULL) {
pthread_mutex_unlock(&hwCapture->captureParam.frameCaptureMode.mutex);
AUDIO_FUNC_LOGE("IAudioCapture already start!");
return AUDIO_SUCCESS; // capture is busy now
}
if (hwCapture->devDataHandle == NULL) {
pthread_mutex_unlock(&hwCapture->captureParam.frameCaptureMode.mutex);
AUDIO_FUNC_LOGE("CaptureStart Bind Fail!");
return AUDIO_ERR_INTERNAL;
}
int32_t ret = (*pInterfaceLibModeCapture)(
hwCapture->devDataHandle, &hwCapture->captureParam, AUDIO_DRV_PCM_IOCTRL_START_CAPTURE);
if (ret < 0) {
pthread_mutex_unlock(&hwCapture->captureParam.frameCaptureMode.mutex);
AUDIO_FUNC_LOGE("AudioCaptureStart SetParams FAIL");
return AUDIO_ERR_INTERNAL;
}
char *tbuffer = (char *)OsalMemCalloc(FRAME_DATA);
if (tbuffer == NULL) {
pthread_mutex_unlock(&hwCapture->captureParam.frameCaptureMode.mutex);
AUDIO_FUNC_LOGE("Calloc Capture tbuffer Fail!");
return AUDIO_ERR_MALLOC_FAIL;
}
hwCapture->captureParam.frameCaptureMode.buffer = tbuffer;
pthread_mutex_unlock(&hwCapture->captureParam.frameCaptureMode.mutex);
AudioLogRecord(AUDIO_INFO, "[%s]-[%s]-[%d] :> [%s]", __FILE__, __func__, __LINE__, "Audio Capture Start");
return AUDIO_SUCCESS;
}
调用alsa的start
int32_t AudioOutputCaptureStart(
const struct DevHandle *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
{
int32_t ret;
struct AlsaCapture *captureIns = NULL;
CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
captureIns = CaptureGetInstance(handleData->captureMode.hwInfo.adapterName);
CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
ret = captureIns->Start(captureIns, handleData);
if (ret != HDF_SUCCESS) {
AUDIO_FUNC_LOGE("Capture start failed!");
return ret;
}
AUDIO_FUNC_LOGI("Capture start success.");
return HDF_SUCCESS;
}
更多推荐

所有评论(0)