質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

2573閲覧

Javaでmidiファイルを外部音源で再生する方法

lemon

総合スコア18

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

1クリップ

投稿2016/09/14 07:13

編集2016/09/14 07:59

###前提・実現したいこと
ハードウェアシンセサイザー(FA06)でCC90を入力したら、midiファイルをそのシンセイザーで発声するというプログラムを作ろうとしています。
###発生している問題・エラーメッセージ

midiファイルを再生した時に音源がシンセサイザーではなくwindows標準のmsgsで発声されてしまいます

###該当のソースコード

Java

1package FA06MidiControl; 2 3import java.io.File; 4 5import javax.sound.midi.MidiDevice; 6import javax.sound.midi.MidiMessage; 7import javax.sound.midi.MidiSystem; 8import javax.sound.midi.MidiUnavailableException; 9import javax.sound.midi.Receiver; 10import javax.sound.midi.Sequence; 11import javax.sound.midi.Sequencer; 12import javax.sound.midi.ShortMessage; 13import javax.sound.midi.Transmitter; 14 15public class MidiControl implements Receiver { 16 static int DEVICE_IN = 0; 17 static int DEVICE_OUT = 0;// ここを修正 18 19 public boolean isOnCC90 = false; 20 public final int PEDAL_MARGIN = 64; 21 22 private MidiDevice.Info[] info; 23 private MidiDevice in_device = null; 24 private MidiDevice out_device = null; 25 26 public Sequencer sequencer; 27 // public static File file = new 28 // File("D:/workspace/midi/midi/moonpride/init.mid"); // midiファイルのディレクトリ指定 29 public static File file = new File("D:/workspace/midi/midi/ceremo.mid"); // midiファイルのディレクトリ指定 30 31 public static void main(String[] args) { 32 new MidiControl(); 33 34 } 35 36 public MidiControl() { 37 info = MidiSystem.getMidiDeviceInfo(); 38 MidiDevice dev = null; 39 40 for (int i = 0; i < info.length; i++) { 41 if (info[i].getName().equals("FA-06 08")) { 42 DEVICE_IN = i; 43 break; 44 } 45 } 46 47 for (int i = 0; i < info.length; i++) { 48 if (info[i].getName().equals("FA-06 08")) { 49 DEVICE_OUT = i; 50 break; 51 } 52 } 53 54 try { 55 dev = MidiSystem.getMidiDevice(info[DEVICE_IN]); 56 } catch (Throwable t) { 57 System.err.println(t); 58 } 59 connectMidiIn(dev); 60 61 try { 62 dev = MidiSystem.getMidiDevice(info[DEVICE_OUT]); 63 } catch (Throwable t) { 64 System.err.println(t); 65 } 66 connectMidiOut(dev); 67 68 connectSequencer(); 69 } 70 71 private void connectMidiIn(MidiDevice device) { 72 try { 73 device.open(); 74 Transmitter tx = device.getTransmitter(); 75 tx.setReceiver(this); 76 in_device = device;// トランスミッターにコンストラクタで生成している自身の参照を渡し、レシーバーとして設定 77 } catch (MidiUnavailableException e) { 78 System.err.println(e); 79 } 80 81 } 82 83 private void connectMidiOut(MidiDevice device) { 84 try { 85 device.open(); 86 out_device = device; 87 } catch (MidiUnavailableException e) { 88 System.err.println(e); 89 } 90 } 91 92 public void connectSequencer() { 93 try { 94 sequencer = MidiSystem.getSequencer(); 95 sequencer.setLoopCount(1); 96 sequencer.open(); 97 } catch (Throwable t) { 98 System.err.println(t); 99 } 100 101 try { 102 Sequence sequence = MidiSystem.getSequence(file); 103 sequencer.setSequence(sequence);// 音源セット 104 } catch (Throwable t) { 105 System.err.println(t); 106 } 107 108 try { 109 sequencer.getTransmitter().setReceiver(out_device.getReceiver()); 110 } catch (MidiUnavailableException e) { 111 System.err.println(e); 112 } 113 } 114 115 public void close() { 116 } 117 118 public void send(MidiMessage message, long timeStamp) { 119 if (message instanceof ShortMessage) { 120 ShortMessage sm = (ShortMessage) message; 121 switch (sm.getCommand()) { 122 case ShortMessage.CONTROL_CHANGE: 123 System.out.println(sm.getData1() + " " + sm.getData2()); 124 if (sm.getData1() == 90) { 125 if (sm.getData2() == 0) { 126 if (isOnCC90) 127 isOnCC90 = false; 128 } else if (sm.getData2() > 127 - PEDAL_MARGIN) { 129 if (!(isOnCC90)) { 130 isOnCC90 = true; 131 System.out.println("踏まれたよ"); 132 sequencer.start(); 133 } 134 135 } 136 System.out.println("isOnCC90: " + isOnCC90); 137 } 138 break; 139 default: 140 } 141 } 142 /* 143 * try { out_device.getReceiver().send(message, timeStamp); } catch 144 * (MidiUnavailableException e) { //System.err.println(e); } 145 */ 146 } 147 148}

###試したこと
connectMidiInでシーケンサーをレシーバーに設定している

###補足情報(言語/FW/ツール等のバージョンなど)

A-pZ👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ソースコードを載せて具体的な質問をするという点はよいとして、「Runの結果がこうなった」だけではなくせめてDEVICE_IN/OUTの値が何でデバイス名はこうなっていた程度は明記してほしいです。ハードがからむため質問者さん以外の人はプログラムを単純にrunしても同じ結果が得られませんよね?

さて情報がないので根本的なところからになってしまいますが、ひょっとして"FA06"というMidiDeviceが実際にはinfo[]中になくてシステムに登録されている最初の(info[0]の)デバイスがたまたま「windows標準のmsgs」だったということはないでしょうか?

投稿2016/09/14 10:59

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lemon

2016/09/15 04:43

指摘ありがとうございます。 申し訳ございません。 http://www.ruimo.com/howto/java/midi/ こちらのサイトのデバイスの種類を選択するプログラムを実行した結果を添付します There are 10 devices. *** 0 *** Description:Software MIDI Synthesizer Name:Gervill Vendor:OpenJDK *** This is Synthesizer. *** 1 *** Description:No details available Name:FA-06 08 Vendor:Unknown vendor *** 2 *** Description:No details available Name:FA-06 08 DAW CTRL Vendor:Unknown vendor *** 3 *** Description:No details available Name:FA-06 08 CTRL Vendor:Unknown vendor *** 4 *** Description:Windows MIDI_MAPPER Name:Microsoft MIDI Mapper Vendor:Unknown vendor *** 5 *** Description:Internal software synthesizer Name:Microsoft GS Wavetable Synth Vendor:Unknown vendor *** 6 *** Description:External MIDI Port Name:FA-06 08 Vendor:Unknown vendor *** 7 *** Description:External MIDI Port Name:FA-06 08 DAW CTRL Vendor:Unknown vendor *** 8 *** Description:External MIDI Port Name:FA-06 08 CTRL Vendor:Unknown vendor *** 9 *** Description:Software sequencer Name:Real Time Sequencer Vendor:Oracle Corporation *** This is Sequencer. こちらになります。
KSwordOfHaste

2016/09/17 05:51

この内容に答えがひそんでいそうですね。ハードウェアシンセサイザーはMidiDeviceとしてシステムが認識できているようですが、FA-06 08に関係するMidiDeviceが複数個登録されていますね。質問者さんのプログラムではこれらのデバイスの中からNameが"FA-06 08"であるものが目的のMidiDeviceであると判断してますが、実はその名前ではないということだと思います。自分はハードシンセサイザーを扱ったことがないのではっきりわかりませんが、[6]External MIDI Port/FA-06 08もしくは[8]External MIDI Port/FA-06 08 CTRLの2つがそれっぽい気がします。([7]はDAW CTRLとあるのできっと違いますかね…) プログラム上forループでDEVICE_IN/DEVICE_OUTを決めている場所を一時的に変えて上記の6とか8とかのデバイスのインデックスを直接設定して試しに動かしてみるのが早そうな気がします。 なお、蛇足ながらMidiDeviceを探すときに名前だけを頼りに探してますが、そのデバイスの`getMaxReceivers`,`getMaxTransmitters`の数をチェックして本当にそのデバイスにreceiver/transmitterの機能があるかを確認すべきと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問