我正在尝试在 Android 中加载和使用 java 的虚拟(软)合成器。我读过Gervill jar 就是用来做这个的。其他构建块是javax-sound作为 aar 文件存在于我的项目中(因为它不存在于 Android 的修剪 Java 包中)
Gradle 文件包含
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 29
buildToolsVersion "29.0.0"
dataBinding {
enabled = true
}
defaultConfig {
applicationId "com.mmm.ttt"
minSdkVersion 18
targetSdkVersion 29
multiDexEnabled true
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(path: ':javax-sound')
implementation project(path: ':gervilljar') // This is folder name at project root folder level containing gervill.jar
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:multidex:1.0.3'
}
代码的问题区域
代码 1
MidiSystem.getMidiDeviceInfo().size //results in an empty array in all cases
一些答案表明仅包含 gervill jar 就足以进行自动检测。但是因为这对我不起作用,所以我写了这个
代码 2
var synth = SoftSynthesizer() as Synthesizer
MidiSystem.addSynthesizer(synth)
我得到这个编译错误
Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class com.sun.media.sound.SoftSynthesizer, unresolved supertypes: com.sun.media.sound.ReferenceCountingDevice
class com.sun.media.sound.AudioSynthesizer, unresolved supertypes: javax.sound.midi.Synthesizer
代码 3
var synth = MidiSystem.getSynthesizer()
synth?.open()
如上所述包含到 gradle 中,这是没有代码 2 的运行时错误
Caused by: jp.kshoji.javax.sound.midi.MidiUnavailableException: Synthesizer not found
at jp.kshoji.javax.sound.midi.MidiSystem.getSynthesizer(MidiSystem.java:323)
我按照https://stackoverflow.com/a/38749847/1029110添加 aar/jar 文件
但是,虽然 gervill 需要 javax.sound
最终目标是加载和播放 soundfont 文件。尽可能避免使用本机 jni 代码。
编辑
发现 1 个问题。Gervill.jar 不够好,无法正常工作。所以我从 com.sun.media.sound.* 中挑选了一些其他类并编译到新的 jar 中。现在代码 2 ( unresolved supertypes
) 中的错误已经消失。
下一个试验是包括 Android midi 服务
val midiManager = context.getSystemService(Context.MIDI_SERVICE) as android.media.midi.MidiManager
midiManager.getDevices()
这提供了 2 项服务,具体取决于安装在移动设备上的外部应用程序。但无论如何,它们与软合成器无关。
因此,代码 1 仍然有 MidiDeviceInfo 的空数组。
代码 3 的一部分:synth?.open()
仍然严重失败,但出现了新的错误。
(目前卡在这里)
Caused by: jp.kshoji.javax.sound.midi.MidiUnavailableException: Can not open line
at com.sun.media.sound.SoftSynthesizer.open(SoftSynthesizer.java:1132)
at com.sun.media.sound.SoftSynthesizer.open(SoftSynthesizer.java:1036)
Caused by: java.lang.IllegalArgumentException: No line matching interface jp.kshoji.SourceDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian is supported.
at jp.kshoji.javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:475)
at jp.kshoji.javax.sound.sampled.AudioSystem.getSourceDataLine(AudioSystem.java:602)
at com.sun.media.sound.SoftSynthesizer.open(SoftSynthesizer.java:1066)
at com.sun.media.sound.SoftSynthesizer.open(SoftSynthesizer.java:1036)
代码 4:
jp.kshoji.javax.sound.midi.MidiSystem.getSoundbank(File("soundfont.sf2"))
失败
Caused by: java.lang.UnsupportedOperationException: not implemented.
at jp.kshoji.javax.sound.midi.MidiSystem.getSoundbank(MidiSystem.java:277)
我已经检查了 Java for windows 版本的源代码。没有使用 getSoundbank 的文件覆盖或实现。
修复和未来的步骤?