我一直在尝试使用可用于使用android 2.3进行本机音频的OpenSL ES库,但看起来头文件和规范的600页pdf是唯一可用的文档.
我应该在哪里寻找示例,教程或功能的简要概述?
我目前正在尝试最小化简单应用程序的音频延迟:
我在PC上有一个视频,我正在通过RTP将视频的音频传输到移动客户端.使用非常相似的缓冲算法,我可以在iOS上实现90ms的延迟,但在Android上可以实现±180ms的可怕延迟.
然而,在阅读了一下后,我发现了这篇文章,其中指出:
自Android 4.1/4.2以来,在某些设备中可以使用低延迟音频.
使用libpd可以实现低延迟音频,libpd是Android的纯数据库.
我有两个问题,与这两个陈述直接相关:
我在哪里可以找到有关Jellybean中新的低延迟音频的更多信息?这是我能找到的全部,但它缺乏具体的信息.如果这些更改对我来说是透明的,或者是否有一些新的类/ API调用我应该实现我注意到我的应用程序中的任何更改?我正在使用AudioTrack API,我甚至不确定它是否应该从这种改进中获益,或者我是否应该研究其他一些音频播放机制.
我应该考虑使用libpd吗?在我看来,这是我实现更低延迟的唯一机会,但由于我一直认为PD是一个音频合成实用程序,它是否真的适合于只从网络流中抓取帧并播放它们的项目?我不是在做任何合成.我跟踪错误的踪迹吗?
另外需要注意的是,在有人提到OpenSL ES之前,本文非常清楚地表明使用它时不应期望延迟有所改善:
"由于OpenSL ES是本机C API,调用OpenSL ES的非Dalvik应用程序线程没有与Dalvik相关的开销,例如垃圾收集暂停.但是,除此之外,使用OpenSL ES没有额外的性能优势.特别是,使用OpenSL ES不会导致比平台通常提供的更低的音频延迟,更高的调度优先级等."
我想使用OpenSL ES FileDescriptor对象从音频资产中获取字节缓冲区,因此我可以将其重复排队到SimpleBufferQueue,而不是使用SL接口来播放/停止/搜索文件.
我想直接管理样本字节有三个主要原因:
好的,所以理由完成 - 这就是我尝试过的 - 我有一个Sample结构,它实质上包含一个输入和输出轨道,以及一个用于保存样本的字节数组.输入是我的FileDescriptor播放器,输出是SimpleBufferQueue对象.这是我的结构:
typedef struct Sample_ {
// buffer to hold all samples
short *buffer;
int totalSamples;
SLObjectItf fdPlayerObject;
// file descriptor player interfaces
SLPlayItf fdPlayerPlay;
SLSeekItf fdPlayerSeek;
SLMuteSoloItf fdPlayerMuteSolo;
SLVolumeItf fdPlayerVolume;
SLAndroidSimpleBufferQueueItf fdBufferQueue;
SLObjectItf outputPlayerObject;
SLPlayItf outputPlayerPlay;
// output buffer interfaces
SLAndroidSimpleBufferQueueItf outputBufferQueue;
} Sample;
Run Code Online (Sandbox Code Playgroud)
初始化文件播放器fdPlayerObject后,以及用于我的字节缓冲区的malloc-ing内存
sample->buffer = malloc(sizeof(short)*sample->totalSamples);
Run Code Online (Sandbox Code Playgroud)
我正在使用它的BufferQueue接口
// get the buffer queue interface
result = (*(sample->fdPlayerObject))->GetInterface(sample->fdPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(sample->fdBufferQueue));
Run Code Online (Sandbox Code Playgroud)
然后我实例化一个 …
有没有人有经验(使用OpenSL ES,ALSA等)在Android中重定向音频或创建新的声音路径?最终目标是创建一个虚拟麦克风来替换外部麦克风,在那里可以播放音频文件,就好像他们正在对着麦克风讲话一样.访问麦克风的应用程序AudioSource.MIC应使用此备用流.它没有必要使用语音呼叫,我相信实现这种功能更难,因为它都是在无线电中完成的.
关于从哪里开始的任何想法?我已经用OpenSL和ALSA做了一些研究,但看起来我需要打包新固件(ROM)才能定义自定义音频路径.如果可以避免,我想创建一个应用程序级解决方案.电话是"扎根"(有su二进制文件).目标设备是三星Galaxy S4谷歌版(GT-i9505G).具体来说,我正在寻找音频驱动程序配置/源代码或i9505G的任何参考.
提前致谢!
编辑 - 我已经检查了CyanogenMod 10.2源代码树,以及jfltexx驱动程序和内核.以下是kernel/samsung/jf/sound的内容:http://pastebin.com/7vK8THcZ.这记录在哪里?
将音频发送到扬声器以便在Android上播放很容易,但是是否可以获得实际最终数字信号的副本?假设我有两个运行"MyApp"和"SomeOtherApp"的应用程序.我的应用程序向扬声器发送音频,但"SomeOtherApp"也是如此."SomeOtherApp"不是我的应用程序 - 它是第三方应用程序.是否有可能获得操作系统播放到扬声器的混合音频信号的副本?也就是说,音频信号是来自我的app的扬声器信号和来自"SomeOtherApp"的扬声器信号的混合.
总结一下:我正在寻找一种方法来连接低级音频路径(HAL音频流输出 - 混音后!)所以我可以获得"最终"扬声器信号的副本(实时).最理想的情况是,我还想加入低级麦克风路径,但现在这不是一个问题.
目前我正在使用AudioTrack传递来自本机层的音频数据来播放.
我似乎可以在本机层使用OpenSL ES而不是Java中的AudioTrack.与AudioTrack相比,OpenSL ES提供了哪些优势?
在我的Android项目中,我使用OpenSL ES来播放音频文件.我希望能够通过提取音频样本,处理它们并将它们重定向到音频输出来动态处理音频.
这是我到目前为止尝试的内容:
// create the engine and output mix objects
void Java_com_ywl5320_openslaudio_MainActivity_createEngine(JNIEnv* env, jclass clazz, int newsamplerate, int newbuffersize)
{
SLresult result;
audioBuffer = calloc(buffersize, sizeof(int16_t));
buffersize = newbuffersize;
samplerate = newsamplerate;
// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
(void)result;
// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void)result;
// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS …Run Code Online (Sandbox Code Playgroud) 我正试图通过接入点使用WiFi将MP3从Android手机流式传输到另一部Android手机.问题是OpenSL ES似乎只支持PCM音频缓冲区作为源(除非使用URI).而不是在发送之前解码"主"侧的潜在巨大文件我宁愿让"客户端"将MP3解码为PCM.请记住,这必须作为文件流发生,而不是简单地发送整个文件然后解码.有没有办法使用OpenSL ES来实现这一目标?AudioTrack?这似乎是一个相当普遍的要求.
我是一名Android App开发人员,我遇到了以下崩溃报告(我每天有5/6):
native: pc 00000000000418e0 /system/lib/libc.so (tgkill+12)
native: pc 0000000000040d59 /system/lib/libc.so (pthread_kill+32)
native: pc 000000000001c7eb /system/lib/libc.so (raise+10)
native: pc 000000000001999d /system/lib/libc.so (__libc_android_abort+34)
native: pc 0000000000017550 /system/lib/libc.so (abort+4)
native: pc 0000000000008d53 /system/lib/libcutils.so (__android_log_assert+86)
native: pc 000000000006e2c3 /system/lib/libmedia.so (_ZN7android11ClientProxy13releaseBufferEPNS_5Proxy6BufferE+94)
native: pc 000000000006c11d /system/lib/libmedia.so (_ZN7android10AudioTrack13releaseBufferEPKNS0_6BufferE+112)
native: pc 000000000006c987 /system/lib/libmedia.so (_ZN7android10AudioTrack18processAudioBufferEv+1350)
native: pc 000000000006d7f3 /system/lib/libmedia.so (_ZN7android10AudioTrack16AudioTrackThread10threadLoopEv+194)
native: pc 0000000000010079 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+112)
native: pc 000000000004065b /system/lib/libc.so (_ZL15__pthread_startPv+30)
native: pc 000000000001a021 /system/lib/libc.so (__start_thread+6)
Run Code Online (Sandbox Code Playgroud)
这些OpenSL函数在JNI世界中被调用.
这些都是存储在堆中的变量:
/* OpenSL ES audio stuff */
SLObjectItf …Run Code Online (Sandbox Code Playgroud) 尝试使用OpenSL ES在运行Android 6.0.1的Nexus 6上实现低延迟流式音频播放时,我遇到了一个奇怪的问题.
我最初的尝试似乎遇到了饥饿问题,所以我在缓冲区完成回调函数中添加了一些基本的时序基准.我发现,如果我在应用程序打开时不断点击屏幕,音频播放效果很好,但如果我将其单独放置几秒钟,则回调开始需要更长时间.我能够一致地重现这种行为.有几点需要注意:
我看到的症状看起来真的像操作系统在与手机不交互几秒钟之后就取消了音频线程的优先级.这是正确的吗?有什么方法可以避免这种行为吗?
android ×10
opensl ×10
audio ×6
android-ndk ×3
alsa ×2
audiotrack ×2
audioflinger ×1
c++ ×1
nexus6 ×1