For the Mathematica-Python translator beginner. This is
based on the Mathematica algorithm given in Tutorial
2.5, section 3.
See other notebook for alternatives (slightly more
complex, advanced)
import numpy as np
import pandas as pd
import re
import matplotlib.pyplot as plt
import sounddevice as sd # see conda install sounddevice instruction google
notes = ["D5", "D5", "E5", "D5", "G5", "F#5"
, "D5", "D5", "E5", "D5", "A5", "G5"];
notedur = 1/np.array([8, 16, 4, 4, 4, 2
, 8, 16, 4, 4, 4, 2])
tau = 0.4; beatdur = 2. ; srate = 11025;
tdur = notedur*beatdur; # actual time duration of each note
dt=1/srate
tdurarr=[np.arange(0,td,dt) for td in tdur]
datimp = pd.read_html("https://pages.mtu.edu/~suits/notefreqs.html");
freqdata=np.array(datimp[1])
freqdata=[list(u) for u in freqdata]
def getfreq(note,flist):
for fr in flist:
if re.search(note,str.replace(fr[0],' ','')):
f=fr[1];
break
else :
f=0 ;
return f
sndout=[]
for i in range(len(notes)):
freq=getfreq(notes[i],freqdata)
sndout=sndout+[np.exp(-t/tau)*np.sin(2*np.pi*freq*t) for t in tdurarr[i]]
sd.play(sndout,srate)
note that the code in cell above isn't exactly parallel with the Mathematica code, but quite similar in concept. An alternative code similar to Mathematica code - and can be used in more advanced version to play different instrumental sounds is below. Here, we get the frequency array, so that a play function can be defined, given any input frequency, duration, overtone characteristics, sampling rate etc. Then a simple sound list just play the play function. See Tutorial 2.5, section 3.2
freq=[getfreq(n,freqdata) for n in notes]
sndarr=[[np.exp(-t/tau)*np.sin(2*np.pi*freq[i]*t) for t in tdurarr[i]]
for i in range(len(freq))]
sndout=[]
for s in sndarr:
sndout=sndout+s
sd.play(sndout,srate)