/*voice changer*/
#define F_CPU 16000000
/*external ocilater 16MHz*/
#include <avr/io.h>
#include <avr/delay.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#define BUFSIZE 768
//macro
#define cbi(addr,bit) addr &= ~(1<<bit)
#define sbi(addr,bit) addr |= (1<<bit)
int8_t res; //encoder result(-1 - +1)
ISR(TIMER0_OVF_vect)
{
const int8_t dir[] PROGMEM = {
0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0 }; /* direction table */
static volatile uint8_t i; //index
i = (i << 2) + ((PINC >>2) & 3);
i &= 15;
res = dir[i];
}
void delay_long(uint8_t x)
{
while(x--){
_delay_ms(10);
}
}
void initio(void)
{
//setting ports
PORTB = 0b00000001;
DDRB = 0b00000101;
PORTD = 0xff;
PORTC = 0x1c;
//setting timers
TCCR0 = 0x03;
TIMSK = _BV(TOIE0); //intrrupt interval 1.024ms
TCCR1A = 0b00100001;
TCCR1B = 0b00001001;
//setting AD-converter
ADMUX = 0b01100000; //ADC0 AVcc
ADCSR = 0b11100101;
}
main()
{
uint8_t rate = 1;
uint8_t frac_rate = 0; //0-127,fraction of rate
uint8_t buf[BUFSIZE];
uint8_t *wp = buf;
uint8_t *rp = buf;
uint8_t frac_rp = 0; //0-127,fraction of rate
uint8_t *tmp_p;
int16_t tmp;
initio();
sei();
delay_long(50);
for(;;){
//update rate
tmp = frac_rate + res;
res = 0;
if(tmp < 0){
rate--;
frac_rate = 128 + tmp;
}else if(tmp > 127){
rate++;
frac_rate = tmp - 128;
}else{
frac_rate = tmp;
}
//regulate rate (0.33<rate<3)
if(rate >=3){
rate = 3;
frac_rate = 0;
}if(rate == 0 && frac_rate < 43){
rate = 0;
frac_rate = 43;
}
//output and input analog value
loop_until_bit_is_set(ADCSR,ADIF);
sbi(ADCSR,ADIF);
*wp = ADCH;
tmp_p = rp;
if(++tmp_p >= buf+BUFSIZE)
tmp_p = buf;
OCR1BL = (*tmp_p*frac_rp + *rp*(127 - frac_rp))>>7;
//update pointers
if(++wp == buf+BUFSIZE)
wp = buf;
frac_rp += frac_rate;
if(frac_rp >= 128){
rp++;
frac_rp -= 128;
}
rp += rate;
if(rp >= buf+BUFSIZE)
rp -= BUFSIZE;
}
}
どう動くのかさっぱりわからないです。