Cabbage Logo
Back to Cabbage Site

Sample Rate Reduction not using Fold

Hi everybody,

Looking to write a sample rate reduction/downsampling opcode/effect. I have been messing with the ‘fold’ opcode for this purpose, and it sounds pretty good(or bad depending on your taste), but I am curious to see if there is any noticeable difference between that and a true downsample -> upsample, sample rate reducer. My processing with fold is this:

adsL fold aL, 44100 / kfold

Here, kfold Hz from 1 to 44100.

From some tests I have been doing, it looks as though a significant amount of high frequency content is still there after the signal is run through the ‘fold’ opcode, see the attached screen shot. My DSP knowledge is only so-so, but I would assume that there would not be any content above kfold / 2, or even kfold… I have tried a few SoX commands (both downsample and -r/rate) and it seems like there is a pretty steep lowpass filter prior to the rate reduction in both of those commands… that being said, it looks as though there is only minor high frequency leakage above the downsampled Nyquist…

So, I guess my question is: Is it possible to create an opcode that downsamples and then upsamples a given signal? From what I could tell this would require a modifiable local ksmps as the downsample opcode outputs a k signal… can we do this? I have seen some other forum posts that suggest changing the global ksmps after the program has started running may cause problems… Here is what I’ve got so far, but the setksmps opcode does not seem to do anything, changing the global ksmps does though, but not really what I am after…

aL inch 1
kfreq chnget “freq”
setksmps i(kfreq)

kdsL downsamp aL
ausL upsamp kdsL

outch 1, ausL

Any help and/or opinions is greatly appreciated, thanks!

Interesting question. So I guess you can dowsample using the downsamp opcode. And you can use setksmps to set the downsample factor. While you can’t change the local ksmps at runtime, you can can it freely at init time. setksmps will set the local ksmps, not the global one. Once you have downsampled it I you can simply pass it to a channel for sampling back to the audio rate? I don’t know. Check this example. Changing setksmps to 1 result in no folder, but change the size and hey presto - folder over?

instr 1
setksmps 32
kFreq line 0, 100, 1000
a1 oscili 1, kFreq
k1 downsamp a1
chnset a(k1), "down" 
endin

instr 2
a1 chnget "down"
outs a1, a1
endin

Rory,

Thanks for the quick response. I think I maybe asked the wrong question, it seems as though downsampling and upsampling works just fine(so long as the downsampling rate is set only once).

That being said, what I am really looking for is a way to assign the downsamp krate to a slider/variable input param, to get a variable true downsampled signal. Using the ‘fold’ opcode, I am able to modify the folderover, but I am really curious to see how a variable true downsample sounds/compares…

Can you REINIT the ksmps during runtime? Perhaps similar to this:

instr 1

    gkbypass	chnget	"bypass"

    aL                      inch 1
    aR                      inch 2

    	
    kdry	 	            chnget		"dry"
    kwet	 	            chnget		"wet"
    
    kfreq	                chnget		"freq"
    
    if changed(kfreq)==1 then
        reinit REINIT
    endif
    REINIT:
        setksmps i(kfreq)
    
    kdsL downsamp aL
    ausL upsamp kdsL 
    
    kdsR downsamp aR
    ausR upsamp kdsR 
    
    outch 1, ausL
    outch 2, ausR
endin

Thanks again,

also/PS - is there a markdown guide for cabbage forums?

Did it work with the reinit? I don’t see why it wouldn’t. You’re only changing the local ksmps, and not the global one… :thinking:

No,

There are a few error messages I’m getting in the console. It looks like local ksmps must be equal/less than global ksamps, so I have made global ksmps 44100. I have also typecast I(kfreq) to int. The local ksmps still don’t seem to be valid…

I’m getting the same problems here. Let’s see what the Csound community get back to you with. Maybe they have some answers…

Sounds good, thanks Rory :+1:

Rory,

Looks like ‘fold’ was the answer I was looking for, thanks for helping me work through it anyways. That being said, I did put together a mpulse and samphold version. I think it does that same thing, but it does delay the audio output by some amount of time… I won’t be using this, but it is noticeable… perhaps it is a side effect of the samphold opcode. Here is my instr if you want to try it out

instr 1

    gkbypass	chnget	"bypass"

    aL                      inch 1
    aR                      inch 2

    	
    kdry	 	            chnget		"dry"
    kwet	 	            chnget		"wet"
    
    kfreq	                chnget		"freq"
    
    aimp mpulse 1, 1 / kfreq
    
    adsL samphold aL, aimp
    adsR samphold aR, aimp
    
     
    if gkbypass == 0 then
        outch 1, (aL * kdry) + (adsL * kwet)
        outch 2, (aR * kdry) + (adsR * kwet)
    else
        outch 1, aL
        outch 2, aR
    endif
    
  
endin

thanks again!

1 Like