|
Introduction
High Level
Design
Program/Hardware Design
Results
Conclusions
Appendix A: Code
Appendix B:
Schematics
Appendix C: Parts
Listing
Appendix D:
Specific Tasks
References
Pictures
Xuemin Hang:
xh24@cornell.edu
Marcel Xu:
mx23@cornell.edu
| |
- Appendix A
-
- Audio Code
-
/**************AUDIO CODE FOR MUSIC SYNTHESIZER *****************/
-
#include <Mega32.h> //the chip
-
#include <stdio.h> //for debugging using printf, etc
-
#include <Math.h> // for sine function
-
- //
definitions
- #define
begin {
- #define
end }
-
- void
initialize(void); //to set up ports
- void
chordsPlay(void);
-
- //the
following must not be registers
- #pragma
regalloc-
-
unsigned long increment,increment2 ;
-
unsigned char r_char; //received char
-
unsigned int i, j; //index to sineTable and counter for
number of iterations in the assembly loop
-
unsigned char notes; //counter for number of notes played
simultaneously
- //flags
for modulating the wave envelope
-
unsigned char modulate, brass, count, instrumentcount, instrumentshift;
-
unsigned char sineTable[256] @0x300; //Table of values; need location to avoid
glitch
- #pragma
regalloc+
-
-
//**************************************************
- void
main(void)
- begin
-
initialize();
-
-
//main loop never exits
-
while(1)
- begin
-
chordsPlay(); //executes the pushbutton detection and music synthesis
- end
- end
-
//**********************************************************
- void
chordsPlay(void) //function that detects pushbuttons and activates the digital
music synthesis
- begin
-
if(brass==1){ //if the instrument requires waveform modulation
-
if(count<instrumentcount) count++; //increment counter when not
yet time for modulation
-
else{
-
if(modulate>instrumentshift) modulate=modulate>>1;
//shift in zeroes from the left
-
count=0; //reset counter
-
}
- }
-
else modulate=0xff; //if the instrument does not require waveform modulation
-
-
notes=0; //reset counter for notes
-
-
if(PINC.7==0){ // 493.883 Hz
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 20715;//frequency*41.94304
-
}
- }
-
if(PINC.6==0){ // 466.164 Hz---467
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 19552;//frequency*41.94304
-
}
-
else if(notes==1){//if one note played
-
notes=2; //two notes played
-
increment2 = 19552;//frequency*41.94304
-
}
- }
-
if(PINC.5==0){ // 440 Hz --441
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 18455;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 18455;//frequency*41.94304
-
}
- }
-
if(PINC.4==0){ // 415.305 Hz---416
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 17419;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 17419;//frequency*41.94304
- }
- }
-
f(PINC.3==0){ // 391.995 Hz ---390
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 16441;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 16441;//frequency*41.94304
- }
- }
-
if(PINC.2==0){ // 369.994 Hz ---370
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 15519;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 15519;//frequency*41.94304
-
}
- }
-
if(PINC.1==0){ //349.228 Hz ---350
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 14648;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 14648;//frequency*41.94304
- }
-
}
-
if(PINC.0==0){ // 329.628 Hz ---328
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment =13826;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 13826;//frequency*41.94304
-
}
- }
-
if(PINB.7==0){ // 311.127 Hz --- 310
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 13050;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 13050;//frequency*41.94304
-
}
- }
-
if(PINB.6==0){ //293.665 Hz --- 294
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 12317;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 12317;//frequency*41.94304
-
}
- }
-
if(PINB.5==0){ //277.183 Hz --- 277
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 11626;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 11626;//frequency*41.94304
-
}
- }
-
if(PINB.4==0){ //261.626 Hz --- 262
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 10973;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 10973;//frequency*41.94304
-
}
- }
-
if(PINB.3==0){ //246.942 Hz --- 247
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 10357;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 10357;//frequency*41.94304
-
}
- }
-
if(PINB.2==0){ //233.082 Hz --- 233
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 9776;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 9776;//frequency*41.94304
-
}
- }
-
if(PINB.1==0){ //220 Hz --- 220
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 9227;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 9227;//frequency*41.94304
-
}
- }
-
if(PINB.0==0){ //207.652 Hz --- 208
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 8710;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 8710;//frequency*41.94304
-
}
- }
-
if(PIND.7==0){ //195.998 Hz --- 196
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 8221;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 8221;//frequency*41.94304
-
}
- }
-
if(PIND.6==0){ //184.997 Hz --- 185
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 7759;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 7759;//frequency*41.94304
-
}
- }
-
if(PIND.5==0){ // 174.614 Hz --- 175
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 7324;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 7324;//frequency*41.94304
-
}
- }
-
if(PIND.4==0){ // 164.814 Hz --- 165
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 6913;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 6913;//frequency*41.94304
-
}
- }
-
if(PIND.3==0){ // 146.832Hz --- 147
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 6159;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 6159;//frequency*41.94304
-
}
- }
-
if(PIND.2==0){ // 130.813 Hz --- 131
-
if(notes==0){ //if no notes played yet
-
notes=1; //one note played
-
increment = 5487;//frequency*41.94304
-
}
-
else if(notes==1){ //if one note played
-
notes=2; //two notes played
-
increment2 = 5487;//frequency*41.94304
-
}
- }
-
-
if(notes==1) increment2=0;
-
if(notes==0) modulate=0xff;
-
-
if(notes>0) //one or more notes played
-
begin
-
#asm
-
;load the increment bytes into registers
-
lds r9, _increment
-
lds r10,_increment+1
-
lds r11, _increment+2
-
-
-
;load the increment bytes into registers
-
lds r3,
_increment2
-
lds r4,_increment2+1
-
lds r5, _increment2+2
-
-
;code with *** are responsible for modulating
the waveform
-
lds r29,
_modulate ;load the modulation flag into register
***
-
-
ldi R31, 0x3 ;high
byte of Z is always pointing to start of the sineTable
-
lds r26,_j ;load
int j into registers
-
lds r27,_j+1
-
-
Loop:
-
;40-cycle loop
-
add r12,
r9 ;accumulator = accumulator + increment;
-
adc r13,
r10 ;24-bit accumulator: r14 is highbyte1 (r14, r13,
r12)
-
adc r14,
r11 ;increment: r11 is highbyte1 (r11,r10,r9)
-
mov r30, r14
;put highbyte1 into address Z
-
ld r2, Z ;2
cycles (load sineTable[highbyte1] at address Z to register 2)
-
-
add r6,
r3 ;accumulator = accumulator + increment;
-
adc r7, r4 ;24-bit
accumulator: r8 is highbyte (r8, r7, r6)
-
adc r8, r5
;increment: r5 is highbyte2 (r5,r4,r3)
-
mov r30, r8 ;put
highbyte2 into address Z
-
ld r15, Z ;2
cycles (load sineTable[highbyte2] at address Z to register 15)
-
-
add r15,
r2 ;add the 2 contents together
-
-
sbrs r29,
0 ;skip if bit 0 is 0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29,
1 ;skip if bit 1 is 0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29,
2 ;skip if bit 2 is 0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29,
3 ;skip if bit 3=0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29,
4 ;skip if bit 4 =0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29,
5 ;skip if bit5=0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29, 6
;skip if bit6=0 ***
-
lsr
r15 ;shift right (/2) ***
-
-
sbrs r29, 7 ;skip
if bit7=0 ***
-
lsr r15
;shift right (/2)***
-
-
;PORTA = sineTable[highbyte1] +
sineTable[highbyte2]
-
out 0x1B,r15
-
-
ldi r28, 0
;put constants into registers
-
ldi r25, 1
;put constants into registers
-
add r26,
r25 ;j++;
-
adc r27, r28
-
-
-
cpi r26, low(0x07d0) ;1
cycle
-
ldi r28, high(0x07d0)
;1 cycle
-
cpc r27,
r28 ;1 cycle
-
brsh EndLoop
;while(j<2000) ( 1 cycle if false)
-
rjmp
Loop ;2 cycles else, repeat the loop
-
-
EndLoop:
-
-
#endasm
-
-
end
-
-
- end
-
//*************************************************************************
-
interrupt [USART_RXC] void usart_rec(void) //implements the menu commands from
the PC
- begin
-
r_char=UDR; // get a char
-
-
switch(r_char){ //command depends on the representative char
-
case 'd': //default
-
brass=0;
-
for(i=0;i<256;i++) sineTable[i]=64+(char)(63.5*sin(6.283*((float)i)/256.0));
-
break;
-
-
-
//WOODWINDS
-
-
case 'c': //clarinet sound ....very good (clarinet and bass
clarinet) ----------- DEMO
-
brass=0;
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((19.01
*sin(6.283*((float)i)/256.0)) + (0.76 *sin(2*6.283*((float)i)/256.0))+
(18.82*sin(3*6.283*((float)i)/256.0)) + (2.28*sin(4*6.283*((float)i)/256.0)) +
(10.08*sin(5*6.283*((float)i)/256.0)) + (2.09 *sin(6*6.283*((float)i)/256.0))+
(4.94*sin(7*6.283*((float)i)/256.0)) + (0.95 *sin(8*6.283*((float)i)/256.0))+(4.56*sin(9*6.283*((float)i)/256.0)));
-
break;
-
-
case 'f': //flute sound
-
brass=0;
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((29.81
*sin(6.283*((float)i)/256.0)) + (23.95*sin(2*6.283*((float)i)/256.0)) +
(5.37*sin(3*6.283*((float)i)/256.0)) + (3.28*sin(4*6.283*((float)i)/256.0)) +
(1.49*sin(5*6.283*((float)i)/256.0)) + (0.596*sin(6*6.283*((float)i)/256.0)));
-
break;
-
-
case 'p': //piccolo
-
brass=0;
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((29.81
*sin(2*6.283*((float)i)/256.0)) + (23.95*sin(4*6.283*((float)i)/256.0)) +
(5.37*sin(6*6.283*((float)i)/256.0)) + (3.28*sin(8*6.283*((float)i)/256.0)) +
(1.49*sin(10*6.283*((float)i)/256.0)) + (0.596*sin(12*6.283*((float)i)/256.0)));
-
break;
-
-
case 'o': //oboe sound
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((3.01*sin(6.283*((float)i)/256.0))
+ (11.14*sin(2*6.283*((float)i)/256.0))+ (10.08*sin(3*6.283*((float)i)/256.0)) +
(17.33*sin(4*6.283*((float)i)/256.0)) + (9.905*sin(5*6.283*((float)i)/256.0)) +
(6.72*sin(6*6.283*((float)i)/256.0))+ (3.36*sin(7*6.283*((float)i)/256.0))+
(0.0884*sin(8*6.283*((float)i)/256.0)) + (0.531*sin(9*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=40;
-
instrumentshift=0x7f;
-
break;
-
-
-
//BRASS
-
-
case 'h': //horn long sound (good for lower octave)
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((24.8
*sin(6.283*((float)i)/256.0)) + (22.076*sin(2*6.283*((float)i)/256.0))+
(12.4*sin(3*6.283*((float)i)/256.0)) + (3.72*sin(4*6.283*((float)i)/256.0)) +
(0.248*sin(5*6.283*((float)i)/256.0)) + (0.248*sin(8*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=50;
-
instrumentshift=0x7f;
-
break;
-
-
case 'i': //horn bounce sound (good for lower octave)
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((24.8
*sin(6.283*((float)i)/256.0)) + (22.076*sin(2*6.283*((float)i)/256.0))+
(12.4*sin(3*6.283*((float)i)/256.0)) + (3.72*sin(4*6.283*((float)i)/256.0)) +
(0.248*sin(5*6.283*((float)i)/256.0)) + (0.248*sin(8*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=30;
-
instrumentshift=0;
-
break;
-
-
case 't': //trombone long sound (good for lower octave)
----------- DEMO
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((4.12*sin(6.283*((float)i)/256.0))
+ (19.42*sin(2*6.283*((float)i)/256.0))+ (37.35*sin(3*6.283*((float)i)/256.0)) +
(0.374*sin(4*6.283*((float)i)/256.0)) + (1.494*sin(5*6.283*((float)i)/256.0)) +
(0.747*sin(6*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=45;
-
instrumentshift=0x7f;
-
break;
-
-
case 'u': //trombone bounce sound (good for lower octave)
----------- DEMO
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((4.12*sin(6.283*((float)i)/256.0))
+ (19.42*sin(2*6.283*((float)i)/256.0))+ (37.35*sin(3*6.283*((float)i)/256.0)) +
(0.374*sin(4*6.283*((float)i)/256.0)) + (1.494*sin(5*6.283*((float)i)/256.0)) +
(0.747*sin(6*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=30;
-
instrumentshift=0x0;
-
break;
-
-
case 'r': //trumpet long sound
-
for(i=0;i<256;i++) sineTable[i]=(char)(0.5*i);
-
brass=1;
-
instrumentcount=20;
-
instrumentshift=0x7f;
-
break;
-
-
case 's': //trumpet bouncesound
-
for(i=0;i<256;i++) sineTable[i]=(char)(0.5*i);
-
brass=1;
-
instrumentcount=20;
-
instrumentshift=0;
-
break;
-
-
-
//STRINGS
-
-
case 'z': //guitar (plucked string) ----------- DEMO
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((4.12*sin(2*6.283*((float)i)/256.0))
+ (20.1*sin(4*6.283*((float)i)/256.0))+ (37.35*sin(6*6.283*((float)i)/256.0)) +
(0.374*sin(8*6.283*((float)i)/256.0)) + (1.494*sin(10*6.283*((float)i)/256.0))
);
-
brass=1;
-
instrumentcount=15;
-
instrumentshift=0;
-
break;
-
-
//PERCUSSION
-
-
case 'y': //steel drum
-
for(i=0;i<256;i++) sineTable[i]=64+(char)((sin(6.283*((float)i)/256.0))
+ (19.42*sin(2*6.283*((float)i)/256.0))+ (37.35*sin(3*6.283*((float)i)/256.0)));
-
brass=1;
-
instrumentcount=8;
-
instrumentshift=0x0;
-
break;
-
-
- }
- end
-
//**********************************************************
- //Set
it all up
- void
initialize(void)
- begin
- UCSRB
= 0x98 ;//enable RxC,Rx,Tx
- UBRRL
= 103 ; //using a 16 MHz crystal (9600)
-
- //set
up the ports
- DDRD=0x00;
// PORT D is an input with pullup
- PORTD=0xff;
- DDRB=0x00;
// PORT B is an input with pullup
- PORTB=0xff;
- DDRC=0x00;
// PORT C is an input with pullup
- PORTC=0xff;
-
- DDRA=0xff;
// PORT A is an output
- PORTA=0;
-
-
//make sine table
- for(i=0;i<256;i++)
sineTable[i]=64+(char)(63.5*sin(6.283*((float)i)/256.0));
-
-
//init the flags
-
increment = 0;
-
increment2=0;
-
-
notes=0;
- j=1;
-
modulate=0xff;
-
brass=1;
-
count=0;
-
instrumentcount=0;
-
instrumentshift=0xff;
-
-
//crank up the ISRs
- #asm
-
sei
-
clr r14
-
clr r13
-
clr r12
-
clr r6
-
clr r7
-
|