安卓Superpowered SDK同时录制和播放

5
我的目标是在录制设备的麦克风输入时播放本地文件,并实现低延迟。我找到了Superpowered库,因为文档中提供了低延迟特性。我使用SuperpoweredAdvancedAudioPlayer和SuperpoweredAndroidAudioIO创建了播放器,它能够正常播放。
SuperpoweredAndroidAudioIO有一个构造函数,带有参数boolean enableInput, boolean enableOutput。当前我使用的是enableInput == false,enableOutput == true。当我将这些参数设置为true时,没有任何效果。
我想知道是否可能同时录制文件和播放其他文件?
此外,库中还有SuperpoweredRecorder类,但它不适用于直接写入磁盘。需要使用createWAV、fwrite、closeWAV方法。我尝试单独实现Recorder,但质量不好(比真实录音快两三倍 + 声音失真)。以下是我使用的记录最简单的代码片段:
void SuperpoweredFileRecorder::start(const char *destinationPath) {
    file = createWAV(destinationPath, sampleRate, 2);
    audioIO = new SuperpoweredAndroidAudioIO(sampleRate, bufferSize, true, false, audioProcessing, NULL, bufferSize); // Start audio input/output.
}

void SuperpoweredFileRecorder::stop() {
    closeWAV(file);
    audioIO->stop();
}

static bool audioProcessing(void *clientdata, short int *audioInputOutput, int numberOfSamples, int samplerate) {
    fwrite(audioInputOutput, sizeof(short int), numberOfSamples, file);
    return false;
}

也许我不能使用Superpowered来实现这个目的,需要直接使用OpenSL ES进行录音。

提前致谢!

3个回答

6
经过实验,我找到了解决方案。
  1. SuperpoweredRecorder适用于录制音轨;
  2. 我创建了两个独立的SuperpoweredAndroidAudioIO源 - 一个用于播放,另一个用于录音。经过一些同步操作,它可以很好地工作(我将延迟最小化到非常低的水平,所以它满足我的需求)。

我发布了一些代码片段,展示了我实现的思路:

https://bitbucket.org/snippets/kasurd/Mynnp/nativesuperpoweredrecorder-with

希望能对某些人有所帮助!


1
@kasurd,请问你可以分享一下带有正确实现的 GitHub 链接吗?那会非常有帮助。 - Deepak Gupta
@kasurd,你能否请在我的请求上留下一些评论? - Deepak Gupta
@DeepakGupta 抱歉,我没有公共代码库。如果你有问题,我可以帮忙解答。 - kasurd
@kasurd 实际上我无法制作 nativesuperpoweredrecorder.h 文件.. 这就是你的帮助所需的基本内容。 - Deepak Gupta
@kasurd 我正在等待你的回复。 - Deepak Gupta
显示剩余5条评论

5
您可以使用一个启用了输入和输出的 SuperpoweredAndroidAudioIO 实例来完成此操作。
在您的情况下,音频处理回调(audioProcessing())会在 audioInputOutput 参数中接收音频(麦克风)。只需将其传递给 SuperpoweredRecorder,它就会将其写入磁盘。
之后,进行 SuperpoweredAdvancedAudioPlayer 处理,并将结果转换为 audioInputOutput。这将进入音频输出。
因此,伪代码如下:
audioProcessing(audioInputOutput) {
   recorder->process(audioInputOutput)
   player->process(some_buffer)
   float_to_short_int(some_buffer, audioInputOutput)
}

在音频处理回调函数中千万不要执行任何 fwrite 操作,因为它必须在非常短的时间内完成,而磁盘操作可能太慢。


谢谢Gabor的评论。 我一开始采用了这种方法,但后来发现我需要同时使用两三个播放器和一个录音机。因此,我决定切换到单独的SuperpoweredAndroidAudioIO。 您的方法对我的情况也适用吗? - kasurd
当然可以。多个玩家可以进入同一个缓冲区。process() 方法有 bufferAdd 参数,只需将其设置为 true,并为所有玩家使用相同的缓冲区即可。 - Gabor Szanto
请问您能否解释一下如何在文件中应用音频效果后编写输出? - arslan haktic
嗨Gabor,你能否简要解释一下如何区分来自输入和输出的回调函数在音频处理中的作用?我的问题是,一旦我将bufferAdd设置为true,播放器的输出就变成了无意义的乱码。如果我将其设置为false,则可以正常听到文件的播放。 - ItWillDo
1
使用Superpowered时,只有一个回调函数,不分为输入和输出。回调的缓冲区将包含音频输入,并且必须被覆盖为输出。 bufferAdd表示“将播放器的输出添加到此缓冲区的内容中,不要覆盖”。 如果这是无意义的话,则缓冲区可能具有无意义的内容或播放器未触及缓冲区(在process()返回false)。 - Gabor Szanto
嗨Gabor,感谢您的评论,我现在已经把它搞定了。我想我只是从不同的角度看待它,但现在它更有意义了! - ItWillDo

0

对我来说,当我将numberOfSamples加倍时,这个程序可以正常工作

fwrite(audioInputOutput, sizeof(short int), numberOfSamples * 2, file);

这将导致清晰的立体声输出


你能否解释一下在应用音频效果后如何将输出写入文件? - arslan haktic
需要帮助解决这个问题:https://dev59.com/gp_ha4cB1Zd3GeqPwEZa - arslan haktic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接