2015年1月17日土曜日

JAVAでMIDI

 MIDIを勉強したので、JAVAでMIDIを鳴らすAppletを作ってみました。
 
 ソースコードを以下に載せます。

 MIDIファイルの詳細についてはWikipediaJava応用技術講義等を参照ください。

 興味ある方は、ご自由にご利用ください。

--------------------------------------------------

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import javax.sound.midi.*;

/*--------------------------------------------------------------------------------*/

/**
 * アプレット
 */
public class MidiApplet extends Applet
{
private Receiver rec = null;

public MidiApplet()
{
super();

this.setSize( 240, 240);

this.addKeyListener( new SimpleKeyListener( this));

/*---------- コンポーネントの配置 ----------*/
setLayout( new FlowLayout());

Label label1 = new Label( "Program:");
Label label2 = new Label( "Press C, D, E, F, G, A, B key.");
Label label3 = new Label( "(with or without up / down / shift key)");

Choice choice = new Choice();
choice.addItemListener( new SimpleItemListener( this));

for( int i = 0; i < 128; i++)
{
choice.add( Integer.toString( i));
}

this.add( label1);
this.add( choice);
this.add( label2);
this.add( label3);

/*------------------------------------------*/

this.setVisible( true);
this.setFocusable( true);
this.requestFocusInWindow();
}

public void init()
{
this.getMidi();
}

public void start()
{
}

public void paint( Graphics g)
{
}

public void stop()
{
this.closeMidi();
}

public void destroy()
{
}

private void getMidi()
{
System.out.println( "getMidi");

try
{
if( this.rec == null)
{
this.rec = MidiSystem.getReceiver();
}
}
catch( Exception e)
{
System.out.println( "error : getMidi");
}
}

public void sendMidiMessage( int status, int data1, int data2)
{
System.out.print( "sendMidiMessage : ");
System.out.print( status);
System.out.print( ", " + data1);
System.out.println( ", " + data1);

try
{
ShortMessage sMsg = new ShortMessage();
sMsg.setMessage( status, data1, data2);
this.rec.send( sMsg, 1);
}
catch( Exception e)
{
System.out.println( "error : sendMidiMessage");
}
}

private void closeMidi()
{
System.out.println( "closeMidi");

try
{
if( this.rec != null)
{
this.rec.close();
}
}
catch( Exception e)
{
System.out.println( "error : closeMidi");
}
}
}

/*--------------------------------------------------------------------------------*/

/**
 * キーリスナー
 */
class SimpleKeyListener implements KeyListener
{
//C, D, E, F, G, A, B
//C#, D#, F#, G#, A#

private MidiApplet midiApplet;
private boolean[] flag;
public int noteC;

public SimpleKeyListener( MidiApplet midiApplet)
{
super();

this.midiApplet = midiApplet;

this.flag = new boolean[10];
this.noteC = 60;
}

public void keyPressed( KeyEvent e)
{
//System.out.println( "key pressed");

int code = e.getKeyCode();
int note = this.noteC;

if( code == KeyEvent.VK_C)
{
if( this.flag[0] == true)
{
return;
}

this.flag[0] = true;
}
else if( code == KeyEvent.VK_D)
{
if( this.flag[1] == true)
{
return;
}

this.flag[1] = true;
note += 2;
}
else if( code == KeyEvent.VK_E)
{
if( this.flag[2] == true)
{
return;
}

this.flag[2] = true;
note += 4;
}
else if( code == KeyEvent.VK_F)
{
if( this.flag[3] == true)
{
return;
}

this.flag[3] = true;
note += 5;
}
else if( code == KeyEvent.VK_G)
{
if( this.flag[4] == true)
{
return;
}

this.flag[4] = true;
note += 7;
}
else if( code == KeyEvent.VK_A)
{
if( this.flag[5] == true)
{
return;
}

this.flag[5] = true;
note += 9;
}
else if( code == KeyEvent.VK_B)
{
if( this.flag[6] == true)
{
return;
}

this.flag[6] = true;
note += 11;
}
else if( code == KeyEvent.VK_UP)
{
this.flag[7] = true;
return;
}
else if( code == KeyEvent.VK_DOWN)
{
this.flag[8] = true;
return;
}
else if( code == KeyEvent.VK_SHIFT)
{
this.flag[9] = true;
return;
}
else
{
return;
}

note += ( this.flag[7] == true ? 12 : 0);
note -= ( this.flag[8] == true ? 12 : 0);
note += ( ( this.flag[9] == true && code != KeyEvent.VK_E && code != KeyEvent.VK_B) ? 1 : 0);

this.midiApplet.sendMidiMessage( ShortMessage.NOTE_ON, note, 127);
}

public void keyReleased( KeyEvent e)
{
//System.out.println( "key released");

int code = e.getKeyCode();
int note = this.noteC;

if( code == KeyEvent.VK_C)
{
this.flag[0] = false;
}
else if( code == KeyEvent.VK_D)
{
this.flag[1] = false;
note += 2;
}
else if( code == KeyEvent.VK_E)
{
this.flag[2] = false;
note += 4;
}
else if( code == KeyEvent.VK_F)
{
this.flag[3] = false;
note += 5;
}
else if( code == KeyEvent.VK_G)
{
this.flag[4] = false;
note += 7;
}
else if( code == KeyEvent.VK_A)
{
this.flag[5] = false;
note += 9;
}
else if( code == KeyEvent.VK_B)
{
this.flag[6] = false;
note += 11;
}
else if( code == KeyEvent.VK_UP)
{
this.flag[7] = false;
return;
}
else if( code == KeyEvent.VK_DOWN)
{
this.flag[8] = false;
return;
}
else if( code == KeyEvent.VK_LEFT)
{
this.noteC -= ( 12 < this.noteC) ? 12 : 0;
}
else if( code == KeyEvent.VK_RIGHT)
{
this.noteC += ( this.noteC < 120) ? 12 : 0;
}
else if( code == KeyEvent.VK_SHIFT)
{
this.flag[9] = false;
return;
}

//Note Onの時の、up, down, shiftキーの状態を記録していないので、すべてにNote Offメッセージを送る
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note, 127);
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note - 12, 127);
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note + 12, 127);

if( code != KeyEvent.VK_E && code != KeyEvent.VK_B)
{
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note -11, 127);
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note + 1, 127);
this.midiApplet.sendMidiMessage( ShortMessage.NOTE_OFF, note + 13, 127);
}
}

public void keyTyped( KeyEvent e)
{
//System.out.println( "key typed");
}
}

/*--------------------------------------------------------------------------------*/

/**
 * アイテムリスナー
 */
class SimpleItemListener implements ItemListener
{
private MidiApplet midiApplet;

public SimpleItemListener( MidiApplet midiApplet)
{
super();

this.midiApplet = midiApplet;
}

public void itemStateChanged( ItemEvent e)
{
Choice choice = (Choice)e.getItemSelectable();
int temp = choice.getSelectedIndex();

this.midiApplet.sendMidiMessage( ShortMessage.PROGRAM_CHANGE, temp, 0);

this.midiApplet.requestFocusInWindow();
}
}

/*--------------------------------------------------------------------------------*/

0 件のコメント:

コメントを投稿