科学の箱

科学・IT・登山の話題

バイオリン

バイオリンのチューナーを作る – midiをさらに掘り下げた

投稿日:2013年11月20日 更新日:

midiについてさらに掘り下げてみた。

連続したノートの演奏

まず前日のソースコードから連続で違うノートを演奏してみた。連続で音を演奏するためには前の音を消す必要がある。消さないと同時に音が鳴り響くために和音となる。音を消すコードは以下になる。

message.setMessage(ShortMessage.NOTE_OFF, 69, 127);

バイオリンのチューニングを考えてA, D, E, Gを鳴らす。


package midi02;

/*
 * midi02
 * 指定した音を連続して演奏してみる
 *
 */

import java.io.*;
import javax.sound.midi.*;

class Test {
    public static void main(String[] args) throws Exception {
        int[] notenums = { 69, 74, 76, 79 }; /* A, D, E, G */
        Receiver midireceiver = MidiSystem.getReceiver();
        ShortMessage smsg = new ShortMessage();
       	try {
	        for(int num : notenums) {
		            smsg.setMessage(ShortMessage.NOTE_ON, num, 127);
		            midireceiver.send(smsg, -1);
		            try {
		                Thread.sleep(5000);
		            } catch (InterruptedException e) {
		                e.printStackTrace();
		                // handle the exception...
		                // For example consider calling Thread.currentThread().interrupt(); here.
		            }
		            smsg.setMessage(ShortMessage.NOTE_OFF, num, 127);
		            midireceiver.send(smsg, -1);
	        }
       	} finally {
       		if (midireceiver != null) midireceiver.close();
       	}
    }
}

MIDIデバイスの取得

さて次にすこし方向性を変えてみて、システムで利用しているMIDIデバイスについて確認をする。この情報はMidiSystemとMidiDeviceオブジェクトから簡単に取得できる。

package midi03;

	import javax.sound.midi.*;
	import java.util.*;
	class Test {
	    public static void main(String[] args) {
	    	System.out.println("----- システムデフォルト情報 ----- ");
	    	try {
		    	Sequencer sequencer = MidiSystem.getSequencer();
		    	System.out.println("デフォルトシステムシーケンサ: " +
		    			   sequencer.getDeviceInfo().toString());

		    	Synthesizer synthesizer = MidiSystem.getSynthesizer();
		    	System.out.println("デフォルトシステムシンセサイザ: " +
		    			   synthesizer.getDeviceInfo().toString());
	    	} catch (Exception e) {
	    		e.printStackTrace();
	    	}

	        MidiDevice.Info[] devices;

	        System.out.println("\n----- システム MIDIデバイス情報 -----");
	        devices = MidiSystem.getMidiDeviceInfo();
	        for(MidiDevice.Info info : devices) {
	            System.out.println("名前:" + info.getName() +
	            		", Version: " + info.getVersion() +
	            		", 会社:" + info.getVendor() +
	            		", 詳細:" + info.getDescription());
	            MidiDevice device = null;
	            try {
				    device = MidiSystem.getMidiDevice(info);
				    if (! device.isOpen()) {
					device.open();
				    }
	            } catch (Exception e){
	            	e.printStackTrace();
	            }
			    if (device instanceof Sequencer) {
			    	System.out.println("        デバイスタイプ: シーケンサ");
			    }
			    if (device instanceof Synthesizer) {
			    	System.out.println("        デバイスタイプ: シンセサイザ");
			    }

			    System.out.println("\n        レシーバ--------------------------------");
			    List receivers = device.getReceivers();
			    for (Receiver r: receivers) {
			    	System.out.println("            " + r.toString());
			    }
			    try {
			    	System.out.println("        デフォルトのレシーバ: " +
						   device.getReceiver().toString());

					System.out.println("        現在開いているレシーバー:");
					receivers = device.getReceivers();
					for (Receiver r: receivers) {
					    System.out.println("            " + r.toString());
					}
			    } catch(MidiUnavailableException e) {
			    	System.out.println("        デフォルトレシーバばなし");
			    }

			    System.out.println("\n        トランスミッター--------------------------------");
			    List transmitters = device.getTransmitters();
			    for (Transmitter t: transmitters) {
			    	System.out.println("            " + t.toString());
			    }
			    try {
					System.out.println("        デフォルトトランスミッター: " +
							   device.getTransmitter().toString());
					System.out.println("        現在開いているトランスミッター:");
					transmitters = device.getTransmitters();
					for (Transmitter t: transmitters) {
					    System.out.println("            " + t.toString());
					}
			    } catch(MidiUnavailableException e) {
			    	System.out.println("        デフォルトトランスミッターなし");
			    }
			    device.close();
		    }

        }
	}

