* Copyright (C) 2025 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 "napi/native_api.h"
#include "ohaudio/native_audiorenderer.h"
#include <ohaudio/native_audiocapturer.h>
#include <ohaudio/native_audiostreambuilder.h>
#include <sstream>
#include <cstring>
void MyOnReadData_NewAPI(
OH_AudioCapturer* capturer,
void* userData,
void* audioData,
int32_t audioDataSize)
{
}
void MyOnInterruptEvent_NewAPI(
OH_AudioCapturer* capturer,
void* userData,
OH_AudioInterrupt_ForceType type,
OH_AudioInterrupt_Hint hint)
{
}
void MyOnError_NewAPI(
OH_AudioCapturer* capturer,
void* userData,
OH_AudioStream_Result error)
{
}
int32_t MyOnReadData_Legacy(
OH_AudioCapturer* capturer,
void* userData,
void* buffer,
int32_t length)
{
return 0;
}
int32_t MyOnInterruptEvent_Legacy(
OH_AudioCapturer* capturer,
void* userData,
OH_AudioInterrupt_ForceType type,
OH_AudioInterrupt_Hint hint)
{
return 0;
}
int32_t MyOnStreamEvent_Legacy(
OH_AudioCapturer* capturer,
void* userData,
OH_AudioStream_Event event)
{
return 0;
}
int32_t MyOnError_Legacy(
OH_AudioCapturer* capturer,
void* userData,
OH_AudioStream_Result error)
{
return 0;
}
int32_t MyOnWriteData(
OH_AudioRenderer* renderer,
void* userData,
void* buffer,
int32_t length)
{
return 0;
}
int32_t MyOnStreamEvent_Renderer(
OH_AudioRenderer* renderer,
void* userData,
OH_AudioStream_Event event)
{
return 0;
}
int32_t MyOnInterruptEvent_Renderer(
OH_AudioRenderer* renderer,
void* userData,
OH_AudioInterrupt_ForceType type,
OH_AudioInterrupt_Hint hint)
{
return 0;
}
int32_t MyOnError_Renderer(
OH_AudioRenderer* renderer,
void* userData,
OH_AudioStream_Result error)
{
return 0;
}
napi_value CreateAudioCapturer(napi_env env, napi_callback_info info)
{
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);
OH_AudioCapturer_OnInterruptCallback OnIntereruptCb = MyOnInterruptEvent_NewAPI;
OH_AudioStreamBuilder_SetCapturerInterruptCallback(builder, OnIntereruptCb, nullptr);
OH_AudioCapturer_OnErrorCallback OnErrorCb = MyOnError_NewAPI;
OH_AudioStreamBuilder_SetCapturerErrorCallback(builder, OnErrorCb, nullptr);
OH_AudioCapturer_OnReadDataCallback OnReadDataCb = MyOnReadData_NewAPI;
OH_AudioStreamBuilder_SetCapturerReadDataCallback(builder, OnReadDataCb, nullptr);
OH_AudioCapturer* audioCapturer;
OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
OH_AudioStreamBuilder_Destroy(builder);
std::stringstream ss;
ss << "创建录制音频流成功\n";
ss << "采样率: 48000Hz\n";
ss << "声道数: 2\n";
ss << "回调方式: 新版API";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
napi_value CreateAudioCapturerLegacy1(napi_env env, napi_callback_info info)
{
std::stringstream ss;
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);
OH_AudioCapturer_Callbacks callbacks;
callbacks.OH_AudioCapturer_OnReadData = MyOnReadData_Legacy;
callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent_Legacy;
callbacks.OH_AudioCapturer_OnStreamEvent = nullptr;
callbacks.OH_AudioCapturer_OnError = nullptr;
OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);
OH_AudioCapturer* audioCapturer;
OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
OH_AudioStreamBuilder_Destroy(builder);
ss << "创建录制音频流成功(使用空指针初始化)\n";
ss << "使用空指针初始化未使用的回调";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
napi_value CreateAudioCapturerLegacy2(napi_env env, napi_callback_info info)
{
std::stringstream ss;
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);
OH_AudioCapturer_Callbacks callbacks = {0};
callbacks.OH_AudioCapturer_OnReadData = MyOnReadData_Legacy;
callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent_Legacy;
OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);
OH_AudioCapturer* audioCapturer;
OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
OH_AudioStreamBuilder_Destroy(builder);
ss << "创建录制音频流成功(使用清零结构体初始化)\n";
ss << "使用清零结构体";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
napi_value CreateAudioCapturerLoopback(napi_env env, napi_callback_info info)
{
OH_AudioStream_Type streamType = AUDIOSTREAM_TYPE_CAPTURER;
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, streamType);
OH_AudioStream_LatencyMode latencyMode = AUDIOSTREAM_LATENCY_MODE_FAST;
OH_AudioStreamBuilder_SetLatencyMode(builder, latencyMode);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);
OH_AudioCapturer_Callbacks callbacks;
callbacks.OH_AudioCapturer_OnReadData = MyOnReadData_Legacy;
callbacks.OH_AudioCapturer_OnStreamEvent = MyOnStreamEvent_Legacy;
callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent_Legacy;
callbacks.OH_AudioCapturer_OnError = MyOnError_Legacy;
OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);
OH_AudioCapturer* audioCapturer;
OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
OH_AudioStreamBuilder_Destroy(builder);
std::stringstream ss;
ss << "创建耳返录制流成功\n";
ss << "时延模式: FAST";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
napi_value CreateLowLatencyModeCapturer(napi_env env, napi_callback_info info)
{
std::stringstream ss;
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);
OH_AudioStream_LatencyMode latencyMode = AUDIOSTREAM_LATENCY_MODE_FAST;
OH_AudioStreamBuilder_SetLatencyMode(builder, latencyMode);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);
OH_AudioCapturer_OnReadDataCallback readDataCb = MyOnReadData_NewAPI;
OH_AudioStreamBuilder_SetCapturerReadDataCallback(builder, readDataCb, nullptr);
OH_AudioCapturer* audioCapturer;
OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
OH_AudioStreamBuilder_Destroy(builder);
ss << "创建低时延模式录制流成功\n";
ss << "时延模式: FAST\n";
ss << "适用场景: k歌、直播";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
napi_value CreateAudioRendererLoopback(napi_env env, napi_callback_info info)
{
OH_AudioStreamBuilder* builder;
OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER);
OH_AudioStream_LatencyMode latencyMode = AUDIOSTREAM_LATENCY_MODE_FAST;
OH_AudioStreamBuilder_SetLatencyMode(builder, latencyMode);
const int SAMPLING_RATE_48K = 48000;
OH_AudioStreamBuilder_SetSamplingRate(builder, SAMPLING_RATE_48K);
const int channelCount = 2;
OH_AudioStreamBuilder_SetChannelCount(builder, channelCount);
OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);
OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);
OH_AudioStreamBuilder_SetRendererInfo(builder, AUDIOSTREAM_USAGE_MUSIC);
OH_AudioRenderer_Callbacks callbacks;
callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
callbacks.OH_AudioRenderer_OnStreamEvent = MyOnStreamEvent_Renderer;
callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent_Renderer;
callbacks.OH_AudioRenderer_OnError = MyOnError_Renderer;
OH_AudioStreamBuilder_SetRendererCallback(builder, callbacks, nullptr);
OH_AudioRenderer* audioRenderer;
OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);
OH_AudioStreamBuilder_Destroy(builder);
std::stringstream ss;
ss << "创建耳返播放流成功\n";
ss << "时延模式: FAST";
napi_value retVal;
napi_create_string_utf8(env, ss.str().c_str(), NAPI_AUTO_LENGTH, &retVal);
return retVal;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{"CreateAudioCapturer", nullptr, CreateAudioCapturer, nullptr, nullptr, nullptr, napi_default, nullptr},
{"CreateAudioCapturerLegacy1", nullptr, CreateAudioCapturerLegacy1, nullptr, nullptr, nullptr, napi_default,
nullptr},
{"CreateAudioCapturerLegacy2", nullptr, CreateAudioCapturerLegacy2, nullptr, nullptr, nullptr, napi_default,
nullptr},
{"CreateAudioCapturerLoopback", nullptr, CreateAudioCapturerLoopback, nullptr, nullptr, nullptr, napi_default,
nullptr},
{"CreateLowLatencyModeCapturer", nullptr, CreateLowLatencyModeCapturer, nullptr, nullptr, nullptr, napi_default,
nullptr},
{"CreateAudioRendererLoopback", nullptr, CreateAudioRendererLoopback, nullptr, nullptr, nullptr, napi_default,
nullptr},
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = ((void *)0),
.reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }