midi api java_原生 MIDI API

本文介绍了如何使用Android NDK中的AMidi API在原生C/C++代码中发送和接收MIDI数据。首先,通过MidiManager在Java层发现和打开MidiDevice,然后通过JNI传递到原生层。在原生层,AMidi API允许直接与MIDI设备交互,无需频繁的JNI调用。应用通常需要单独的线程来轮询MIDI输入端口并处理异步接收的数据。此外,文章还涵盖了设置AMidi、接收和发送MIDI数据的详细步骤以及如何处理回调以更新界面。
摘要由CSDN通过智能技术生成

AMidi API 在 Android NDK r20b 及更高版本中可用。借助该 API,应用开发者可以使用 C/C++ 代码发送和接收 MIDI 数据。

Android MIDI 应用通常使用 midi API 与 Android MIDI 服务通信。MIDI 应用主要依赖于 MidiManager 发现、打开和关闭一个或多个 MidiDevice 对象,并通过设备的 MIDI 输入和输出端口与各个设备相互传递数据:

midi.svg

在使用 AMidi 时,您通过 JNI 调用将 MidiDevice 的地址传递给原生代码层。然后,AMidi 会创建一个对 AMidiDevice 的引用,后者具有 MidiDevice 的大部分功能。您的原生代码会使用直接与 AMidiDevice 通信的 AMidi 函数。AMidiDevice 直接连接到 MIDI 服务:

amidi.svg

您可以使用 AMidi 调用将应用的 C/C++ 音频/控制逻辑与 MIDI 传输紧密集成。这样就无需 JNI 调用或回调至应用的 Java 端。例如,采用 C 代码实现的数字合成器可以直接从 AMidiDevice 接收按键事件,而不是等待 JNI 调用从 Java 端向下发送事件。或者,算法作曲进程可以直接向 AMidiDevice 发送 MIDI 演奏,而无需向上回调至 Java 端来传输按键事件。

虽然 AMidi 改进了与 MIDI 设备的直接连接,但应用仍必须使用 MidiManager 来发现和打开 MidiDevice 对象。AMidi 可以负责处理后续事务。

有时候,您可能需要将信息从界面层向下传递到原生代码。例如,发送 MIDI 事件来响应屏幕上的按钮时。为此,请创建对原生逻辑的自定义 JNI 调用。如果需要发送回数据来更新界面,您可以像往常一样从原生层回调。

本文档介绍了如何设置 AMidi 原生代码应用,同时提供了发送和接收 MIDI 命令的示例。如需获取可正常工作的完整示例,请查看 NativeMidi 示例应用。

使用 AMidi

无论是要发送 MIDI、接收 MIDI,还是这两种操作都涉及,所有使用 AMidi 的应用都具有相同的设置和关闭步骤。

启动 AMidi

在 Java 端,应用必须发现所连接的 MIDI 硬件、创建对应的 MidiDevice 并将其传递到原生代码。

使用 Java MidiManager 类发现 MIDI 硬件。

获取与 MIDI 硬件对应的 Java MidiDevice 对象。

使用 JNI 将 Java MidiDevice 传递到原生代码。

发现硬件和端口

输入和输出端口对象不属于应用。它们代表 MIDI 设备上的端口。。为了将 MIDI 数据发送到设备,应用会打开 MIDIInputPort,然后在其中写入数据。反之,为了接收数据,应用会打开 MIDIOutputPort。为了正常工作,应用必须确保它打开的端口类型正确无误。设备和端口发现在 Java 端完成。

下面是发现各个 MIDI 设备并查找其端口的一种方法。它会返回具有输出端口的设备列表(从设备接收数据),或者具有输入端口的设备列表(向设备发送数据)。MIDI 设备可同时具有输入端口和输出端口。

Kotlin

private fun getMidiDevices(isOutput: Boolean) : List{

if (isOutput) {

return mMidiManager.devices.filter { it.outputPortCount > 0 }

} else {

return mMidiManager.devices.filter { it.inputPortCount > 0 }

}

}Java

private ListgetMidiDevices(boolean isOutput){

ArrayListfilteredMidiDevices = new ArrayList<>();

for (MidiDeviceInfo midiDevice : mMidiManager.getDevices()){

if (isOutput){

if (midiDevice.getOutputPortCount() > 0) filteredMidiDevices.add(midiDevice);

} else {

if (midiDevice.getInputPortCount() > 0) filteredMidiDevices.add(midiDevice);

}

}

return filteredMidiDevices;

}

如需在 C/C++ 代码中使用 AMidi 函数,您必须包含 AMidi/AMidi.h 并链接 amidi 库。这两项内容都可以在 Android NDK 中找到。

Java 端应通过 JNI 调用将一个或多个 MidiDevice 对象和端口号传递到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值