pconvolve

convolve — Convolution based on a uniformly partitioned overlap-save algorithm

Description

Convolution based on a uniformly partitioned overlap-save algorithm. Compared to the convolve opcode, 'pconvolve' has these benefits:

  • small delay

  • possible to run in real-time for shorter impulse files

  • no pre-process analysis pass

  • can often render faster than convolve

Syntax

ar1 [, ar2] [, ar3] [, ar4] pconvolve ain, ifilcod [, ipartitionsize, ichannel]

Initialization

ifilcod -- integer or character-string denoting an impulse response soundfile. multichannel files are supported, the file must have the same sample-rate as the orc. [Note: cvanal files cannot be used!] Keep in mind that longer files require more calculation time [and probably larger partition sizes and more latency]. At current processor speeds, files longer than a few seconds may not render in real-time.

ipartitionsize (optional, defaults to the output buffersize [-b]) -- the size in samples of each partition of the impulse file. This is the parameter that needs tweaking for best performance depending on the impulse file size. Generally, a small size means smaller latency but more computation time. If you specify a value that is not a power-of-2 the opcode will find the next power-of-2 greater and use that as the actual partition size.

ichannel (optional) -- which channel to use from the impulse response data file.

Performance

ain -- input audio signal.

The overall latency of the opcode can be calculated as such [assuming ipartitionsize is a power of 2]

    ilatency = (ksmps < ipartitionsize ? ipartitionsize + ksmps : ipartitionsize)/sr
    

Examples

Instrument 1 shows an example of real-time convolution.

Instrument 2 shows how to do file-based convolution with a 'look ahead' method to remove all delay.

[Note] NOTE

You will need to download the impulse response files from noisevault.com or replace the filenames with your own impulse files

        sr = 44100
        ksmps = 100
        nchnls = 2


        instr   1
kmix = .5    ; Wet/dry mix. Vary as desired.
kvol = .5*kmix    ; Overall volume level of reverb. May need to adjust
                    ; when wet/dry mix is changed, to avoid clipping.

; do some safety checking to make sure we the parameters a good
kmix = (kmix < 0  || kmix > 1 ? .5 : kmix)
kvol = (kvol < 0 ? 0 : .5*kvol*kmix)

; size of each convolution partion -- for best performance, this parameter needs to be tweaked
ipartitionsize = p4

; calculate latency of pconvolve opcode
idel    = (ksmps < ipartitionsize ? ipartitionsize + ksmps : ipartitionsize)/sr
prints "Convolving with a latency of %f seconds%n", idel

; actual processing
al, ar    ins

awetl, awetr pconvolve    kvol*(al+ar), "Mercedes-van.wav", ipartitionsize

; Delay dry signal, to align it with the convoled sig
adryl        delay  (1-kmix)*al, idel
adryr        delay   (1-kmix)*ar, idel

    outs    adryl+awetl, adryr+awetr

    endin




        instr   2
imix = 0.5         ; Wet/dry mix. Vary as desired.
ivol = .5*imix    ; Overall volume level of reverb. May need to adjust
                ; when wet/dry mix is changed, to avoid clipping.

ipartitionsize =    32768    ; size of each convolution partion
idel    = (ksmps < ipartitionsize ? ipartitionsize + ksmps : ipartitionsize)/sr    ; latency of pconvolve opcode

kcount init idel*kr

; since we are using a soundin [instead of ins] we can
; do a kind of "look ahead" by looping during one k-pass
; without output, creating zero-latency

loop:
    al, ar    soundin "John_Cage_1.aif", 0

    awetl, awetr pconvolve ivol*(al+ar),"FactoryHall.aif", ipartitionsize

    adryl        delay  (1-imix)*al,idel  ; Delay dry signal, to align it with
    adryr        delay   (1-imix)*ar,idel  ;

    kcount = kcount - 1
if kcount > 0 kgoto loop

        outs    awetl+adryl, awetr+adryr

        endin
        

See also

convolve, dconv.

Credits

Author: Matt Ingalls
2004