【问题标题】:Distinguish between key press and release of MIDI piano input区分 MIDI 钢琴输入的按键和释放
【发布时间】:2016-06-20 16:15:25
【问题描述】:

我即将为一个学校项目编写一个小程序,该程序应该识别通过 MIDI 钢琴输入演奏的和弦(这只是其中的一部分)。

目前为止,在 MIDI 键盘上每次按下和释放一个键,我都会得到一个 ShortMessage 类的对象。

我的问题:如何确定按键是被按下还是释放? 在每种情况下,按下并释放,静态变量 NOTE_OFF 包含值 128,变量 NOTE_ON 包含值 144。

我不明白这应该如何告诉我该键是否已被按下或释放。任何想法?我错过了一个基本的东西吗?

提前致谢。

【问题讨论】:

  • “在每种情况下(按下并释放)静态变量 NOTE_OFF 确实包含值 128” 什么静态变量?
  • 只是FWIW,很久以前的非常(我上一次处理MIDI是> 20年前),一些乐器从未发送过“注意关闭”事件。他们以 0 的速度发送“Note On”事件。非常混乱。
  • 状态字段(通过继承自MidiMessagegetStatus()方法可访问)不是可能包含NOTE_ON/NOTE_OFF的字段吗?我很确定它是,但无法测试。

标签: java release midi piano


【解决方案1】:

NOTE_ONNOTE_OFF 只是常量;您将消息的实际命令值 (getCommand()) 与它们进行比较。

请注意,速度 (getData2()) 为零的音符打开消息必须被解释为音符关闭消息。

【讨论】:

    【解决方案2】:

    您可能希望将JFugue 库用于您的应用程序。

    // You'll need some try/catches around this block. This is traditional Java Midi code.
    MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
    MidiDevice device = MidiSystem.getMidiDevice(infos[0]); // You'll have to get the right device for your MIDI controller. 
    
    // Here comes the JFugue code
    MusicTransmitterToParserListener m = new MusicTransmitterToParserListener(device);
    m.addParserListener(new ChordParserListener());
    
    // Choose either this option:
    m.startListening();
    ...do stuff...
    m.stopListening();
    
    // Or choose this option:
    m.listenForMillis(5000); // Listen for 5000 milliseconds (5 seconds)
    
    
    public ChordParserListener extends ParserListenerAdapter {
        List<Note> notes = new ArrayList<Note>;
    
        @Override public void onNotePressed(Note note) {
            notes.add(note);
            // Go through your list and see if you have a chord
        }
        @Override public void onNoteReleased(Note note) {
            // Remove the note from the list, might not be as easy as notes.remove(note)
        }
    }
    

    JFugue 还有一个Chord 类,你可能会觉得它很有用——尤其是返回一个给定音符数组的 Chord 的方法......它被称为Chord.fromNotes(Note[] notes)——除非它消除了你所面临的挑战希望解决。

    【讨论】:

      【解决方案3】:

      我有同样的“问题”并尝试了亚伦评论中的建议:

      不是状态字段吗(可以通过getStatus()方法访问 继承自 MidiMessage) 可能包含 NOTE_ON / 注意关闭?我很确定它是,但无法测试它。

      它工作得很好!谢谢海报和亚伦!。

      if( sm.getStatus() == sm.NOTE_ON )
      {
         piano-key-down.
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-01
        • 2016-02-20
        • 1970-01-01
        • 1970-01-01
        • 2020-07-31
        • 1970-01-01
        • 2017-09-06
        • 2019-10-11
        • 1970-01-01
        相关资源
        最近更新 更多