Csound Csound-dev Csound-tekno Search About

[Csnd] interesting SOLA timeScale quick pitch shifting Issues

Date2013-04-21 22:03
Fromzohar argaman
Subject[Csnd] interesting SOLA timeScale quick pitch shifting Issues
AttachmentsNone  None  

Date2013-04-22 00:10
Fromzohar argaman
Subject[Csnd] Re: interesting SOLA timeScale quick pitch shifting Issues
AttachmentsNone  None  

Date2013-04-22 00:42
Fromzohar argaman
Subject[Csnd] Re: interesting SOLA timeScale quick pitch shifting Issues
AttachmentsNone  None  

Date2013-04-23 13:17
Fromjoachim heintz
SubjectRe: [Csnd] Re: interesting SOLA timeScale quick pitch shifting Issues
perhaps you could try ptablei instead of tablei?


Am 22.04.2013 01:42, schrieb zohar argaman:
> i thought of using tablei warp function, but i need the length of the
> table to be a specific not-power-of-2 size. and ftgen of GEN01 is giving
> me an error when inputing a non 2^x size. maybe i can workaround by
> writing the sample index by index, but this seems too much. will it
> work? or maybe there is an easier way?
>
> On Monday, April 22, 2013 at 8:10 AM, zohar argaman wrote:
>
>> after figuring a mistake in ftgen normalisation (should be -1) I'm
>> getting sound and i just need to get the phasor mechanism working.
>> changing the value of the linsey beginning point do not work as
>> expected, if i ask to begin at the value of 1 I'm getting a short
>> squeeki version of my sample. this is obviously not suppose to happen
>> when only one sample offset is set. any ideas?
>>
>> 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 SOLA
>>> http://www.csounds.com/ezine/spring2000/processing/
>>> I 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
>>> 
>>> ;---------------------------------------------------------------
>>> ; Pitch and Time Scaling
>>> ;---------------------------------------------------------------
>>>        instr    11
>>>
>>> idur   =        p3       ; Duration
>>> iamp   =        p4       ; Amplitude ;1
>>> ipshft =        p5       ; Pitch scaling factor
>>> itstr  =        p6       ; Time scaling factor
>>> iaph   =        p7*sr    ; Amplitude of the phasor in seconds
>>> converted to samples ;.1
>>> itab   =        p8       ; Sample
>>> ismth  =        p9       ; Smoothing factor ;2
>>>
>>> ipval  =        (ipshft-1)                ; Setup for pitch shifting
>>> ifph   =        sr/iaph*((itstr-1)/itstr + ipval) ; Frequency for phasor
>>>
>>> prints "P-Coef:%f ipval:%f, ifph:%f%R%R",ipshft,ipval,ifph
>>>
>>> aphas1 phasor   ifph                      ; Phasor 1
>>> aphas2 phasor   ifph, .5                  ; Phasor 2 shifted by 180
>>> degrees
>>> apos   linseg   0, idur, idur/itstr*sr    ; Scan this many samples of
>>> the table.
>>>
>>> kph1 downsamp aphas1
>>> kph2 downsamp aphas2
>>> printks "kph1:%f kph2:%f%R",0.1,kph1,kph2
>>>
>>>
>>> kdclk1 oscil    1, ifph, 1                ; Declick envelope matches
>>> phasor frequency
>>> kdclk2 oscil    1, ifph, 1, .5            ; Another one shifted by
>>> 180 degrees
>>>
>>> kdclk1 =        (tanh(kdclk1*ismth)+1)*.5 ; Flatten the sine waves
>>> and offset
>>> kdclk2 =        (tanh(kdclk2*ismth)+1)*.5 ; Same for other stream
>>>
>>>
>>> ashft1 table3   iaph*aphas1+apos, itab    ; Scan the table with cubic
>>> interpolation
>>> ashft2 table3   iaph*aphas2+apos, itab    ; second stream
>>>
>>> aout   =        ashft1*kdclk1 + ashft2*kdclk2 ; Combine the two
>>> streams with declicking
>>>
>>>        outs     aout*iamp, aout*iamp      ; Output the result
>>>
>>>        endin
>>>
>>> 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:
>>> ,
>>> 
>>> 
>>> 
>>>
>>>
>>> sr =44100
>>> ksmps = 64
>>> nchnls = 2
>>>
>>> ;vocal sample
>>> #define Filename #vocal_sample.aif#
>>>
>>>
>>>
>>> instr Init
>>> ;Calculate important global vars and load FT
>>> giproperLen filelen "$Filename"
>>> giftsnd     ftgen  0, 0, 2^(inbase), 1, "$Filename", 0, 0, 1
>>> giftlen =ftlen(giftsnd)
>>> endin
>>>
>>> ;---------------------------------------------------------------
>>> ; Pitch and Time Scaling - modified to play loop and support initial
>>> samp offset
>>> ;TIME STRETCH - DISABLED
>>> ;---------------------------------------------------------------
>>>        instr    SOLA
>>>
>>> idur   =        p3       ; Duration
>>> iamp   =        p4       ; Amplitude ;1
>>> inote =        p5       ; note- convert to Pitch scaling factor
>>> itstr  =        p6       ; Time scaling factor
>>> iaph   =        p7*sr    ; Amplitude of the phasor in seconds
>>> converted to samples ;.1
>>> itab   =        p8       ; Sample
>>> ismth  =        p9       ; Smoothing factor ;2
>>> ilenSamp =p11;length of loop in samples
>>>
>>> knote =k(p5)
>>> ;scale factor
>>> kpshft = knote/gkAMDFcps
>>>
>>>
>>> reinit PhsDeter ;extract phase from phasor and store it while a note
>>> is played
>>> PhsDeter:
>>>     iSampOffset = int(i(gkeepPhs)*sr)
>>> rireturn
>>>
>>> printks "knote:%d kpshft:%f iSampOffset%f
>>> gkPhs:%f%R",0.1,knote,kpshft,iSampOffset,gkeepPhs
>>>
>>> kpval  =        (kpshft-1)                ; Setup for pitch shifting
>>> gkfph   =        sr/iaph*(kpval) ; Frequency for phasor
>>>
>>> aphas1 phasor   gkfph                      ; Phasor 1
>>> aphas2 phasor   gkfph, .5                  ; Phasor 2 shifted by 180
>>> degrees
>>> apos   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 interpolation
>>> gashft2 table3   (iaph*aphas2+apos+iSampOffset)%ilenSamp, itab    ;
>>> second stream
>>> krms rms gashft1
>>> outvalue "rms", krms
>>>        endin
>>>
>>> ;Notes - No Live Input, Orchestrated :(
>>> instr 1
>>> ivel = p5
>>> a1 subinstr "SOLA" ,1 ,p4,1,0.1,giftsnd,2,1,giproperLen*sr
>>> endin
>>>
>>> ;delay vocal until sample will hit the beat
>>> instr Setup
>>> event "i", "Process",0 , 65
>>> turnoff
>>> endin
>>> instr Process
>>> ;Read loop
>>> a1 lposcil 0dbfs, 1,0,giproperLen*sr, giftsnd
>>> ;Start Phasor to keep track with pitch, reset every sample Length in
>>> seconds
>>> gkeepPhs phasor 1/giproperLen
>>>
>>> ;AMDF PDA - send global to instr SOLA
>>> gkAMDFcps, krms pitchamdf a1, 50, 700 ,130
>>>
>>> ;fade mini-samples of SOLA
>>> kdclk1 oscil    1, gkfph, 1                ; Declick envelope matches
>>> phasor frequency
>>> kdclk2 oscil    1, gkfph, 1, .5            ; Another one shifted by
>>> 180 degrees
>>> iamp=1
>>> ismth=2
>>> kdclk1 =        (tanh(kdclk1*ismth)+1)*.5 ; Flatten the sine waves
>>> and offset
>>> kdclk2 =        (tanh(kdclk2*ismth)+1)*.5 ; Same for other stream
>>> aout   =        gashft1*kdclk1 + gashft2*kdclk2 ; Combine the two
>>> streams with declicking
>>>        outs     aout*iamp, aout*iamp      ; Output the result
>>> endin
>>>
>>> 
>>> 
>>>
>>> f 1 0 16384 10 1
>>>
>>> s
>>> i "Init" 0 1
>>> s
>>> f0 70
>>> i "Setup" 0 0.003
>>> i10.50362820146.828242120
>>>
>>> 
>>> 
>>> 
>>>
>>> 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.
>>
>

Date2013-05-06 01:34
Fromzohar argaman
SubjectRe: [Csnd] Re: interesting SOLA timeScale quick pitch shifting
AttachmentsNone  None