2015年1月13日火曜日

Piano-パソコン側

//javac -cp C:\xbee\rxtx-2.1-7-bins-r2\Windows\ch-rxtx-2.2-20081207-win-x64\RXTXcomm.jar ArduinoPiano.java
//java -cp C:\xbee\rxtx-2.1-7-bins-r2\Windows\ch-rxtx-2.2-20081207-win-x64\RXTXcomm.jar;. -Djava.library.path=C:\xbee\rxtx-2.1-7-bins-r2\Windows\ch-rxtx-2.2-20081207-win-x64 ArduinoPiano

import java.io.*;
import gnu.io.*;
import java.awt.*;
import javax.sound.sampled.*;
public class ArduinoPiano{
static int SAMPLE_RATE = 44100; // 44.1KHz
static int BPM = 120;
static SourceDataLine line;
public static void main( String arg[] ){
try{
int counter=0;
//シリアルポートを確保する
//使用するCOMポートを取得
CommPortIdentifier comID = CommPortIdentifier.getPortIdentifier( "COM13" );
//COMポートを開く
CommPort commPort = comID.open("hoge",2000);
//シリアルポートのインスタンスを生成
SerialPort port = (SerialPort)commPort;

//シリアルポートの設定
//ボーレート、データビット数、ストップビット数、パリティを設定
port.setSerialPortParams( 9800,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
//フロー制御(今回は行わない)
port.setFlowControlMode( SerialPort.FLOWCONTROL_NONE );
InputStream in = port.getInputStream();
while (true) {
byte[] buffer = new byte[1024];
int numRead = in.read(buffer);
if (numRead == -1) {
break;
} else if (numRead == 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// 割り込まれても何もしない
}
}
String xx = new String(buffer, "UTF-8");
String s2 = "do";
if(xx.startsWith(s2)){
playdo();
}
s2 = "re";
if(xx.startsWith(s2)){
playre();
}
s2 = "mi";
if(xx.startsWith(s2)){
playmi();
}
s2 = "fa";
if(xx.startsWith(s2)){
playfa();
}
s2 = "so";
if(xx.startsWith(s2)){
playso();
}
s2 = "ra";
if(xx.startsWith(s2)){
playra();
}
s2 = "si";
if(xx.startsWith(s2)){
playsi();
}
s2 = "ta";
if(xx.startsWith(s2)){
playddo();
}
}
port.close();
}catch( Exception e ){
System.out.println( "エラーです:" + e );
}
}
public static void playdo()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,C), n8);
        /*writeNote(getNotenoToFreq(6,E), n8);
        writeNote(getNotenoToFreq(6,E), n4);
        writeNote(getNotenoToFreq(6,F), n8);
        writeNote(getNotenoToFreq(6,D), n8);
        writeNote(getNotenoToFreq(6,D), n4);
        writeNote(getNotenoToFreq(6,C), n8);
        writeNote(getNotenoToFreq(6,D), n8);
        writeNote(getNotenoToFreq(6,E), n8);
        writeNote(getNotenoToFreq(6,F), n8);
        writeNote(getNotenoToFreq(6,G), n8);
        writeNote(getNotenoToFreq(6,G), n8);
        writeNote(getNotenoToFreq(6,G), n4);*/
        line.drain(); // 終了まで待機
}
public static void playre()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,D), n8);
        line.drain(); // 終了まで待機
}
public static void playmi()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,E), n8);
        line.drain(); // 終了まで待機
}
public static void playfa()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,F), n8);
        line.drain(); // 終了まで待機
}
public static void playso()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,G), n8);
        line.drain(); // 終了まで待機
}
public static void playra()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,A), n8);
        line.drain(); // 終了まで待機
}
public static void playsi()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(6,B), n8);
        line.drain(); // 終了まで待機
}
public static void playddo()
throws LineUnavailableException {
        calcFrequency();
        // Initialize Audio
        AudioFormat af = new AudioFormat(SAMPLE_RATE, 8, 1, true, true);
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
        line = (SourceDataLine)AudioSystem.getLine(info);
        // Play
        line.open();
        line.start();
        // 演奏
        int n8 = getSampleCount(8/*分音符*/);
        writeNote(getNotenoToFreq(7,C), n8);
        line.drain(); // 終了まで待機
}

// 実際に波形を書き込む
    static void writeNote(double frequency, int sampleCount) {
        byte[] b = new byte[sampleCount];
        double amplitude = SAMPLE_RATE / frequency; // 波長
        for (int i = 0; i < b.length; i++) {
            double r = i / amplitude;
            b[i] = (byte)((Math.round(r) % 2 == 0) ? 100 : -100);
        }
        // 再生(バイト列を line に書き込む)
        line.write(b, 0, b.length);
    }
    // 音の長さを計算する
    static int getSampleCount(int nLength/*n分音符*/) {
        double n4 = (60.0 / BPM) * SAMPLE_RATE; // 四分音符のサンプル数
        double n1 = n4 * 4; // 全音符のサンプル数
        return (int)Math.round(n1 / nLength);
    }
        // 音名を定数で表したもの
    static int C=0,CS=1,D=2,DS=3,E=4,F=5,FS=6,G=7,GS=8,A=9,AS=10,B=11;
    // 音名から NoteNo を計算する
    static int getNoteNo(int octave, int noteName) {
        return octave * 12 + noteName;
    }
    // 周波数を計算してテーブルにセットする
    static double note_freq[] = new double[128];
    static void calcFrequency() {
        // 半音(2の12乗根)を計算
        double r = Math.pow(2.0, 1.0 / 12.0);
        // A(NoteNo=69) より上の音を計算
        note_freq[69] = 440.0; // A のノート
        for (int i = 70; i < 128; i++) {
            note_freq[i] = note_freq[i-1] * r;
        }
        // A(NoteNo=69) より下の音を計算
        for (int i = 68; i >= 0; i--) {
            note_freq[i] = note_freq[i+1] / r;
        }
        return;
    }
    static double getNotenoToFreq(int octave, int noteName) {
        return note_freq[getNoteNo(octave, noteName)];
    }

}

0 件のコメント:

コメントを投稿