A Phase Modulation example is presented.
Instead of using the function that was named add() in our csound module, it will be renamed as addTag(), to make its meaning clear. Further, there are checks to see if the first and last character are the angle brackets.
# moduleCsound.py from os import system from time import sleep L = [] startSyn,stopSyn='<CsoundSynthesizer>','</CsoundSynthesizer>' startOpt,stopOpt='<CsOptions>','</CsOptions>' startIns,stopIns='<CsInstruments>','</CsInstruments>' startSco,stopSco='<CsScore>','</CsScore>' def addTag(*b): """ Adding Tag terms to csd file """ for s in b: if s[0]!='<' or s[-1]!='>': raise Exception("AddTag only adds Tags") L.extend(b) return def rem(remark): """ Generates one line of comment """ L.append('; %s' % remark) def header(sr=44100,ksmps=10,nch=1,amp=1): """ Generates 4 headers in the orchesta section """ L.append('sr = %d' % sr) L.append('ksmps = %d' % ksmps) L.append('nchnls = %d' % nch) L.append('0dbfs = %d' % amp) return def instrument(rem,instr,S): """ Generates instrument code given a String in the orchestra section """ tL = S.split('\n') if tL[0]!='' or tL[-1]!='' : raise Exception("Instr Str") tL = [' '*2 + tl for tl in tL] tL[0] = 'instr %d' % instr # (3) tL[-1] = 'endin' if rem!='': L.append('; ' + rem) L.extend(tL) return def table(rem,tabNum,tabTime,tabSize,tabGEN,*tab): """ Generates f line inside score section """ tup = (tabNum,tabTime,tabSize,tabGEN) String = 'f %s %s %s %s' % tup LString1=[' ' + str(i) for i in tab] String1 = "".join(LString1) if rem!='': L.append('; ' + rem) L.append(String+String1) return def score(instr,start,dur,*p): """ Generates i line inside score section """ String = 'i %s %s %s' % (instr,start,dur) LString1=[' ' + str(pf) for pf in p] String1 = "".join(LString1) L.append(String+String1) return def writeRun(fname): """ Write out the csd file and perform it """ OutL=[Lu + '\n' for Lu in L] out = open('%s.csd' % fname,'w') out.writelines(OutL) out.close() sleep(1) cmd = 'csound -o %s.wav %s.csd' % (fname,fname) status=system(cmd) if status!=0: raise Exception ('Could not write wav file') return
This equation shows what we are trying to do. In the csound program we have to prefix each variable with the letter a to indicate that it is an audio rate variable. First y3 is found as the output of an oscil with a frequency of f3. Then y2p is found, as a sum of phasor, of frequency f2, and the signal y3. The variable y2p, is a phase term. Using the table opcode, y2p, is decoded, to y2. Finally yp is found, which is the sum of a phasor of frequency f1, and the signal y2. Finally we decode the yp with the table opcode to get the y output.
These steps are indicated in this Instrument String Template. There are 3 placeholders representing f3, f2 and f1. We have fixed the values of A, and B. After getting y, two envelopes are created for the left and right channels. There is a fast attack, and then the signal slowly decays, with fade-out, at the end.
The ten instruments are created such that f3 equals 5 Hz, f2 equals 20 Hz, and f1 is going from 2200 Hz to 1300 Hz in steps of minus 100 Hz. Python knows we have a multi-line statement if there is a starting delimiter such as square brackets, until it finds a matching closing delimiter. The indentation level of a multi-line statement is that of the line that started the delimiter.
Now the sine table is created and 10 scores are written, one for each instrument.
# PhaseEx.py from moduleCsound import * addTag(startSyn,startOpt,stopOpt,startIns) header(nch=2) # *** Instrument String Template *** PhaseExTemplate=""" ay3 oscil .5, %s, 1 ; f3 (B=.5) ay2p phasor %s ; f2 ay2p = ay2p + ay3 ay2 table ay2p, 1, 1, 0, 1 ay2 = ay2*2 ; A=2 ayp phasor %s; f1 ayp = ayp + ay2 ay table ayp, 1, 1, 0, 1 aenvL linseg 0,.01,.5,.19,.2,p3-.3,.2,.1,0 aenvR linseg 0,.01,.6,.19,.2,p3-.3,.2,.1,0 aL = ay*aenvL aR = ay*aenvR out aL, aR """ N = 10 PhaseExStr=[ PhaseExTemplate % (5,20,2200-100*i) for i in range(N)] for i in range(N): instrument('HaHa', i+1, PhaseExStr[i]) addTag(stopIns,startSco) # *** Table *** table('1. Sine wave',1,0,8192,10,1) # *** Score *** rem('Phase Mod Score') for i in range(N): score(i+1,0.4*i,0.4) addTag(stopSco,stopSyn) writeRun('Tut23')
The wav file shows the effect of the envelope.
This is the frequency spectrum of the first score using the first instrument.
You will find additional information at pythonaudio.blogspot.com, including the source code.
This is the video of Tutorial 23:
Thanks for sharing very informative blog..
ReplyDeletepython online training in hyderabad