Question: import sys import os import math import pyaudio BITRATE=16000 TICKS_PER_SECOND=800. SPEEDFACTOR=3 PITCHFACTOR=2 MAXSIZE=1000000 microperiods = [ 0, 0, 0, 0, 0, 0, 0, 0, 0,

 import sys import os import math import pyaudio BITRATE=16000 TICKS_PER_SECOND=800. SPEEDFACTOR=3

PITCHFACTOR=2 MAXSIZE=1000000 microperiods = [ 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

import sys

import os

import math

import pyaudio

BITRATE=16000

TICKS_PER_SECOND=800.

SPEEDFACTOR=3

PITCHFACTOR=2

MAXSIZE=1000000

microperiods = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30578, 28861, 27242, 25713, 24270, 22909, 21622, 20409, 19263, 18182, 17161, 16198, 15289, 14436, 13621, 12856, 12135, 11454, 10811, 10205, 9632, 9091, 8581, 8099, 7645, 7218, 6811, 6428, 6068, 5727, 5406, 5103, 4816, 4546, 4291, 4050, 3823, 3609, 3406, 3214, 3034, 2864, 2703, 2552, 2408, 2273, 2146, 2025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

def getmidigram(fname):

notes=[]

os.system("midi2abc -midigram -f "+fname+" > midigram")

f=file("midigram").read().split(" ")

lastline=0

for line in f:

lsplit=line.split()

if(len(lsplit)

continue

if(int(lsplit[0])

break

notes.append([int(lsplit[0]),int(lsplit[1]),int(lsplit[4])])

lastline=int(line[0])

return notes

def gentones(midinotes):

# midinotes=midinotes[:10]

WAVDATA=''

for i in xrange(len(midinotes)):

note=midinotes[i]

length=note[1]-note[0]

length=length/TICKS_PER_SECOND

# freq=microperiods[note[2]]*1.0

if(microperiods[note[2]-12])!=0:

freq=1000000./microperiods[note[2]-12]

else:

freq=1

# print note[2],note[2]-12,microperiods[note[2]],freq,microperiods[69],1000000./microperiods[69]

# freq=440.

freq=freq*2

WAVDATA+=gentone(freq,length)

if(i

off=midinotes[i+1][0]

length=off-note[1]

length=length/TICKS_PER_SECOND

WAVDATA+=genemptytone(length)

return WAVDATA

def gentone(frequency,length):

if(frequency==0):

return genemptytone(length)

NOF=int(BITRATE*length)

REST=NOF%BITRATE

WAVEDATA=''

for x in xrange(NOF):

WAVEDATA+=chr(int(math.sin(x/((BITRATE/frequency)/(2*math.pi)))*127+128))

# for x in xrange(REST):

# WAVEDATA+=chr(128)

return WAVEDATA

def genemptytone(length):

NOF=int(BITRATE*length)

W=''

for x in xrange(NOF):

W+=chr(128)

return W

def playtone(wav):

PyAudio=pyaudio.PyAudio

p=PyAudio()

s=p.open(format=p.get_format_from_width(1),channels=1,rate=BITRATE,output=True)

s.write(wav)

s.stop_stream()

s.close()

p.terminate()

def genC(notes):

notestr="const int notes[] PROGMEM={"

time=notes[0][0]

durstr="const float durations[] PROGMEM={"

size=0

for n in notes:

if n[0]>time:

notestr+="0,"

durstr+=str(n[0]-time)+","

if microperiods[n[2]-12]!=0:

freq=1000000/microperiods[n[2]-12]

else:

freq=0

notestr+=str(freq*PITCHFACTOR)+","

durstr+=str((n[1]-n[0])*SPEEDFACTOR)+","

time=n[1]

size+=1

if size==MAXSIZE:

break

notestr+="}; "

durstr+="}; "

f=file("out.c","w")

f.write(notestr)

f.write(durstr)

numnotes=len(notes)

if numnotes>MAXSIZE:

numnotes=MAXSIZE

f.write( "const int NUMNOTES="+str(numnotes)+"; ")

f.close()

return

f.write( "const int notes[] PROGMEM={ ")

offset=notes[0][0]

for n in notes:

f.write(str(n[2]-12)+",")

f.write( "}; ")

f.write("const float durations[] PROGMEM={ ")

for n in notes:

f.write( "{"+str(n[0]-offset)+","+str(n[1]-offset)+","+str(n[2]-12)+"}, ")

f.write( "}; ")

f.write( "const int NUMNOTES="+str(len(notes))+"; ")

f.close()

def main(fname):

# os.system('play --null --channels 1 synth .2 sine 840')

# print "getting notes"

notes=getmidigram(fname)

genC(notes)

# print "generating waveform"

wav=gentones(notes)

# print "playing"

playtone(wav)

# print "done"

main(sys.argv[1])

int notes[] ={658,0,658,0,658,0,522,0,658,0,782,0,522,0,390,0,328,0,438,0,492,0,466,0,438,0,390,0,658,0,782,0,878,0,698,0,782,0,658,0,522,0,586,0,492,0,522,0,390,0,328,0,438,0,492,0,466,0,438,0,390,0,658,0,782,0,878,0,698,0,782,0,658,0,522,0,586,0,492,0,782,0,738,0,698,0,622,0,658,0,414,0,438,0,522,0,438,0,522,0,586,0,782,0,738,0,698,0,622,0,658,0,0,0,0,0,0,0,782,0,738,0,698,0,622,0,658,0,414,0,438,0,522,0,438,0,522,0,586,0,622,0,586,0,522,0,782,0,738,0,698,0,622,0,658,0,414,0,438,0,522,0,438,0,522,0,586,0,782,0,738,0,698,0,622,0,658,0,0,0,0,0,0,0,782,0,738,0,698,0,622,0,658,0,414,0,438,0,522,0,438,0,522,0,586,0,622,0,586,0,522,0,522,0,522,0,522,0,522,0,586,0,658,0,522,0,438,0,390,0,522,0,522,0,522,0,522,0,586,}; float durations[] ={240,40,240,160,240,160,240,40,240,160,240,880,240,280,240,280,240,280,240,160,240,160,240,40,240,160,240,80,240,80,240,80,240,160,240,40,240,160,240,160,240,40,240,40,240,280,240,280,240,280,240,280,240,160,240,160,240,40,240,160,240,80,240,80,240,80,240,160,240,40,240,160,240,160,240,40,240,40,240,520,240,40,240,40,240,40,240,160,240,160,240,40,240,40,240,160,240,40,240,40,240,280,240,40,240,40,240,40,240,160,240,160,240,160,240,40,240,640,240,40,240,40,240,40,240,160,240,160,240,40,240,40,240,160,240,40,240,40,240,280,240,280,240,280,240,1120,240,40,240,40,240,40,240,160,240,160,240,40,240,40,240,160,240,40,240,40,240,280,240,40,240,40,240,40,240,160,240,160,240,160,240,40,240,640,240,40,240,40,240,40,240,160,240,160,240,40,240,40,240,160,240,40,240,40,240,280,240,280,240,280,240,880,240,40,240,160,240,160,240,40,240,160,240,40,240,160,240,40,240,400,240,40,240,160,240,160,240,40,240,}; const int NUMNOTES=120;

v

Objective: Take musical notes extracted from a midi file and play them. Parts Arduino Uno Breadboard & wires Buzzer or speaker Construction Plug a buzzer into the breadboard. Connect the positive side of a buzzer to pin 13 and the negative side to ground. Step 1. Make a 440 Hz tone In loopO, make a 440 Hz tone. Do not use tone(), except to check your accuracy, but produce the note by cycling on and off pin 13. To maximise your accuracy, use direct writes to PORTB instead of calls to digital Write and use micros(), not delay. Play a sequence of tones Posted along with the assignment are several sample MIDI files, a Python script that extracts the first track and generates an array of notes and duration, and several C files containing music. Unless you wish to play other MIDI files, you will only need the C files in this project. Open mario.c and you will find two arrays and a size: const int notes[] = {658, 0,658, 0... const int durations[] = {80, 40, 80, 160,... const int NUMNOTES = 299; The notes are in Hz and the durations are in milliseconds. You should paste these variables at the beginning of your program. Step 2. Create a timer interrupt routine Using https://oscarliang.com/arduino-timer-and-interrupt-tutorial/ as a resource, set up timer 1 to produce an interrupt every millisecond. I recommend using the CTC mode output-compare match setting and a 64 prescalar. Create a function ISR(Timer/_COMPA_vect) that the timer will call every millisecond. Then set up the timer as follows: 1. call no Interrupts() to disable interrupts 2. clear the timer: set the three timer registers TCCR14, TCCRIB, TCNT1 to 0 3. choose a 3-bit prescalar (CS12, CSI1, CS10) and 4-bit counting mode (WGM13, WGM12, WGMII, WGM10): This is the bit meanings for timer register TCCRIB: TCCHI C1 CEST RW 0 WM WZ 1911 CUTE HW HW RW HW 0 0 0 . Here they are for timer register TCCRIA: ww COUT CONTACT FOR 9318 WONTO WONITOR HUW TW w W MW . . o We only care about the CS and WGM bits. The rest of them can stay 0 CS 2, 1, 0 specify a prescalar. This is will divide 16 MHz down to a smaller number. CS12 C811 CS10 0 0 0 Description No do source Counter stopped COLOM Norcaling) 0 0 + 0 1 0 cho From Diese 0 1 1 0/64 (From poscolor) 1 0 0 1 0 1 1 1 0 klo 25 (Promo) | CO1024 from prescaler) Exloo clock source on Tp Clock 01 talling ed Exdenal clock some on T1 pin Clock on thing oda 1 1 + Pick the three bit pattern for a prescalar of 64. Table 16-4 Woman den w WOMIT WORTO Trofeu de wat TOVI CTCPWPWM walion TOP OCRIS D . COFFEE IMAX + . 0 0 1 PW.Presse OFF TOF BOTTOM . PW OFF TOP BOTTOM + . . 1 PWP DOFF TOF BOTTOM 4 . 1 CTC OCHA MAX . 1 a 1 IWM. OFT BOTTOM TOP . PPWM OF SOTTON 7 1 1 PWM 1 OWOFF BOTTOM TO o 0 w IRI Com BOTTOM BOTTOM . 1 Com BOTTOM BOTTOM 10 10 0 We BOTTOM 11 0 1 PwCom OGRIATO BOTTOM + o CTC WAX 13 1 1 9 1 OM CRI BOTTOM TOP 15 + + FP Post PWM OCRIA BOTTOM TOP P. P. Om D WGM 3, 2, 1, 0 sets the timer mode as shown in the above table. We want a timer mode of CTC (clear timer on compare match). This means that it will count up from 0 until it hits our "compare number", interrupt, then reset and do it again. Pick the four bit patten for mode CTC. 4. Now, using the bit meanings, set TCCRIA and TCCRIB. Note that some of the mode bits fall in one register and some in the other. 5. Use the following formula to figure out OCRIA: 16000000 / 64 /OCRIA= 1000 solve for OCRIA and set it. 6. set TIMSK1 to (1

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!