使用OpenSL ES開發(fā)音頻錄制功能

2024-02-16 13:56 更新

OpenSL ES全稱為Open Sound Library for Embedded Systems,是一個嵌入式、跨平臺、免費的音頻處理庫。為嵌入式移動多媒體設備上的應用開發(fā)者提供標準化、高性能、低延遲的API。HarmonyOS的Native API基于Khronos Group開發(fā)的OpenSL ES 1.0.1 API 規(guī)范實現(xiàn),開發(fā)者可以通過<OpenSLES.h>和<OpenSLES_OpenHarmony.h>在HarmonyOS上使用相關API。

HarmonyOS上的OpenSL ES

OpenSL ES中提供了以下的接口,HarmonyOS當前僅實現(xiàn)了部分OpenSL ES接口,可以實現(xiàn)音頻錄制的基礎功能。

調用未實現(xiàn)接口后會返回SL_RESULT_FEATURE_UNSUPPORTED,當前沒有相關擴展可以使用。

以下列表列舉了HarmonyOS上已實現(xiàn)的OpenSL ES的接口,具體說明請參考OpenSL ES規(guī)范:

  • HarmonyOS上支持的Engine接口
    • SLresult (*CreateAudioPlayer) (SLEngineItf self, SLObjectItf * pPlayer, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, const SLInterfaceID * pInterfaceIds, const SLboolean * pInterfaceRequired)
    • SLresult (*CreateAudioRecorder) (SLEngineItf self, SLObjectItf * pRecorder, SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces, const SLInterfaceID * pInterfaceIds, const SLboolean * pInterfaceRequired)
    • SLresult (*CreateOutputMix) (SLEngineItf self, SLObjectItf * pMix, SLuint32 numInterfaces, const SLInterfaceID * pInterfaceIds, const SLboolean * pInterfaceRequired)
  • HarmonyOS上支持的Object接口:
    • SLresult (*Realize) (SLObjectItf self, SLboolean async)
    • SLresult (*GetState) (SLObjectItf self, SLuint32 * pState)
    • SLresult (*GetInterface) (SLObjectItf self, const SLInterfaceID iid, void * pInterface)
    • void (*Destroy) (SLObjectItf self)
  • HarmonyOS上支持的Recorder接口:
    • SLresult (*SetRecordState) (SLRecordItf self, SLuint32 state)
    • SLresult (*GetRecordState) (SLRecordItf self,SLuint32 *pState)
  • HarmonyOS上支持的BufferQueue接口
    以下接口需引入<OpenSLES_OpenHarmony.h>使用。

    接口

    說明

    SLresult (*Enqueue) (SLOHBufferQueueItf self, const void *buffer, SLuint32 size)

    根據(jù)情況將buffer加到相應隊列中。

    如果是播放操作,則將帶有音頻數(shù)據(jù)的buffer插入到filledBufferQ_隊列中;如果是錄音操作,則將錄音使用后的空閑buffer插入到freeBufferQ_隊列中。

    self:表示調用該函數(shù)的BufferQueue接口對象。

    buffer:播放時表示帶有音頻數(shù)據(jù)的buffer,錄音時表示已存儲完錄音數(shù)據(jù)后的空閑buffer。

    size:表示buffer的大小。

    SLresult (*Clear) (SLOHBufferQueueItf self)

    釋放BufferQueue接口對象。

    self:表示調用該函數(shù)的BufferQueue接口對象將被釋放。

    SLresult (*GetState) (SLOHBufferQueueItf self, SLOHBufferQueueState *state)

    獲取BufferQueue接口對象狀態(tài)。

    self:表示調用該函數(shù)的BufferQueue接口對象。

    state:BufferQueue的當前狀態(tài)。

    SLresult (*RegisterCallback) (SLOHBufferQueueItf self, SlOHBufferQueueCallback callback, void* pContext)

    注冊回調函數(shù)。

    self:表示調用該函數(shù)的BufferQueue接口對象。

    callback:播放/錄音時注冊的回調函數(shù)。

    pContext:播放時傳入待播放音頻文件,錄音時傳入將要錄制的音頻文件。

    SLresult (*GetBuffer) (SLOHBufferQueueItf self, SLuint8** buffer, SLuint32* size)

    根據(jù)情況獲取相應的buffer。

    如果是播放操作,則從freeBufferQ_隊列中獲取空閑buffer;如果是錄音操作,則從filledBufferQ_隊列中獲取攜帶錄音數(shù)據(jù)的buffer。

    self:表示調用該函數(shù)的BufferQueue接口對象。

    buffer:播放時表示空閑的buffer,錄音時表示攜帶錄音數(shù)據(jù)的buffer。

    size:表示buffer的大小。

