录音模块流程分为以下部分:

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的函数。
OnOff:开启或关闭事件的监听。这可能用于处理音频捕获器的事件,如音频数据到达、错误等。
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;
}
Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