///////////////////////////////////////////////////////////// // GR-ADZUKI(β) Motor-DriverでSpeaker鳴らしてみるテスト // 2016.7.1 // ★ モータードライバの片ピンしか制御していないので、DCがかかります。 // スピーカーとか壊れても責任取りません。自己責任でお願いします。 // ・HZNUMを小さくすると音が歪んでいくのが分かります。 // ・HZNUMは処理の重さ上、10kHzが限界です。それ以上はヘンになります。たぶん。 ///////////////////////////////////////////////////////////// #define HZNUM 10000 // 割り込み周期(Hz)。10000なら10kHzでanalogWriteを変える。 unsigned long int INTUS; unsigned long int INUSHUN; #define PIBUF 9 #define PBF (1 << PIBUF) unsigned char sindat[PBF]; int led = 23; #define VOLUME 127 unsigned long int outsinhz[] = {52325,65925,78399}; unsigned long int outsinct[] = {0,0,0}; unsigned long int outsinmx[] = {0,0,0}; unsigned char mus_part[3][3][40] = { {{ 1, 6, 7, 8, 9,10,12,13,15,16,18,21,22,24,25,30,31,32,33,34,36,37,39,40,42}, // 時間軸 {21,16,21,25,28,25,21,23,23,23,18,23,21,20,21,16,21,25,28,25,21,22,22,22,21}, // 音階 { 5, 1, 1, 1, 1, 2, 1, 2, 1, 2, 3, 1, 2, 1, 5, 1, 1, 1, 1, 2, 1, 2, 1, 2, 6}}, // 長さ {{ 1, 6, 7, 8, 9,10,12,13,15,16,18,21,22,24,25,30,31,32,33,34,36,37,39,40,42}, {13,13,13,16,21,16,13,14,14,14,14,14,14,14,13,13,13,13,13,13,13,14,14,14,13}, { 5, 1, 1, 1, 1, 2, 1, 2, 1, 2, 3, 1, 2, 1, 5, 1, 1, 1, 1, 2, 1, 2, 1, 2, 6}}, {{ 1, 2, 3, 4, 7, 8, 9,10,13,14,15,16,19,20,21,22,25,26,27,28,31,32,33,34,37,38,39,40,42}, { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6}} }; unsigned long int oki[36],oct[36],gkf_cntr,gkf_cntend; unsigned char musprtmst,musprtcnt[3]; unsigned long int musprtstp[3]; void setup() { // unsigned short int e,f; // Serial.begin(57600); // // while (!Serial || Serial.available() <= 0) {}; for(f = 0;f < PBF;f++) sindat[f] = (sin(3.141592 * 2 * f / PBF) + 1.0) * VOLUME; for(e = 0;e < 3;e++) { // とりあえず3オクターブ分作る for(f = 0;f < 12;f++) { // oki[e * 12 + f] = (unsigned long int)((22000.0 * pow(2.0,e) * pow(pow(2.0,(1.0/12.0)),f)) * 0.94); oct[e * 12 + f] = hz2us(oki[e * 12 + f]); // ここでus変換後の値も作っちゃう } // } // INTUS = (1000.0 * 1000.0 / HZNUM); // HZNUMのus値。 INUSHUN = INTUS; // 音との比較値。 pinMode(led, OUTPUT); // pinMode(10,OUTPUT); // pinMode( 9,OUTPUT); // digitalWrite(10,0); // analogWriteFrequency(40000); // outsinmx[0] = oct[28]; // outsinmx[1] = oct[32]; // outsinmx[2] = oct[35]; // musprtmst = 0; // for(f = 0;f < 3;f++) { // musprtcnt[f] = 0; // musprtstp[f] = 0; // } // gkf_cntend = 10000.0 / (7.5 * (10000.0 / HZNUM)); // とりあえず6変化/1secな感じで attachMicroIntervalTimerHandler(int_wavout,INTUS); // サンプリング周波数な感じでタイマ割り込み } // void loop() { // なんもしない } // unsigned long int hz2us(unsigned long int dt){ // return (1000.0*1000.0*100.0/dt); // us変換だけのつもりだったけど更に分解能UP } // void int_wavout() { // unsigned char a,b; // unsigned char f; // a = 0; // for(f = 0;f < 3;f++){ // 3音ぶん処理 outsinct[f] += INUSHUN; // 出力波位置に割り込み時間を加算 while(1) { // if(outsinct[f] < outsinmx[f]) break; // 出力波位置が出力波長を超えてなければ脱出 outsinct[f] -= outsinmx[f]; // 越えてたら引く } // b = sindat[int(PBF * outsinct[f] / outsinmx[f])] / 4 ; // 波長一周期のうちどのへんかってのからバッファ位置に変換 if(musprtstp[f] != 0) { // a += b; musprtstp[f]--; // } // } // analogWrite(5,a); // 出力 gkf_cntr++; // if(gkf_cntr > gkf_cntend) { // gkf_cntr = 0; // gakufu_koushin(); // } // return; // } // void gakufu_koushin(void){ // unsigned char f; // musprtmst++; // if (musprtmst > 48) { // musprtmst = 0; // for(f = 0;f < 3;f++) { // musprtcnt[f] = 0; // musprtstp[f] = 0; // } // } // for(f = 0;f < 3;f++){ // if(mus_part[f][0][musprtcnt[f]] == musprtmst) { // outsinmx[f] = oct[mus_part[f][1][musprtcnt[f]]]; // musprtstp[f] = gkf_cntend * mus_part[f][2][musprtcnt[f]] * 0.7; // musprtcnt[f]++; // 次のタイミングを見るよう準備 } // } // return; // } //