我有个MIDI键盘。我想要的只是一个例子,说明我如何设置默认的软件合成器来播放声音,就像我玩键盘一样。
package cleffsgame;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
public class CheckDevices {
public static void main(String[] args) {
MidiDevice device;
// display each device's properties
for (MidiDevice.Info info: MidiSystem.getMidiDeviceInfo()) {
try {
device = MidiSystem.getMidiDevice(info);
System.out.println("\nDevice: ");
System.out.println("Name: " + device.getDeviceInfo().getName());
System.out.println("Vendor: " + device.getDeviceInfo().getVendor());
System.out.println("Version: " + device.getDeviceInfo().getVersion());
System.out.println("Description: " + device.getDeviceInfo().getDescription());
System.out.println("Transmitters: " + device.getMaxTransmitters());
System.out.println("Receivers: " + device.getMaxReceivers());
} catch (MidiUnavailableException ex) {
Logger.getLogger(CheckDevices.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}通过运行上面的代码,我得到了以下输出:
跑: 设备名称: Gervill Vendor: OpenJDK版本: 1.0描述:软件MIDI合成器发射机:0接收器:-1 设备名称:氧气49供应商:m-音频版本:未知版本描述:氧气49发射机:-1接收器:0 设备名称:氧气49供应商:m-音频版本:未知版本描述:氧气49发射机:0接收器:-1 设备名称:实时Sequencer : Oracle公司版本: 1.0版本:软件顺序发射器:-1接收器:-1成功构建(总时间:2秒)
但是当我运行下面的代码时,当我按下键时,没有声音被播放。
package cleffsgame;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;
/**
*
* @author umberto
*/
public class Test {
public static void main(String[] args) {
MidiDevice inputDevice = null, synthDevice = null;
Transmitter transmitter = null;
Synthesizer synthesizer = null;
Receiver receiver = null;
try {
inputDevice = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[1]);
synthDevice = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[0]);
} catch (MidiUnavailableException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
// goodDevice must be Oxygen 49 transmitter (MIDI Input)
if (inputDevice != null && synthDevice != null) {
try {
transmitter = inputDevice.getTransmitter();
System.out.println("Transmitter: " + inputDevice.getDeviceInfo());
System.out.println(String.format("T/R: %s/%s", inputDevice.getMaxTransmitters(), inputDevice.getMaxReceivers()));
receiver = synthDevice.getReceiver();
System.out.println("Receiver: " + synthDevice.getDeviceInfo());
System.out.println(String.format("T/R: %s/%s", synthDevice.getMaxTransmitters(), synthDevice.getMaxReceivers()));
transmitter.setReceiver(receiver);
System.out.println("GoodDevice is open... check sound\n");
inputDevice.open();
synthDevice.open();
} catch (Exception ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}似乎有更多的工作要做,而不是像我从docs Synthesizer.receiver中获得的那样,将一个InputDevice.transmitter连接到一个https://docs.oracle.com/javase/tutorial/sound/MIDI-synth.html。
发布于 2020-07-31 20:39:02
这个对我有用
transmitter.setReceiver(new Receiver() {
@Override
public void send(MidiMessage message, long timeStamp) {
receiver.send(message, -1);
}
@Override
public void close() {
receiver.close();
}
});发布于 2016-06-01 06:36:15
在获得发射机/接收器之前打开设备可能是个好主意。
但实际的问题是,这个程序会立即退出,因此设备不会在有效的时间内打开。
发布于 2022-04-13 09:33:37
最近也想做同样的事。Java教程和堆栈溢出的答案不起作用。问题是,我把timestamp上的键盘注释传递给内部合成器。修复方法是将-1作为时间戳传递。
本例使用Kotlin调用。
JDK 17,MacOS 11.3,Kotlin 1.6
import javax.sound.midi.*
class ReceiverAdapter (val targetReceiver: Receiver) : Receiver {
override fun send(midiMsg: MidiMessage, timeStamp: Long) {
targetReceiver.send(midiMsg, -1); // only works for me when i pass -1 as timestamp instead of original value from keyboard
}
override fun close() { }
}
class MidiKeyboardInternalSynthExample {
companion object {
fun doIt(keyboardDeviceName: String){
// connect external keyboard to internal synth
val midiTransmitter = find1stMidiTransmitterWithName(keyboardDeviceName)
if(midiTransmitter != null) {
val synth = MidiSystem.getSynthesizer()!!
val midiReceiver = ReceiverAdapter(synth.receiver)
midiTransmitter.transmitter.receiver = midiReceiver
synth.open()
midiTransmitter.open()
}
else {
println("Didn't find MIDI transmitter named '$keyboardDeviceName'.")
}
}
fun find1stMidiTransmitterWithName(deviceName: String): MidiDevice? =
MidiSystem.getMidiDeviceInfo()
?.filter { info -> info.name == deviceName }
?.map { info -> MidiSystem.getMidiDevice(info) }
?.filter { device -> device.maxTransmitters == -1 }
?.first()
}
}
fun main(args: Array<String>) {
MidiKeyboardInternalSynthExample.doIt("LPK25")
}https://stackoverflow.com/questions/37558401
复制相似问题