Java 覆盆子pi上的Midi输入
我已经实现了一个简单的程序,它从Midi键盘获取输入,然后使用javax合成器接口输出相应的声音。 这在我运行Windows的Pc上运行得非常好,但是,我想在运行Raspbian的Raspberry Pi上运行它。它实际上也能工作,但当我弹奏更多/更快的音符时,声音开始抖动和噼啪作响,非常糟糕,我必须停止弹奏音符大约2秒钟,以便使抖动消失。 我已经在使用一个外置USB声音适配器了,这并没有多大帮助。 下面是处理midi输入的类:Java 覆盆子pi上的Midi输入,java,raspberry-pi,midi,Java,Raspberry Pi,Midi,我已经实现了一个简单的程序,它从Midi键盘获取输入,然后使用javax合成器接口输出相应的声音。 这在我运行Windows的Pc上运行得非常好,但是,我想在运行Raspbian的Raspberry Pi上运行它。它实际上也能工作,但当我弹奏更多/更快的音符时,声音开始抖动和噼啪作响,非常糟糕,我必须停止弹奏音符大约2秒钟,以便使抖动消失。 我已经在使用一个外置USB声音适配器了,这并没有多大帮助。 下面是处理midi输入的类: public class MidiHandler { p
public class MidiHandler {
public MidiHandler() {
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for (int i = 0; i < infos.length; i++) {
try {
device = MidiSystem.getMidiDevice(infos[i]);
// does the device have any transmitters?
// if it does, add it to the device list
System.out.println(infos[i]);
// get all transmitters
List<Transmitter> transmitters = device.getTransmitters();
// and for each transmitter
for (int j = 0; j < transmitters.size(); j++) {
// create a new receiver
transmitters.get(j).setReceiver(
// using my own MidiInputReceiver
new MidiInputReceiver(device.getDeviceInfo()
.toString()));
}
Transmitter trans = device.getTransmitter();
trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo()
.toString()));
// open each device
device.open();
// if code gets this far without throwing an exception
// print a success message
} catch (MidiUnavailableException e) {
}
}
}
// tried to write my own class. I thought the send method handles an
// MidiEvents sent to it
public class MidiInputReceiver implements Receiver {
Synthesizer synth;
MidiChannel[] mc;
Instrument[] instr;
int instrument;
int channel;
public MidiInputReceiver(String name) {
try
{
patcher p = new patcher();
this.instrument = p.getInstrument();
this.channel = p.getChannel();
this.synth = MidiSystem.getSynthesizer();
this.synth.open();
this.mc = synth.getChannels();
instr = synth.getDefaultSoundbank().getInstruments();
this.synth.loadInstrument(instr[1]);
mc[this.channel].programChange(0, this.instrument);
System.out.println(this.channel + ", " + this.instrument);
}
catch (MidiUnavailableException e)
{
e.printStackTrace();
System.exit(1);
}
}
public void send(MidiMessage msg, long timeStamp) {
/*
* Use to display midi message
*
for(int i = 0; i < msg.getMessage().length; i++) {
System.out.print("[" + msg.getMessage()[i] + "] ");
}
System.out.println();
*/
if (msg.getMessage()[0] == -112) {
mc[this.channel].noteOn(msg.getMessage()[1], msg.getMessage()[2]+1000);
}
if (msg.getMessage()[0] == -128) {
mc[this.channel].noteOff(msg.getMessage()[1], msg.getMessage()[2]+1000);
}
}
public void close() {
}
}
}
公共类MIDI处理程序{
公共middhandler(){
MIDI设备;
MidiDevice.Info[]infos=MidiSystem.getMidiDeviceInfo();
for(int i=0;i
这是由于Pi的硬件限制,还是我可以做些什么?如果您有任何更新midi检索/声音输出的循环,也许可以尝试在那里休眠线程,让操作系统有时间做一些事情?除此之外,我不确定。由于某些原因,原始Raspberry Pi上的USB不是很好(有很多bug,性能很慢——但这些在较新的Linux/固件中得到了一定程度的修复)。如果可以访问,您可能还需要修改采样率以匹配当前声音输出的理想设置(采样率不匹配意味着更多转换)。Java可能会尝试使用理想值作为默认值,但可能会被操作系统误报?CPU利用率是多少?@CL程序运行时,CPU利用率在30%到50%之间。当我弹奏一个音符时,它会上升到60%到70%。每当cpu使用率达到~90%以上时,就会出现声音故障