【问题标题】:Midi input on raspberry pi树莓派上的MIDI输入
【发布时间】:2015-04-18 10:13:50
【问题描述】:

我已经实现了一个简单的程序,它从 Midi 键盘获取输入,然后使用 javax 合成器接口输出相应的声音。 这在我运行 Windows 的 PC 上运行良好,但是,我想在运行 Raspbian 的 Raspberry Pi 上运行它。它实际上也确实有效,但是一旦我弹奏更多/更快的音符,声音就会开始抖动和噼啪作响,非常糟糕,我必须停止播放音符约 2 秒钟才能让抖动消失。 我已经在使用外部 USB 声音适配器,但这并没有太大帮助。 这是处理 MIDI 输入的类:

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() {
        }
    }
}

这是由于 Pi 的硬件限制,还是我可以做些什么?

【问题讨论】:

  • CPU 利用率是多少?
  • @CL 在程序运行时,cpu 使用率在 30% 到 50% 之间。当我弹奏一个音符时,它会上升到 60% 到 70% 之间。每当 cpu 使用率超过 ~90% 时,就会出现声音故障

标签: java raspberry-pi midi


【解决方案1】:

如果您有任何用于更新 midi 检索/声音输出的循环,也许可以尝试在其中进行线程睡眠以让操作系统有时间做事?除此之外,不确定。由于某种原因,原始 Raspberry Pi 上的 USB 不是很好(有很多错误,性能缓慢——但这些确实在较新的 Linux/固件中得到了一些修复)。如果可以访问,您可能还需要修改采样率以匹配当前声音输出的理想设置(采样率不匹配意味着更多转换)。 Java 可能会尝试使用理想作为默认值,但可能会被操作系统误报?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-05
    • 2020-03-14
    • 2012-12-04
    • 2014-01-18
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多