On Monday, April 22, 2013 at 6:03 AM, zohar argaman wrote:
Hi guys,first post for me. let me say, i love CSound!Hans Mikelson posted on CSound magazine this interesting Time Domain TimeScale algorithm based on SOLAI love his explanation and the sound is good, but i needed a dynamic pitch shifting, that is, one that can change pitch in k-rate, i messed around with his code but i made more mess than i can cleanup, so i need your help.this is Mikelson's version. very clear and neat<raw>;---------------------------------------------------------------; Pitch and Time Scaling;---------------------------------------------------------------instr 11idur = p3 ; Durationiamp = p4 ; Amplitude ;1ipshft = p5 ; Pitch scaling factoritstr = p6 ; Time scaling factoriaph = p7*sr ; Amplitude of the phasor in seconds converted to samples ;.1itab = p8 ; Sampleismth = p9 ; Smoothing factor ;2ipval = (ipshft-1) ; Setup for pitch shiftingifph = sr/iaph*((itstr-1)/itstr + ipval) ; Frequency for phasorprints "P-Coef:%f ipval:%f, ifph:%f%R%R",ipshft,ipval,ifphaphas1 phasor ifph ; Phasor 1aphas2 phasor ifph, .5 ; Phasor 2 shifted by 180 degreesapos linseg 0, idur, idur/itstr*sr ; Scan this many samples of the table.kph1 downsamp aphas1kph2 downsamp aphas2printks "kph1:%f kph2:%f%R",0.1,kph1,kph2kdclk1 oscil 1, ifph, 1 ; Declick envelope matches phasor frequencykdclk2 oscil 1, ifph, 1, .5 ; Another one shifted by 180 degreeskdclk1 = (tanh(kdclk1*ismth)+1)*.5 ; Flatten the sine waves and offsetkdclk2 = (tanh(kdclk2*ismth)+1)*.5 ; Same for other streamashft1 table3 iaph*aphas1+apos, itab ; Scan the table with cubic interpolationashft2 table3 iaph*aphas2+apos, itab ; second streamaout = ashft1*kdclk1 + ashft2*kdclk2 ; Combine the two streams with declickingouts aout*iamp, aout*iamp ; Output the resultendin</raw>now, how would you make a auto-tuner out of this?youll have to have a pitch detection algorithm (PDA) and the complicated thing is i want to scale a sample that runs in a loop, so... this is my code with event flow at the bottom:<raw>,<CsoundSynthesizer><CsOptions></CsOptions><CsInstruments>sr =44100ksmps = 64nchnls = 2;vocal sample#define Filename #vocal_sample.aif#instr Init;Calculate important global vars and load FTgiproperLen filelen "$Filename"giftsnd ftgen 0, 0, 2^(inbase), 1, "$Filename", 0, 0, 1giftlen =ftlen(giftsnd)endin;---------------------------------------------------------------; Pitch and Time Scaling - modified to play loop and support initial samp offset;TIME STRETCH - DISABLED;---------------------------------------------------------------instr SOLAidur = p3 ; Durationiamp = p4 ; Amplitude ;1inote = p5 ; note- convert to Pitch scaling factoritstr = p6 ; Time scaling factoriaph = p7*sr ; Amplitude of the phasor in seconds converted to samples ;.1itab = p8 ; Sampleismth = p9 ; Smoothing factor ;2ilenSamp = p11 ;length of loop in samplesknote =k(p5);scale factorkpshft = knote/gkAMDFcpsreinit PhsDeter ;extract phase from phasor and store it while a note is playedPhsDeter:iSampOffset = int(i(gkeepPhs)*sr)rireturnprintks "knote:%d kpshft:%f iSampOffset%f gkPhs:%f%R",0.1,knote,kpshft,iSampOffset,gkeepPhskpval = (kpshft-1) ; Setup for pitch shiftinggkfph = sr/iaph*(kpval) ; Frequency for phasoraphas1 phasor gkfph ; Phasor 1aphas2 phasor gkfph, .5 ; Phasor 2 shifted by 180 degreesapos linseg 0, idur, idur*sr ; Scan this many samples of the table.gashft1 table3 (iaph*aphas1+apos+iSampOffset)%ilenSamp, itab ; Scan the table with cubic interpolationgashft2 table3 (iaph*aphas2+apos+iSampOffset)%ilenSamp, itab ; second streamkrms rms gashft1outvalue "rms", krmsendin;Notes - No Live Input, Orchestrated :(instr 1ivel = p5a1 subinstr "SOLA" ,1 ,p4,1,0.1,giftsnd,2,1,giproperLen*srendin;delay vocal until sample will hit the beatinstr Setupevent "i", "Process",0 , 65turnoffendininstr Process;Read loopa1 lposcil 0dbfs, 1,0,giproperLen*sr, giftsnd;Start Phasor to keep track with pitch, reset every sample Length in secondsgkeepPhs phasor 1/giproperLen;AMDF PDA - send global to instr SOLAgkAMDFcps, krms pitchamdf a1, 50, 700 ,130;fade mini-samples of SOLAkdclk1 oscil 1, gkfph, 1 ; Declick envelope matches phasor frequencykdclk2 oscil 1, gkfph, 1, .5 ; Another one shifted by 180 degreesiamp=1ismth=2kdclk1 = (tanh(kdclk1*ismth)+1)*.5 ; Flatten the sine waves and offsetkdclk2 = (tanh(kdclk2*ismth)+1)*.5 ; Same for other streamaout = gashft1*kdclk1 + gashft2*kdclk2 ; Combine the two streams with declickingouts aout*iamp, aout*iamp ; Output the resultendin</CsInstruments><CsScore>f 1 0 16384 10 1si "Init" 0 1sf0 70i "Setup" 0 0.003i1 0.503628 20 146.828242 120</CsScore></CsoundSynthesizer></raw>it became kind of global variable - p-rate nightmare ;/the Init method initialize any global variable so the compiler wont be angry.setup initializes the Process instrument that runs as the Always On instr while performance.Pseudo Midi given by the note in i1.i1 trigger the SOLA instr.the SOLA instr takes global params from Process like the pitch of the current k-frame, and creates global signal gashft1 that is picked up by Process and mixes with the fade mechanism and heads out.the original sound is a loop, since its beeing read by a table3 opcode, i used a phasor to keep track of where is the pointer of the sample should be on the table. the thing is, that phasor must stop running when activating a note on SOLA, so the reinit section was added with hope to solve this.now, what is the problem? simple, no sound!i tried measuring rms of the ga coming out of SOLA, it measured 0.2 RMS. that's wierd. im i reading the table wrong? what can cause this behavior? how is best to debug this? what tools to use? is this idea possible anyway?thanks to all readers and answerers.