レシーバとシーケンサの違い

レシーバを使って連続したピッチを再生しようとしたがうまくいかなかった。調べてみるとレシーバはビープのような単一の音を再生をする機能しかない。音楽のように複雑なノートが合わさった曲はシーケンサを使う。

レシーバとシーケンサの違いを調べてみた。

Oracleが提供するJava SE documentからの抜粋である。本文はこちらにある。

Transmitters and Receivers

Most MIDI devices are capable of sending MidiMessages, receiving them, or both. The way a device sends data is via one or more transmitter objects that it “owns.”

Sequencers

A sequencer is a device for capturing and playing back sequences of MIDI events. It has transmitters, because it typically sends the MIDI messages stored in the sequence to another device, such as a synthesizer or MIDI output port. It also has receivers, because it can capture MIDI messages and store them in a sequence.

レシーバはMidiMessagを送る機能があると説明されている。それに対してSequencerは一連のMidiイベントをキャプチャおよび再生できるとしている。またこのMidiイベントにはMIDIメッセ―ジも含まれている。

MIDIシーケンサを利用すれば連続したノートを再生できるらしい。

Instrument

midiでは楽器の種類を変えて同じ音を演奏することができる。まずシステムで利用できる楽器の一覧を取得する。


package midi04;

import javax.sound.midi.*;

import java.util.*;

public class midi04main {

	public static void main(String[] args)
	{
	    try {
	        Synthesizer synthesizer = MidiSystem.getSynthesizer();
	        synthesizer.open();
	        Instrument[] ints = synthesizer.getAvailableInstruments();
	        int index = 0;
		for (Instrument i: ints) {
		    	index++;
		    	System.out.println(index + " : " + i.getName());
		}
	    } catch (Exception e)
	    {
	        e.printStackTrace();
	    }
	}

}

midiで楽器を変えてみる

midiでは楽器をシンセサイザから変えることができる。violinは楽器番号が40であることがわかっているので、ノート69をバイオリンで再生する。


package midi05;

import javax.sound.midi.*;
import javax.sound.*;

public class midi05main {

	static int instrument = 41;
    static int note = 69;
    static int velocity = 127;

    public static void main(String[] args) {
        Synthesizer synth = null;
        try {
            synth = MidiSystem.getSynthesizer();
            synth.open();
        }
        catch (Exception e) {
            System.out.println(e);
        }
        Soundbank soundbank = synth.getDefaultSoundbank();
        Instrument[] instr = soundbank.getInstruments();
        synth.loadInstrument(instr[instrument]);
            //Changing this int (instrument) does nothing
        MidiChannel[] mc = synth.getChannels();
        mc[0].programChange(0, instrument);
mc[0].noteOn(note, velocity);
        try { Thread.sleep(5000); } catch (InterruptedException e) {}
        System.out.println(instr[instrument].getName());
        synth.close();

    }
}

メタ情報

inarticle



メタ情報

inarticle



-バイオリン
-, ,

執筆者:


  1. […] バイオリンのチューナーを作る – midiをさらに掘り下げた […]

comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

midiで入力デバイスの一覧を取得する

マイクロフォンを使いmidiで録音をしてみる。下記のページからmidiデバイスの一覧を取得したが、肝心のマイクロフォンが含まれていない。 バイオリンのチューナーを作る – midiをさらに …

no image

バイオリンのチューナーを作る – midiについて調べた

バイオリンのチューナーアプリを作ろうと思い立ち調査を開始。 PC上で音楽関連の操作をするにはmidiを利用する。javaではすでにjavax.soud.midiパッケージが提供されている。 midiで …

no image

midiシーケンサで調べたことをまとめる

シーケンサと対比するのはレシーバである。レシーバではリアルタイムに指定したノートを送信できる。例えばユーザーの入力に合わせて音を鳴らしたいときにはレシーバを使う。 それに対してシーケンサはあらかじめ作 …

2013年11月
« 10月   12月 »
 123
45678910
11121314151617
18192021222324
252627282930  

side bar top



アーカイブ

カテゴリー