【发布时间】:2020-06-10 03:40:46
【问题描述】:
由于延迟低,我正在尝试将 Google Oboe 用于 3D 音频处理应用。该应用程序将有一个 C++ 后端,它负责处理,前端由 Flutter 完成。我正在运行几个测试,看看它是否会工作,但我在将资产从 Flutter 加载到双簧管时遇到问题。我检查了双簧管repo 中的示例 RhythmGame,使用 Java 完成,但无法安静地找到直接从 Dart 到 C++ 的方法。 前后端的连接是通过dart::ffi
这是我迄今为止尝试过的。根据 Richard Heap here 发布的示例,我将 noise 变量从正弦波更改为 wav 文件中歌曲的一小段:
class _MyAppState extends State<MyApp> {
final stream = OboeStream();
var noise = Float32List(512);
Timer t;
@override
void initState() {
super.initState();
// for (var i = 0; i < noise.length; i++) {
// noise[i] = sin(8 * pi * i / noise.length);
// }
_loadSound();
}
void _loadSound() async {
final ByteData data = await rootBundle.load('assets/song_cut.wav');
noise = data.buffer.asFloat32List();
}
(...)
那么 Dart 中的这个函数调用原生库的 Dart 包装器:
void start() {
stream.start();
var interval = (512000 / stream.getSampleRate()).floor() + 1;
t = Timer.periodic(Duration(milliseconds: interval), (_) {
stream.write(noise);
});
}
Dart 中的包装是:
void write(Float32List original) {
var length = original.length;
var copy = allocate<Float>(count: length)
..asTypedList(length).setAll(0, original);
FfiGoogleOboe()._streamWrite(_nativeInstance, copy, length);
free(copy);
}
_streamWrite 是 C++ 中的原生函数:
EXTERNC void stream_write(void* ptr, void* data, int32_t size) {
auto stream = static_cast<OboeFfiStream*>(ptr);
auto dataToWrite = static_cast<float*>(data);
stream->write(dataToWrite, size);
}
void OboeFfiStream::write(float *data, int32_t size) {
managedStream->write(data, size, 1000000);
}
现在我可以听到这首歌,但它的失真太大了。尝试使用正弦时,我也能听到它,但它也有一些失真。我还没有在双簧管中使用回调模式,因为我想先尝试一下。
【问题讨论】:
-
youtu.be/X8JD8hHkBMc 特别是从 23:00 开始
-
Richard,我几天前看过你的视频(顺便说一句,谢谢你,这是我能找到的唯一一个使用 ffi 的好例子,干得好),但是我'我现在想做的是用我从 pubspec.yaml 中的资产加载的 mp3 文件替换正弦声音
-
您可以通过添加更多细节来改进您的问题。您正在尝试做什么,如何,您尝试了什么,什么不起作用。显示您的代码。
标签: c++ flutter dart oboe dart-ffi