前提・実現したいこと
具体的な質問でなく抽象的な質問になってしまい申し訳ございません。
javaでのソフトウェアシンセサイザーのプログラミングについての情報がネット上にあまりなかったので質問させてもらいました。
はじめてteratailの利用するので何が問題があればご指摘お願いします。
また質問などがありましたらお願いします。
javaでMIDIキーボードからの入力でリアルタイムに演奏できるようなソフトを作りたいと思っています。
MIDIキーボードでの入力
↓
オシレーターを作成しSin波などの波形を生成する
↓
javax.sound.sampled.*(?)のaudio.writeを使って出音
という流れで処理を行いたいと思っています。
MIDIキーボードからのメッセージの受け取りはReceiverのsendメソッドを用いて実装できたのですが、この後のオシレーターの管理について悩んでいます。
試したこと
sendメソッドで受け取ったMIDIキーの鍵盤の番号でOscillatorクラスを作成し、リストに追加
Mainクラスのfor文内部でリストをループしOscillator.readメソッドから読み出しを4回分繰り返す。
リストの要素数で割り、byte型にキャストし再生
この方法を用いた所、遅延が酷く、複数音ならした時にまともに音がなりませんでした…
該当のソースコード
上記で試した内容は省いて最低限のものだけ載せています、java初心者のため見づらい所も多々あると思います。
java
1import javax.sound.sampled.*; 2import java.lang.Math; 3 4import java.util.ArrayList; 5import javax.sound.midi.*; 6import java.util.Scanner; 7 8public class Main{ 9 10 11 static final int SAMPLE_RATE=44100; 12 static byte[] data = new byte[4]; 13 14//----------------------------------------------------------- 15 16 public static void main(String[] args){ 17 18 19 dumpDeviceInfo();//MIDI一覧の表示 20 Scanner scan = new Scanner(System.in); 21 System.out.print("デバイス番号を入力してください:"); 22 int DEVICE_IN = scan.nextInt(); //デバイス番号の入力 23 24 ArrayList<MidiDevice> devices = getDevices(); 25 MidiDevice device_input = devices.get(DEVICE_IN); 26 27 try{ 28 Transmitter trans = device_input.getTransmitter(); 29 30 trans.setReceiver(new MidiInputReceiver(devices.get(DEVICE_IN).getDeviceInfo().toString()));//Receive 31 32 device_input.open(); 33 34 }catch (MidiUnavailableException e) { 35 System.err.println(e.getMessage()); 36 System.exit(0); 37 } 38 39 try{ 40 AudioFormat fmt=new AudioFormat(SAMPLE_RATE, 8, 1, true, false); 41 SourceDataLine audio=(SourceDataLine)AudioSystem.getSourceDataLine(fmt); 42 audio.open(fmt); 43 audio.start(); 44 45 while(true){ 46 47 for(int i=0; i<4; i++){ 48 //このループ内でdata配列に波形を入れたい。 49 } 50 51 audio.write(data, 0, 4);//再生 52 53 } 54 55 }catch(Exception e){ 56 e.printStackTrace(); 57 System.exit(1); 58 } 59 60 } 61} 62
java
1import javax.sound.midi.*; 2//===================== 3 4class MidiInputReceiver implements Receiver { 5 public String name; 6 public MidiInputReceiver(String name) { 7 this.name = name; 8 System.out.println("midi connect"); 9 } 10 11 public void send(MidiMessage message, long timeStamp) { 12 13 if (message instanceof ShortMessage) { 14 ShortMessage sm = ((ShortMessage)message); 15 16 System.out.println(sm.getCommand()); 17 System.out.println(sm.getData1()); 18 System.out.println(sm.getData2()); 19 20 } 21 System.out.println("midi received"); 22 } 23 24 public void close() {} 25 26 }
java
1public class Oscillator{ 2 3 static final int SAMPLE_RATE=44100; 4 double freq,dt; 5 int time; 6 7 public Oscillator(int key){ 8 9 dt = Math.PI*2/SAMPLE_RATE; 10 freq = 440*(Math.pow(2,((key-69)/12))); 11 time = 0; 12 13 } 14 15 public double read(){ 16 17 double w = (Math.sin(dt*time*freq)*127); 18 time++; 19 return w; 20 } 21 22}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/07/22 01:36