Package jrackattack.midi

Source Code of jrackattack.midi.MidiReader$KeyBoardReceiver

/* For License see bottom */
/*
* MidiReader.java
*
* Created on 1. Juli 2007, 20:26
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package jrackattack.midi;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;

import jonkoshare.util.VersionInformation;
import jrackattack.JRackAttack;
import jrackattack.gui.JRackAttackFrame;

import org.apache.log4j.Logger;

/**
* One half of the MIDI-messaging and the reading one. This thread runs to get
* filled with all the fine parameter changes one causes. This thread is not
* directly responsible for keyboard events, have a look at
* {@link jrackattack.midi.MidiReader.KeyboardReceiver KeyboardReceiver} for
* this.
* <p>
* TODO: Re-implement as
* {@link java.util.concurrent.ScheduledThreadPoolExecutor}.
*
* @author methke01
*/
@VersionInformation(lastChanged = "$LastChangedDate: 2009-07-25 04:59:33 -0500 (Sat, 25 Jul 2009) $", authors = { "Alexander Methke" }, revision = "$LastChangedRevision: 11 $", lastEditor = "$LastChangedBy: onkobu $", id = "$Id")
public class MidiReader extends Thread implements Receiver {
  private static final Logger log = Logger.getLogger(MidiReader.class);

  /** Creates a new instance of MidiReader */
  public MidiReader() {
  }

  // Thread
  @Override
  public void run() {
    runFlag = true;
    while (runFlag) {
      try {
        sleep(200);
      } catch (InterruptedException e) {
      }
    }
  }

  // Receiver
  public void close() {
    // do nothing?
  }

  public void send(MidiMessage message, long timeStamp) {
    if (JRackAttack.spoolMidi()) {
      debug("receiving " + MidiReader.formatMidiMessage(message));
      debug(message.getLength() + " bytes)");
    }
    // Clock and active sensing won't be treated
    // in any way
    if (message.getStatus() == ShortMessage.ACTIVE_SENSING
        || message.getStatus() == ShortMessage.TIMING_CLOCK) {
      return;
    }
    if (!isWaldorfSysex(message)) {
      JRackAttackFrame.getInstance().handleError(
          "message.sysex_not_waldorf", "EOX");
      return;
    }
    soundBytes = message.getMessage();
    switch (soundBytes[4]) {
    case RackAttack.SOUND_DUMP: {
      fill(new SoundParameter());
    }
      break;
    case RackAttack.FX_DUMP: {
      fill(new FXParameter());
    }
      break;
    case RackAttack.GLOBAL_DUMP: {
      fill(new GlobalParameter());
    }
      break;
    case RackAttack.PATTERN_DUMP: {
      fill(new PatternParameter());
    }
      break;
    case RackAttack.PROGRAM_DUMP: {
      fill(new ProgramParameter());
    }
      break;
    case RackAttack.SOUND_CHANGE: {
      fill(new ParameterChange(ParameterChange.Type.SND));
    }
      break;
    case RackAttack.FX_CHANGE: {
      fill(new ParameterChange(ParameterChange.Type.FX));
    }
      break;
    case RackAttack.GLOBAL_CHANGE: {
      fill(new ParameterChange(ParameterChange.Type.GLB));
    }
      break;
    case RackAttack.PATTERN_CHANGE: {
      fill(new ParameterChange(ParameterChange.Type.PAT));
    }
      break;
    case RackAttack.PROGRAM_CHANGE: {
      fill(new ParameterChange(ParameterChange.Type.PRG));
    }
      break;
    default: {
      log("Sysex-Message unknown: " + formatMidiMessage(message));
    }
    }
  }

  public boolean isRunning() {
    return runFlag;
  }

  public void setRunning(boolean state) {
    runFlag = state;
  }

  public void done() {
    runFlag = false;
  }

