convolve

convolve — Convolves a signal and an impulse response.

Description

Output is the convolution of signal ain and the impulse response contained in ifilcod. If more than one output signal is supplied, each will be convolved with the same impulse response. Note that it is considerably more efficient to use one instance of the operator when processing a mono input to create stereo, or quad, outputs.

Note: this opcode can also be written as convle.

Syntax

ar1 [, ar2] [, ar3] [, ar4] convolve ain, ifilcod [, ichannel]

Initialization

ifilcod -- integer or character-string denoting an impulse response data file. An integer denotes the suffix of a file convolve.m; a character string (in double quotes) gives a filename, optionally a full pathname. If not a fullpath, the file is sought first in the current directory, then in the one given by the environment variable SADIR (if defined). The data file contains the Fourier transform of an impulse response. Memory usage depends on the size of the data file, which is read and held entirely in memory during computation, but which is shared by multiple calls.

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

Performance

ain -- input audio signal.

convolve implements Fast Convolution. The output of this operator is delayed with respect to the input. The following formulas should be used to calculate the delay:

  For (1/kr) <= IRdur:
          Delay = ceil(IRdur * kr) / kr
  For (1/kr) > IRdur: 
          Delay = IRdur * ceil(1/(kr*IRdur))
  Where:
          kr  = Csound control rate
          IRdur = duration, in seconds, of impulse response
          ceil(n) = smallest integer not smaller than n

One should be careful to also take into account the initial delay, if any, of the impulse response. For example, if an impulse response is created from a recording, the soundfile may not have the initial delay included. Thus, one should either ensure that the soundfile has the correct amount of zero padding at the start, or, preferably, compensate for this delay in the orchestra (the latter method is more efficient). To compensate for the delay in the orchestra, subtract the initial delay from the result calculated using the above formula(s), when calculating the required delay to introduce into the 'dry' audio path.

For typical applications, such as reverb, the delay will be in the order of 0.5 to 1.5 seconds, or even longer. This renders the current implementation unsuitable for real time applications. It could conceivably be used for real time filtering however, if the number of taps is small enough.

The author intends to create a higher-level operator at some stage, that would mix the wet & dry signals, using the correct amount of delay automatically.

Examples

Create frequency domain impulse response file using the cvanal utility:

csound -Ucvanal l1_44.wav l1_44.cv

Determine duration of impulse response. For high accuracy, determine the number of sample frames in the impulse response soundfile, and then compute the duration with:


duration = (sample frames)/(sample rate of soundfile)

This is due to the fact that the sndinfo utility only reports the duration to the nearest 10ms. If you have a utility that reports the duration to the required accuracy, then you can simply use the reported value directly.

sndinfo l1_44.wav


length = 60822 samples, sample rate = 44100
 
Duration = 60822/44100 = 1.379s.

Determine initial delay, if any, of impulse response. If the impulse response has not had the initial delay removed, then you can skip this step. If it has been removed, then the only way you will know the initial delay is if the information has been provided separately. For this example, let us assume that the initial delay is 60ms (0.06s)

Determine the required delay to apply to the dry signal, to align it with the convolved signal:


  If kr = 441:
        1/kr = 0.0023, which is <= IRdur (1.379s), so:
        Delay1  = ceil(IRdur * kr) / kr
                = ceil(608.14) / 441
                = 609/441
                = 1.38s


  Accounting for the initial delay:
        Delay2  = 0.06s
   Total delay  = delay1 - delay2
                = 1.38 - 0.06
                = 1.32s

Here is similar example of the convolve opcode. It uses the file convolve.csd.

Example 160. Example of the convolve opcode.

See the sections Real-time Audio and Command Line Flags for more information on using command line flags.

<CsoundSynthesizer>
<CsOptions>
; Select audio/midi flags here according to platform
-odac     ;;;RT audio out
;-iadc    ;;;uncomment -iadc if RT audio input is needed too
; For Non-realtime ouput leave only the line below:
;-o convolve.wav -W ;;; for file output any platform
</CsOptions>
<CsInstruments>
; NB: 'Small' reverbs often require a much higher percentage of wet signal to sound interesting. 'Large'
; reverbs seem require less. Experiment! The wet/dry mix is very important - a small change can make a large difference.

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

; by Menno Knevel - 2021

ires1 system_i 1,{{ cvanal rv_mono.wav rv_mono.con }}  ; analyze mono spring reverb
ires2 system_i 1,{{ cvanal rv_stereo.wav rv_stereo.con }} ; analyze stereo spring reverb

instr 1 

imix = 0.25	;wet/dry mix. Vary as desired.
ivol = .8 	;Overall volume level of reverb. Adjust to avoid clipping.

idel   filelen p4			;calculate length and number of channels of soundfile
ichnls filenchnls  p4
prints	"\n**this reverb file = %f seconds and has %d channel(s)**\n", idel, ichnls

if (ichnls == 1) then					; if mono
	adry    soundin "fox.wav"               ; input (dry) audio
	awet    convolve adry,"rv_mono.con"	; mono convolved (wet) audio
	awet1   diff    awet                    ; brighten sound
	awet2	=	awet1						; as it is a mono file played stereo
	adrydel delay   (1-imix)*adry, idel	; Delay dry signal to align it with convolved signal
else									; if stereo
	adry    soundin "fox.wav"               ; input (dry) audio
	awet1, awet2 convolve adry,"rv_stereo.con" ; stereo convolved (wet) audio
	awet1   diff    awet1                   ; brighten left sound
	awet2   diff    awet2                   ; and brighten right sound
	adrydel delay   (1-imix)*adry, idel     ; Delay dry signal to align it with convolved signal
endif
outs    ivol*(adrydel+imix*awet1),ivol*(adrydel+imix*awet2) ; Mix wet & dry signals

endin

</CsInstruments>
<CsScore>

i 1 0 4 "rv_mono.wav"
i 1 5 4 "rv_stereo.wav"
e
</CsScore>
</CsoundSynthesizer>


See also

Convolution and Morphing

Credits

Author: Greg Sullivan

1996

New in version 3.28