Unity3d 中集成的 android MIDI 驱动程序没有声音
No sound out of an android MIDI driver integrated in Unity3d
我想在 android 上使用 Unity3d 输出 MIDI 音频。使用开源库我想我可以正常工作,但设备没有发出声音,也没有任何类型的错误 messages/logs。
我正在使用这个库:
https://github.com/billthefarmer/mididriver
我已经使用 Android Studio 使用提供的 gradle 项目测试了库,它运行良好。
Unity 通过将其放入 Assets\Plugins\Android 来识别此库的 AAR 文件。然后我添加了一个 java class 来包装方法调用,
并创建了一个小的 C# MonoBehaviour 脚本来测试它。我隔离了代码以便您可以重现问题。
重现:
- 使用 Unity3d 创建一个新的 3d 项目。
- 添加一个空的游戏对象。
- 将下面的 C# 脚本附加到它。
- 在 Assets 文件夹中创建文件夹 Plugins\Android。
- 在 Android 文件夹中创建一个包含以下 java 代码的新文件。
- 添加链接库最新版本的AAR文件。
- 构建并将其加载到 android 设备。
C# 单行为
每 2 秒发送一条 NOTE_ON 消息,然后在一秒后发送一条 NOTE_OFF 消息。 AndroidJavaClass 用于调用库的方法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MidiDriverDemo : MonoBehaviour
{
private const string CLASS_PATH = "com.example.driver.AndroidMidiDriver";
public static readonly float CYCLE_TIME_SEC = 1f;
private float remainingTime;
private Dictionary<int, int[]> messages;
private int currentMessage;
AndroidJavaClass midiDriver;
// Start is called before the first frame update
void Start()
{
remainingTime = CYCLE_TIME_SEC;
currentMessage = 0;
messages = new Dictionary<int, int[]>() {
{ 0, new int[] { 0x90, 48, 63 } },
{ 1, new int[] { 0x80, 48, 0 } }
};
midiDriver = new AndroidJavaClass(CLASS_PATH);
midiDriver.Call("start");
}
// Update is called once per frame
void Update()
{
remainingTime -= Time.deltaTime;
if(remainingTime <= 0) {
remainingTime = CYCLE_TIME_SEC;
midiDriver.Call("send", messages[currentMessage][0],
messages[currentMessage][1], messages[currentMessage][2]);
currentMessage++;
currentMessage %= messages.Count;
}
}
}
java 包装
package com.example.driver;
import org.billthefarmer.mididriver.MidiDriver;
public class AndroidMidiDriver {
private MidiDriver midi;
public AndroidMidiDriver(){
midi = new MidiDriver();
}
public void start(){
if (midi != null) {
midi.start();
}
}
public void stop() {
if (midi != null) {
midi.stop();
}
}
public void send(int command, int noteNumber, int velocity){
byte[] msg = new byte[3];
msg[0] = (byte) command;
msg[1] = (byte) noteNumber;
msg[2] = (byte) velocity;
midi.write(msg);
}
}
因此它可以完美编译,没有任何警告,并且在设备上 运行 但仍然没有声音。音量设置正确。
在我隔离问题之前,对 "send" 方法的调用使我的应用程序因分段错误而崩溃,所以我猜有些东西正在工作。
所以我认为问题是以下之一:
- 这不是访问 AAR 的正确方法。
- 我错过了 Unity 中的一些设置。
- 问题出在库本身,不太可能,因为它与提供的 gradle 项目独立工作。
欢迎任何ides/suggestions。
从 .aar 中提取 jni/armv7a 文件夹中的 libmidi.so 后,删除 java 包装器并将代码更改为以下内容:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class MidiDriverDemo : MonoBehaviour
{
public static readonly float CYCLE_TIME_SEC = 1f;
private float remainingTime;
private Dictionary<int, byte[]> messages;
private int currentMessage;
[DllImport("midi")]
private static extern float midi_init();
[DllImport("midi")]
private static extern float midi_shutdown();
[DllImport("midi")]
private static extern float midi_write(byte[] msg, int length);
// Start is called before the first frame update
void Start()
{
remainingTime = CYCLE_TIME_SEC;
currentMessage = 0;
messages = new Dictionary<int, byte[]>() {
{ 0, new byte[] { 0x90, 48, 100 } },
{ 1, new byte[] { 0x80, 48, 0 } }
};
midi_init();
}
// Update is called once per frame
void Update()
{
remainingTime -= Time.deltaTime;
if(remainingTime <= 0) {
remainingTime = CYCLE_TIME_SEC;
midi_write(messages[currentMessage], 3);
currentMessage++;
currentMessage %= messages.Count;
}
}
}
设备终于有音频输出了。
我想在 android 上使用 Unity3d 输出 MIDI 音频。使用开源库我想我可以正常工作,但设备没有发出声音,也没有任何类型的错误 messages/logs。
我正在使用这个库: https://github.com/billthefarmer/mididriver
我已经使用 Android Studio 使用提供的 gradle 项目测试了库,它运行良好。
Unity 通过将其放入 Assets\Plugins\Android 来识别此库的 AAR 文件。然后我添加了一个 java class 来包装方法调用, 并创建了一个小的 C# MonoBehaviour 脚本来测试它。我隔离了代码以便您可以重现问题。
重现:
- 使用 Unity3d 创建一个新的 3d 项目。
- 添加一个空的游戏对象。
- 将下面的 C# 脚本附加到它。
- 在 Assets 文件夹中创建文件夹 Plugins\Android。
- 在 Android 文件夹中创建一个包含以下 java 代码的新文件。
- 添加链接库最新版本的AAR文件。
- 构建并将其加载到 android 设备。
C# 单行为
每 2 秒发送一条 NOTE_ON 消息,然后在一秒后发送一条 NOTE_OFF 消息。 AndroidJavaClass 用于调用库的方法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MidiDriverDemo : MonoBehaviour
{
private const string CLASS_PATH = "com.example.driver.AndroidMidiDriver";
public static readonly float CYCLE_TIME_SEC = 1f;
private float remainingTime;
private Dictionary<int, int[]> messages;
private int currentMessage;
AndroidJavaClass midiDriver;
// Start is called before the first frame update
void Start()
{
remainingTime = CYCLE_TIME_SEC;
currentMessage = 0;
messages = new Dictionary<int, int[]>() {
{ 0, new int[] { 0x90, 48, 63 } },
{ 1, new int[] { 0x80, 48, 0 } }
};
midiDriver = new AndroidJavaClass(CLASS_PATH);
midiDriver.Call("start");
}
// Update is called once per frame
void Update()
{
remainingTime -= Time.deltaTime;
if(remainingTime <= 0) {
remainingTime = CYCLE_TIME_SEC;
midiDriver.Call("send", messages[currentMessage][0],
messages[currentMessage][1], messages[currentMessage][2]);
currentMessage++;
currentMessage %= messages.Count;
}
}
}
java 包装
package com.example.driver;
import org.billthefarmer.mididriver.MidiDriver;
public class AndroidMidiDriver {
private MidiDriver midi;
public AndroidMidiDriver(){
midi = new MidiDriver();
}
public void start(){
if (midi != null) {
midi.start();
}
}
public void stop() {
if (midi != null) {
midi.stop();
}
}
public void send(int command, int noteNumber, int velocity){
byte[] msg = new byte[3];
msg[0] = (byte) command;
msg[1] = (byte) noteNumber;
msg[2] = (byte) velocity;
midi.write(msg);
}
}
因此它可以完美编译,没有任何警告,并且在设备上 运行 但仍然没有声音。音量设置正确。
在我隔离问题之前,对 "send" 方法的调用使我的应用程序因分段错误而崩溃,所以我猜有些东西正在工作。
所以我认为问题是以下之一:
- 这不是访问 AAR 的正确方法。
- 我错过了 Unity 中的一些设置。
- 问题出在库本身,不太可能,因为它与提供的 gradle 项目独立工作。
欢迎任何ides/suggestions。
从 .aar 中提取 jni/armv7a 文件夹中的 libmidi.so 后,删除 java 包装器并将代码更改为以下内容:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class MidiDriverDemo : MonoBehaviour
{
public static readonly float CYCLE_TIME_SEC = 1f;
private float remainingTime;
private Dictionary<int, byte[]> messages;
private int currentMessage;
[DllImport("midi")]
private static extern float midi_init();
[DllImport("midi")]
private static extern float midi_shutdown();
[DllImport("midi")]
private static extern float midi_write(byte[] msg, int length);
// Start is called before the first frame update
void Start()
{
remainingTime = CYCLE_TIME_SEC;
currentMessage = 0;
messages = new Dictionary<int, byte[]>() {
{ 0, new byte[] { 0x90, 48, 100 } },
{ 1, new byte[] { 0x80, 48, 0 } }
};
midi_init();
}
// Update is called once per frame
void Update()
{
remainingTime -= Time.deltaTime;
if(remainingTime <= 0) {
remainingTime = CYCLE_TIME_SEC;
midi_write(messages[currentMessage], 3);
currentMessage++;
currentMessage %= messages.Count;
}
}
}
设备终于有音频输出了。