完整示例

參考下列示例代碼,完成音頻錄制。

  1. 添加頭文件
    1. #include <OpenSLES.h>
    2. #include <OpenSLES_OpenHarmony.h>
    3. #include <OpenSLES_Platform.h>
  2. 使用slCreateEngine接口創(chuàng)建引擎對象和實例化引擎對象engine。
    1. SLObjectItf engineObject = nullptr;
    2. slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
    3. (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
  3. 獲取接口SL_IID_ENGINE的引擎接口engineEngine實例。
    1. SLEngineItf engineItf = nullptr;
    2. (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
  4. 配置錄音器信息(配置輸入源audiosource、輸出源audiosink),創(chuàng)建錄音對象pcmCapturerObject。
    1. SLDataLocator_IODevice io_device = {
    2. SL_DATALOCATOR_IODEVICE,
    3. SL_IODEVICE_AUDIOINPUT,
    4. SL_DEFAULTDEVICEID_AUDIOINPUT,
    5. NULL
    6. };
    7. SLDataSource audioSource = {
    8. &io_device,
    9. NULL
    10. };
    11. SLDataLocator_BufferQueue buffer_queue = {
    12. SL_DATALOCATOR_BUFFERQUEUE,
    13. 3
    14. };
    15. // 具體參數(shù)需要根據(jù)音頻文件格式進行適配
    16. SLDataFormat_PCM format_pcm = {
    17. SL_DATAFORMAT_PCM, // 輸入的音頻格式
    18. 1, // 單聲道
    19. SL_SAMPLINGRATE_44_1, // 采樣率: 44100HZ
    20. SL_PCMSAMPLEFORMAT_FIXED_16, // 音頻采樣格式,小尾數(shù),帶符號的16位整數(shù)
    21. 0,
    22. 0,
    23. 0
    24. };
    25. SLDataSink audioSink = {
    26. &buffer_queue,
    27. &format_pcm
    28. };
    29. SLObjectItf pcmCapturerObject = nullptr;
    30. (*engineItf)->CreateAudioRecorder(engineItf, &pcmCapturerObject,
    31. &audioSource, &audioSink, 0, nullptr, nullptr);
    32. (*pcmCapturerObject)->Realize(pcmCapturerObject, SL_BOOLEAN_FALSE);
  5. 獲取錄音接口SL_IID_RECORD的recordItf接口實例。
    1. SLRecordItf recordItf;
    2. (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_RECORD, &recordItf);
  6. 獲取接口 SL_IID_OH_BUFFERQUEUE 的 bufferQueueItf 實例
    1. SLOHBufferQueueItf bufferQueueItf;
    2. (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf);
  7. 注冊BufferQueueCallback回調。
    1. static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size)
    2. {
    3. // 可從pContext獲取注冊時傳入的使用者信息
    4. SLuint8 *buffer = nullptr;
    5. SLuint32 pSize = 0;
    6. (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, &pSize);
    7. if (buffer != nullptr) {
    8. // 可從buffer內讀取錄音數(shù)據(jù)進行后續(xù)處理
    9. (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size);
    10. }
    11. }
    12. void *pContext; // 可傳入自定義的上下文信息,會在Callback內收到
    13. (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, pContext);
  8. 開始錄音。
    1. (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING);
  9. 結束音頻錄制。
    1. (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED);
    2. (*pcmCapturerObject)->Destroy(pcmCapturerObject);
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號