  public void fill(SoundParameter param) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    param.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setSoundParameter(param);
    MidiThread.getInstance().receivedData();
  }

  public void fill(PatternParameter param) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    param.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setPatternParameter(param);
    MidiThread.getInstance().receivedData();
  }

  public void fill(ProgramParameter param) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    // when loading a program from edit buffer it has no
    // program number, so we need to redefine this
    //
    if (soundBytes[5] == RackAttack.EDIT_BUFFER
        && getNextProgramNumber() != -1) {
      soundBytes[6] = (byte) (getNextProgramNumber() & 0x7f);
      setNextProgramNumber(-1);
    }
    param.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setProgramParameter(param);
    MidiThread.getInstance().receivedData();
  }

  public void fill(GlobalParameter param) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    param.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setGlobalParameter(param);
    MidiThread.getInstance().receivedData();
  }

  public void fill(FXParameter param) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    param.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setFxParameter(param);
    MidiThread.getInstance().receivedData();
  }

  public void fill(ParameterChange pc) {
    if (soundBytes == null) {
      throw new IllegalStateException("cannot fill without recorded data");
    }
    pc.parse(soundBytes);
    soundBytes = null;
    JRackAttackFrame.getInstance().setParameterChange(pc);
  }

  // private String formatMidiEvent(MidiEvent msg) {
  // if (msg == null) {
  // return "";
  // }
  // return formatMidiMessage(msg.getMessage());
  // }

  public static final String formatMidiMessage(MidiMessage msg) {
    if (msg == null) {
      return "";
    }
    byte bts[] = msg.getMessage();
    StringBuffer sb = new StringBuffer();
    for (byte b : bts) {
      String str = Integer.toHexString(b & 0xFF);
      if (str.length() < 2) {
        sb.append("0");
      }
      sb.append(str);
      sb.append(" ");
    }
    return sb.toString();
  }

  protected void debug(String msg) {
    log.debug(msg);
  }

  private boolean runFlag;

  private byte[] soundBytes;

  /**
   * Holds value of property midiInDevice.
   */
  private MidiDevice midiInDevice;

  /**
   * Getter for property midiInDevice.
   *
   * @return Value of property midiInDevice.
   */
  public MidiDevice getMidiInDevice() {
    return this.midiInDevice;
  }

  /**
   * Setter for property midiInDevice.
   *
   * @param midiInDevice
   *            New value of property midiInDevice.
   */
  public void setMidiInDevice(MidiDevice midiInDevice) {
    if (this.midiInDevice != null && midiInDevice.isOpen()) {
      midiInDevice.close();
    }
    this.midiInDevice = midiInDevice;
    if (this.midiInDevice != null && !midiInDevice.isOpen()) {
      if (midiInDevice.getMaxTransmitters() == 0) {
        JRackAttackFrame.getInstance()
            .handleError("msg.no_transmitter");
      } else {
        try {
          midiInDevice.open();
          midiInDevice.getTransmitter().setReceiver(this);
        } catch (Exception ex) {
          JRackAttackFrame.getInstance().handleError(
              "msg.midi_in_init_failed", ex);
        }
      }
    }
  }

  protected boolean isWaldorfSysex(MidiMessage msg) {
    return (msg.getMessage()[0] & 0xff) == 0xf0
        && msg.getMessage()[1] == RackAttack.WALDORF_MANUFACTURER_BYTE
        && msg.getMessage()[2] == RackAttack.RACK_ATTACK_MODEL_BYTE;
  }

  protected void log(String msg) {
    log.debug(msg);
  }

  /**
   * Holds value of property keyInDevice.
   */
  private MidiDevice keyInDevice;

  /**
   * Getter for property keyInDevice.
   *
   * @return Value of property keyInDevice.
   */
  public MidiDevice getKeyInDevice() {
    return this.keyInDevice;
  }

  /**
   * Setter for property keyInDevice.
   *
   * @param keyInDevice
   *            New value of property keyInDevice.
   */
  public void setKeyInDevice(MidiDevice keyInDevice) {
    if (this.keyInDevice != null && this.keyInDevice.isOpen()) {
      this.keyInDevice.close();
    }
    this.keyInDevice = keyInDevice;
    if (this.keyInDevice != null && !this.keyInDevice.isOpen()) {
      try {
        this.keyInDevice.open();
        this.keyInDevice.getTransmitter().setReceiver(
            new KeyBoardReceiver());
      } catch (MidiUnavailableException e) {
        log.error("error", e);
      }
    }
  }

  /**
   * Receiver for keyboard events. If you have MIDI-IN and Keyboard-In
   * configured correctly, you'll be able to play the RackAttack through the
   * GUI with a master keyboard or similar. All emitted events from this
   * device will be routet through this Receiver and back into the
   * {@link jrackattack.midi.MidiThread MidiThread} to be sent to your
   * RackAttack.
   *
   */
  public class KeyBoardReceiver implements Receiver {
    public void send(MidiMessage message, long timeStamp) {
      // looks for the active MIDI channel to reprogram
      // the incoming NOTE-events to become events of the
      // right channel (RackAttack has 12 of them each with
      // a possibly different sound loaded)
      try {
        if (message.getStatus() == ShortMessage.NOTE_ON
            || message.getStatus() == ShortMessage.NOTE_OFF) {
          ShortMessage sm = (ShortMessage) message;
          sm.setMessage(sm.getCommand(), JRackAttackFrame
              .getInstance().getActiveMidiChannel(), sm
              .getData1(), sm.getData2());
        }
        MidiThread.getInstance().enqueueEvent(message);
      } catch (MidiUnavailableException e) {
        log.error("error", e);
      } catch (InvalidMidiDataException e) {
        log.error("error", e);
      }
    }

    public void close() {
    }
  }

  /**
   * Holds value of property nextProgramNumber.
   */
  private int nextProgramNumber;

  /**
   * Getter for property nextProgramNumber.
   *
   * @return Value of property nextProgramNumber.
   */
  public int getNextProgramNumber() {
    return this.nextProgramNumber;
  }

  /**
   * Setter for property nextProgramNumber.
   *
   * @param nextProgramNumber
   *            New value of property nextProgramNumber.
   */
  public void setNextProgramNumber(int nextProgramNumber) {
    this.nextProgramNumber = nextProgramNumber;
  }
}
/*
* Copyright (C) 2008 Alexander Methke
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program (gplv3.txt).
*/
TOP

Related Classes of jrackattack.midi.MidiReader$KeyBoardReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.