Android Open Source - QuMixDroid Qu16_ Midi_ Parser






From Project

Back to project page QuMixDroid.

License

The source code is released under:

GNU General Public License

If you think the Android project QuMixDroid listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Copyright (c) 2013 george wieggers.//from   ww w .j  a  va2  s .  c  om
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     george wieggers - initial API and implementation
 ******************************************************************************/
package org.wieggers.qu_apps.qu16;

import java.util.Arrays;

import org.wieggers.qu_apps.qu16.midi.Qu16_Id_Parameters;

class Qu16_Midi_Parser {
  
  //private static final String mTag = "Qu16_Midi_Parser";
  private IMidiListener mParent;

  private parse_state_enum mState = parse_state_enum.next_command;
  
  private byte[] current_command = new byte[4000];
  private int current_command_length = 0;

  /**
   * Construct a parser object, capable of processing individual commands for the Qu-16
   * @param commandDirection  2 Modes, because commands are different when sent to, or received from the Qu-16
   */
  public Qu16_Midi_Parser(IMidiListener parent) {
    mParent = parent;
  }
  
  /**
   * Analyzes a stream of bytes and extracts individual commands 
   * @param data     Network data buffer 
   * @param length  Network data buffer length
   */
  public void parse (Object origin, byte[] data)
  {
    for (int i = 0; i < data.length; ++i) {
      boolean command_complete = false;
      byte d = data [i];
      current_command [current_command_length] = d;
      switch (mState) {
      case next_command:
        switch (d) {
        case (byte) 0x90: // start mute
          mState = parse_state_enum.in_mute_command;
          break;
        case (byte) 0xB0: // start channel command
          mState = parse_state_enum.start_channel_command;
          break;
        case (byte) 0xF0:
          mState = parse_state_enum.in_sysex_command;
          break;
        case (byte) 0xFE:
          // just ignore "keep alive" commands
          continue;
        default:
          // also ignore everything we don't understand
          //Log.d(mTag, Qu16_Mixer.bytesToHex(new byte[] { d }));
          continue;
        }
        break;
      case start_channel_command:
        switch (d) {
        case (byte) 0x63: // 0xB0 - 0x63 detected, proceed to next state "in channel command"
          mState = parse_state_enum.in_channel_command;
          break;
        default:
          mState = parse_state_enum.next_command; // unknown sequence, ignore and wait for next command
          current_command_length = 0;
          continue;
        }
        break;
      case in_channel_command:
        command_complete = (current_command_length == 11);
        if (current_command_length > 6) {
          if (current_command[3] == (byte) 0xB0) {
            command_complete = (current_command_length == 11);
          } else {
            command_complete = (current_command_length == 8);
          }            
        }
        break;
      case in_mute_command:
        command_complete = (current_command_length == 4);
        break;
      case in_sysex_command:
        if (d == (byte) 0xF7)
          command_complete = true;
        break;
      }
      ++current_command_length;
      if (command_complete) {                
        byte[] command; 

        if (mState == parse_state_enum.in_channel_command && current_command_length == 8) { // Qu-pad sends too short NRPN commands          
          // so fix them by inserting proper 0xB0 values
          command = new byte[] {
              current_command[0],
              current_command[1],
              current_command[2],
              (byte) 0xB0,
              current_command[3],
              current_command[4],
              (byte) 0xB0,
              current_command[5],
              current_command[6],
              (byte) 0xB0,
              current_command[7],
              current_command[8]
          };
          
          // Qu-pad doesn't follow the specs for the output_mix command, correct it over here
          if (   current_command[4] >= Qu16_Id_Parameters.Chn_Output_Mix.getValue() 
            && current_command[4] <= Qu16_Id_Parameters.Chn_Output_Mix9_10.getValue()) {
            current_command[4] = Qu16_Id_Parameters.Chn_Output_Mix.getValue();
          }
        } else {
          command = Arrays.copyOfRange(current_command, 0, current_command_length);
        }
                  
        mParent.singleMidiCommand(this, origin, command);

        mState = parse_state_enum.next_command;
        current_command_length = 0;
      }
    }
  }
    
  private enum parse_state_enum
  {
    next_command,
    in_sysex_command,
    in_mute_command,
    start_channel_command,
    in_channel_command
  }
  
  public interface IMidiListener {
    void singleMidiCommand(Object sender, Object origin, byte[] midiCommand);
  }
}




Java Source Code List

org.wieggers.qu_apps.communication.Connected_Device.java
org.wieggers.qu_apps.controls.Fader.java
org.wieggers.qu_apps.controls.RotaryKnob.java
org.wieggers.qu_apps.controls.bound.BoundMixFader.java
org.wieggers.qu_apps.controls.bound.BoundMixRotaryKnob.java
org.wieggers.qu_apps.controls.bound.BoundMixSeekbar.java
org.wieggers.qu_apps.controls.bound.BoundMixToggleButton.java
org.wieggers.qu_apps.controls.bound.BoundMuteToggleButton.java
org.wieggers.qu_apps.qu16.Qu16_MeteringValues.java
org.wieggers.qu_apps.qu16.Qu16_Midi_Parser.java
org.wieggers.qu_apps.qu16.Qu16_MixValue.java
org.wieggers.qu_apps.qu16.Qu16_Mixer.java
org.wieggers.qu_apps.qu16.Qu16_UI.java
org.wieggers.qu_apps.qu16.midi.Qu16_GEQ_Bands.java
org.wieggers.qu_apps.qu16.midi.Qu16_Id_Parameters.java
org.wieggers.qu_apps.qu16.midi.Qu16_Input_Channels.java
org.wieggers.qu_apps.qu16.midi.Qu16_VA_Ranges.java
org.wieggers.qu_apps.qu16.midi.Qu16_VX_Buses.java
org.wieggers.qu_apps.qumixdroid.ConnectingFragment.java
org.wieggers.qu_apps.qumixdroid.LoginActivity.java
org.wieggers.qu_apps.qumixdroid.MainActivity.java
org.wieggers.qu_apps.qumixdroid.MixerFragment.java