标签: oboe

将音频(麦克风)输入共享给 Android 中的多个应用程序

根据官方文档

Android 10(API 级别 29)及更高版本强加了一个优先级方案,可以在应用运行时在应用之间切换输入音频流。在大多数情况下,如果新应用程序获取音频输入,则先前捕获的应用程序会继续运行但会收到静音。在某些情况下,系统可以继续向两个应用程序传送音频。下面解释了各种共享场景。

除了一些特殊情况,应用程序之间不共享音频。

但是我看到很多应用程序共享音频输入而没有在上述特殊情况下。例如。Zoom,当我在通话中进行缩放并启动录音机时,两个应用程序都在获取音频,但缩放音频的强度会降低。

同样,即使其他应用程序可以访问麦克风,Omlet Arcade也能够录制麦克风音频。

这怎么可能?根据文档,这不应该被允许。

更新: 能够通过使用Oboe来实现它。但它在所有设备上并不一致。这也会导致我的直播应用出现同步问题。音频有延迟

audio android oboe

7
推荐指数
1
解决办法
1319
查看次数

如何用 Oboe 正确播放解码的内存 PCM?

我使用oboe来播放 ndk 库中的声音,并使用带有 Android 扩展的 OpenSL将 wav 文件解码为 PCM。解码后的带符号 16 位 PCM 存储在内存中 ( std::forward_list<int16_t>),然后通过回调将它们发送到双簧管流中。我从手机中听到的声音在音量级别上与原始 wav 文件相似,但是这种声音的“质量”却并非如此——它会爆裂和爆裂。

我猜测我以错误的顺序或格式(采样率?)在音频流中发送 PCM。如何使用 OpenSL 解码双簧管音频流?


要将文件解码为 PCM,我使用AndroidSimpleBufferQueue作为接收器,并使用AndroidFD和AAssetManager作为源:

// Loading asset
AAsset* asset = AAssetManager_open(manager, path, AASSET_MODE_UNKNOWN);
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
AAsset_close(asset);

// Creating audio source
SLDataLocator_AndroidFD loc_fd = { SL_DATALOCATOR_ANDROIDFD, fd, start, length };
SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
SLDataSource audio_source = { &loc_fd, &format_mime }; …
Run Code Online (Sandbox Code Playgroud)

audio android android-ndk oboe

5
推荐指数
1
解决办法
1803
查看次数

在 Flutter 应用程序中使用 Android NDK 中的 AssetManager 类

我一直在尝试在我的 Flutter 应用程序中使用 Android NDK 的AssetManager类(它与Google Oboe配合使用)来访问音频文件。按照Oboe 存储库中的这个示例,我了解到他们是AssetManager这样从 Java 获取的:

JNIEXPORT void JNICALL
Java_com_google_oboe_sample_rhythmgame_MainActivity_native_1onStart(JNIEnv *env, jobject instance,
                                                                     jobject jAssetManager) {

    AAssetManager *assetManager = AAssetManager_fromJava(env, jAssetManager);
    if (assetManager == nullptr) {
        LOGE("Could not obtain the AAssetManager");
        return;
    }

    game = std::make_unique<Game>(*assetManager);
    game->start();
}
Run Code Online (Sandbox Code Playgroud)

基本上,它们通过 JNI 接口将参数jAssetManager从 Java 传递到 C++ 函数。现在我不使用 JNI,因为我使用 Flutter 和 Dart,Dart 中与 C++ 函数通信的方式是通过dart:ffi,但由于我可以创建的唯一方法AssetManager是 with AAssetManager_fromJava(env, jAssetManager),所以我需要这两个参数我找不到用 Flutter 和 Dart 替代的方法。

我做了一些研究,当我创建 Flutter FFI …

c++ android-ndk flutter oboe dart-ffi

5
推荐指数
1
解决办法
1366
查看次数

如何使用回调函数从流中读取数据。双簧管-Android

我目前正在开发一个需要低延迟音频的项目,因此我决定使用 Oboe(谷歌库)来处理它。

我已阅读该文档,但其中出现了多个问题。

首先,一旦我使用构建器模式创建流、打开流并请求流启动,我如何捕获从麦克风传入的数据?

我知道有两种方法:使用读取函数或回调。

问题:

  1. 但是,如果我使用读取函数,如何确保只要流启动就正在调用它?

  2. 如何使用回调来获取数据并进行处理?

我将在下面留下我的代码

void HelloOboeEngine::start() {
    isRecording = true;

    oboe::Result result = createStream();
    if (result != oboe::Result::OK) {
        closeStream(mRecordingStream);
    }

    result = mRecordingStream->requestStart();
    if (result != oboe::Result::OK) {
        closeStream(mRecordingStream);
    }
    
}


oboe::Result HelloOboeEngine::createStream() {
    oboe::AudioStreamBuilder builder;
    return builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
            ->setDirection(oboe::Direction::Input)
            ->setFormat(mFormat)
            ->setFormatConversionAllowed(true)
            ->setChannelConversionAllowed(true)
            ->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)
            ->openStream(mRecordingStream);
}

void HelloOboeEngine::closeStream(std::shared_ptr<oboe::AudioStream> &stream) {
    if (stream) {
        oboe::Result result = stream->stop();
        if (result != oboe::Result::OK) {
            LOGW("Error stopping stream: %s", oboe::convertToText(result));
        }
        result = stream->close();
        if (result != oboe::Result::OK) …
Run Code Online (Sandbox Code Playgroud)

android oboe android-audio-streams

5
推荐指数
1
解决办法
381
查看次数