diff --git a/en/application-dev/media/Readme-EN.md b/en/application-dev/media/Readme-EN.md index f4c117684b891c43b1dd94513420f6793f52d886..c42fd8cdfe9f24f7040ce8e52268a15bfced04fb 100755 --- a/en/application-dev/media/Readme-EN.md +++ b/en/application-dev/media/Readme-EN.md @@ -8,13 +8,15 @@ - [Audio Rendering Development](audio-renderer.md) - [Audio Capture Development](audio-capturer.md) - [OpenSL ES Audio Playback Development](opensles-playback.md) + - [OpenSL ES Audio Recording Development](opensles-capture.md) + - Video - - [Video Playback Development](video-playback.md) - - [Video Recording Development](video-recorder.md) - + - Image - - [Image Development](image.md) + +- Camera + - [Camera Development](camera.md) diff --git a/en/application-dev/media/opensles-capture.md b/en/application-dev/media/opensles-capture.md new file mode 100644 index 0000000000000000000000000000000000000000..d7aab6606fc0ca49220892e077de2fa5db73ec98 --- /dev/null +++ b/en/application-dev/media/opensles-capture.md @@ -0,0 +1,162 @@ +# OpenSL ES Audio Recording Development + +## When to Use + +You can use OpenSL ES to develop the audio recording function in OpenHarmony. Currently, only some +[OpenSL ES APIs](https://gitee.com/openharmony/third_party_opensles/blob/master/api/1.0.1/OpenSLES.h) are implemented. If an API that has not been implemented yet is called, **SL_RESULT_FEATURE_UNSUPPORTED** will be returned. + + + +## How to Develop + +To use OpenSL ES to develop the audio recording function in OpenHarmony, perform the following steps: + +1. Add the header files. + + ```c++ + #include + #include + #include + ``` + +2. Use the **slCreateEngine** API to create and instantiate the **engine** instance. + + ```c++ + SLObjectItf engineObject = nullptr; + slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr); + (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); + ``` + + + +3. Obtain the **engineEngine** instance of the **SL_IID_ENGINE** interface. + + ```c++ + SLEngineItf engineItf = nullptr; + result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf); + ``` + + + +4. Configure the recorder information (including the input source **audiosource** and output source **audiosink**), and create a **pcmCapturerObject** instance. + + ```c++ + SLDataLocator_IODevice io_device = { + SL_DATALOCATOR_IODEVICE, + SL_IODEVICE_AUDIOINPUT, + SL_DEFAULTDEVICEID_AUDIOINPUT, + NULL + }; + + SLDataSource audioSource = { + &io_device, + NULL + }; + + SLDataLocator_BufferQueue buffer_queue = { + SL_DATALOCATOR_BUFFERQUEUE, + 3 + }; + + // Configure the parameters based on the audio file format. + SLDataFormat_PCM format_pcm = { + SL_DATAFORMAT_PCM, + OHOS::AudioStandard::AudioChannel::MONO, + OHOS::AudioStandard::AudioSamplingRate::SAMPLE_RATE_44100, + OHOS::AudioStandard::AudioSampleFormat::SAMPLE_S16LE, + 0, + 0, + 0 + }; + + SLDataSink audioSink = { + &buffer_queue, + &format_pcm + }; + + SLObjectItf pcmCapturerObject = nullptr; + result = (*engineItf)->CreateAudioRecorder(engineItf, &pcmCapturerObject, + &audioSource, &audioSink, 0, nullptr, nullptr); + (*pcmCapturerObject)->Realize(pcmCapturerObject, SL_BOOLEAN_FALSE); + ``` + +5. Obtain the **recordItf** instance of the **SL_IID_RECORD** interface. + + ``` + SLRecordItf recordItf; + (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_RECORD, &recordItf); + ``` + +6. Obtain the **bufferQueueItf** instance of the **SL_IID_OH_BUFFERQUEUE** interface. + + ``` + SLOHBufferQueueItf bufferQueueItf; + (*pcmCapturerObject)->GetInterface(pcmCapturerObject, SL_IID_OH_BUFFERQUEUE, &bufferQueueItf); + ``` + + + +7. Register the **BufferQueueCallback** function. + + ```c++ + static void BufferQueueCallback(SLOHBufferQueueItf bufferQueueItf, void *pContext, SLuint32 size) + { + AUDIO_INFO_LOG("BufferQueueCallback"); + FILE *wavFile = (FILE *)pContext; + if (wavFile != nullptr) { + SLuint8 *buffer = nullptr; + SLuint32 pSize = 0; + (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize); + if (buffer != nullptr) { + fwrite(buffer, 1, pSize, wavFile); + (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, size); + } + } + + return; + } + + // Set wavFile_ to the descriptor of the file to be recorded. + (*bufferQueueItf)->RegisterCallback(bufferQueueItf, BufferQueueCallback, wavFile_); + ``` + + +8. Start audio recording. + + ```c++ + static void CaptureStart(SLRecordItf recordItf, SLOHBufferQueueItf bufferQueueItf, FILE *wavFile) + { + AUDIO_INFO_LOG("CaptureStart"); + (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING); + if (wavFile != nullptr) { + SLuint8* buffer = nullptr; + SLuint32 pSize = 0; + (*bufferQueueItf)->GetBuffer(bufferQueueItf, &buffer, pSize); + if (buffer != nullptr) { + AUDIO_INFO_LOG("CaptureStart, enqueue buffer length: %{public}lu.", pSize); + fwrite(buffer, 1, pSize, wavFile); + (*bufferQueueItf)->Enqueue(bufferQueueItf, buffer, pSize); + } else { + AUDIO_INFO_LOG("CaptureStart, buffer is null or pSize: %{public}lu.", pSize); + } + } + + return; + } + ``` + + +9. Stop audio recording. + + ```c++ + static void CaptureStop(SLRecordItf recordItf) + { + AUDIO_INFO_LOG("Enter CaptureStop"); + fflush(wavFile_); + (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_STOPPED); + (*pcmCapturerObject)->Destroy(pcmCapturerObject); + fclose(wavFile_); + wavFile_ = nullptr; + return; + } + ```