「サクラ」交流掲示板

サクラの掲示板です。
[一覧へ] > (@62) [緊急] [コメント]
@62■ (#210) 楽器の音色 - a (2012-01-14 15:47) /緊急 コメント
AVRマイコンで電子オルゴール(「私だけの電子オルゴール」というサイトのもの)を作っています。この「サクラ」というソフトで曲を作り、マイコンに書き込んだあと、スピーカーから3和音で楽器音が出るようにしたいのですが、どのようにするべきかわかりません。教えて頂けないでしょうか。
c言語で記述したプログラムを下にはりつけました。

// avr-gcc -O -mmcu=attiny45 45_3.c -o mymelo.elf
// avr-objcopy -O ihex mymelo.elf mymelo.hex
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include \"mymelo.h\"
#define  V1    0xffff
#define  V2    0x7fff
#define  V3    0x7fff
uint16_t mi1,mi2,mi3,  v1,v2,v3,  vm1,vm2, cntr;
uint8_t  c, c1,c2,c3,  C1,C2,C3,  len1,len2,len3,   t, t1,t2,t3, n, icntr;
SIGNAL(SIG_OVERFLOW1){              // .125*256=32us(@8MHz)
  if(n>0){
    if(--cntr==0){
      cntr=CNT;              // 32us*(1953*120/TEMPO)=62.5ms
      if(--len1==0){            // Part1の次の音符
        t=t1=pgm_read_byte(mi1++);
        if(t==0){
          n--;            // 演奏回数
          mi1=(uint16_t)part1; mi2=(uint16_t)part2; mi3=(uint16_t)part3;
          len1=31; len2=32; len3=32;  // ポーズ(62.5ms*32=2s)
          c=t1=t2=t3=0;
        }else{
          len1=len[t1>>5];      // L32:17.408*10=174.08ms
          c1=0;C1=(C[t1&=0x1f]+64)>>7;
          v1=V1;
        }
      }
      if(--len2==0){            // Part2の次の音符
        t2=pgm_read_byte(mi2++);
        len2=len[t2>>5];        // L32:17.408*10=174.08ms
        c2=0;C2=(C[t2&=0x1f]+64)>>7;
        v2=V2;
      }
      if(--len3==0){            // Part3の次の音符
        t3=pgm_read_byte(mi3++);
        len3=len[t3>>5];        // L32:17.708*10=174.08ms
        c3=0;C3=(C[t3&=0x1f]+64)>>7;
        v3=V3;
      }
    }
    vm2=vm1=0;
    c++;
    if(t1>1){
      if(++c1==C1)  c1=0;        // Part1の周期は32us*C1
      if(c1<(C1>>1))  vm1+=v1;      // Part1の振幅を加算
      else if(!(c&0x0f))  v1-=(v1>>8);  // Part1の振幅減衰
    }
    if(t2>1){
      if(++c2==C2)  c2=0;        // Part2の周期は32us*C2
      if(c2<(C2>>1))  vm2+=v2;      // Part2の振幅を加算
      else if(!(c&0x0f))  v2-=(v2>>8);  // Part2の振幅減衰
    }
    if(t3>1){
      if(++c3==C3)  c3=0;        // Part3の周期は32us*C3
      if(c3<(C3>>1))  vm2+=v3;      // Part3の振幅を加算
      else if(!(c&0x0f))  v3-=(v3>>8);  // Part3の振幅減衰
    }
    OCR1A=(vm1+128)>>8;  OCR1B=~((vm2+128)>>8);
  }
  if(icntr>0)  icntr--;
}
SIGNAL(SIG_INTERRUPT0){          // External Interrupt Request 0
  if(icntr==0){
    if(n>0)  n=0;          // 演奏中ならば停止
    else{
      n=1;            // 1回演奏
      cntr=CNT;          // 32us*(1953*120/TEMPO)=62.5ms
      c=t1=t2=t3=0;
      mi1=(uint16_t)part1; mi2=(uint16_t)part2; mi3=(uint16_t)part3;
      len1=len2=len3=8;      // 初期ディレイ(62.5ms*8=.5s)
    }
  }
  icntr=255;              // チャタリング防止(32*255=8.1ms)
}
int main (void){
  PORTB=0x04;  DDRB=0x1b;        // xxxooroo, CK/1
  TCCR1=0x51;              // if(TCNT1==1)      OC1A=1;
                    // else if(TCNT1==OCR1A)OC1A=0;
  GTCCR=0x50;              // if(TCNT1==1)      OC1B=1;
                    // else if(TCNT1==OCR1B)OC1B=0;
  OCR1C=255;
  n=2;                // 初めに2回演奏
  cntr=CNT;              // 32us*(1953*120/TEMPO)=62.5ms
  c=t1=t2=t3=0;
  mi1=(uint16_t)part1; mi2=(uint16_t)part2; mi3=(uint16_t)part3;  // 楽譜先頭
  len1=len2=len3=8;          // 初期ディレイ(62.5ms*8=.5s)
  TIMSK=_BV(TOIE1); GIMSK=_BV(INT0);  sei();  // enable Ext SW
LOOP:                  // 最適化オプションでfor(;;){}はNG
  if(n==0 && icntr==0){
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_mode();          // SE=1, sleep, SE=0
  }
  goto  LOOP;
}


(#211) Re:楽器の音色 - ん。 (2012-01-17 00:33) /緊急 コメント
表題の件について、質問に質問で返すようで恐縮ですが、
どこまで出来ていて、どこからが出来ないのですか?
出来ないとして、どういう状況で出来ないのですか?
簡単な質問ならともかく、○○したいけどどうやるの? だけでは、
回答しようにも情報が少なすぎます。

とりあえずおっしゃるサイトを少し見た感じだと、

・材料をそろえる
・材料を組み立てる
・専用ソフトとライタで書き込む
・スイッチを入れる
 →演奏開始

のシンプルな流れでできると書いてありました。
サイトの手順どおりにやる分には、出来上がった部品を組み立てるだけです。
ハンダ付けもないです。
c のコンパイルもツールが勝手に行なうようですし、
貼り付けたソースを意識する必要は無いように思いますが。。

まずは、理解できるところだけでもいいのでサイト全体を読んでみてください。
その上で、疑問点を整理されたほうがよいと思います。

(#210)へ返信する:

👆お手数ですが、いたずら防止のために、「医者」の読み方をカタカナで記入してください。

編集時に使うキーを入力(省略可能)

画像ファイル(最大300KB)を添付可能