| "Michael A. Thompson" wrote:
>
> Looking for a good compressor/limiter csound .orc. Anybody messed around
> with doing one?
Funny you should ask, I've been working on this lately.
csound has a "dam" opcode that's supposed to be a general-purpose
dynamics processor, but I can't get it to sound good.
Here's where I left off on my compressor instr. THe big difficulty
seems to be implementing "attack" and "decay" in ways that work like
an analog compressor, since it's rarely desirable to have a
compressor that works instantaneously all the time. This version
sort-of does the trick.
Next step is to add a threshold level and different ratios above/
below that level. Not sure how to do that yet. I had some good
exchanges with Paul Barton-Davis where we tried to figure out how
that worked; I think his idea of using an ftable to plot input level
vs. output gain might be the best approach, since it allows multiple
threshold levels and arbitrary dynamics curves.
instr 14 ; do everything in dB.
; Attack/release added using my by-hand linear slope
method.
; Let's see if I can make this work right with ratio (that
is,
; ratio of 1 "turns off" attack/release controls...)
; OK, this is getting there....
; EXTRACT & COMPRESS ENVELOPE
iratio = 1 / p4 ; p4 is "compression ratio" -- 4 means 4:1
ihp = 10 ; lopass filter freq for rms and gain
kenv expseg 1, p3 - .1, 32767, .1, 32767
kdclick linseg 0, .1, 1, p3 -.1, 1
asig, asig2 diskin "arms/salt_notice/nines.wav", 1 ; , 217
avg = (asig + asig2) * .5
krms_raw rms avg, ihp, 0
kdb_raw = 20 * log10(krms_raw + 1) ; + 1 to avoid divide by 0
kdb_comp = kdb_raw * iratio
ioffset = 72 - (72 * iratio) ; I thought it should be 90 d
; but that doesn't work right at high
; ratios.
; 70 catches peaks pretty well.
kdb_comp = kdb_comp + ioffset ; make-up gain.
kdiff = kdb_comp - kdb_raw ; difference
; SLOPE CONTROL (attack & release)
iattack = p6 ; MAX time for level to RISE 60 dB
irelease = p7 ; MIN time for level to DROP 60 dB
; Now we translate that into maximum diff. between
successive
; values of k-rate DIFFERENCE
imaxattd = (90 * iratio) / (kr * iattack ); "max. attack difference"
imaxreld = (90 * iratio) / (kr * irelease)
print iattack, imaxattd
print irelease, imaxreld
kdiff_old init 88
if (kdiff > kdiff_old) goto RELEASE
ATTACK:
; khalftime = iattack ; fast attack
; ; ; this works???
goto OUTPUT
RELEASE:
; This sort-of works...
if (kdiff_old + imaxreld) > kdiff goto OUTPUT
kdiff = kdiff_old + imaxreld
OUTPUT:
kdiff_old = kdiff ; store for next cycle
; FINAL OUTPUT GAIN CONTROL ...
kdb_comp = kdb_raw + kdiff ; construct final target gain
krms_comp = 10 ^ (kdb_comp / 20) ; convert back to rms.
aout1 gain asig, krms_comp, ihp, 1 ; set gain to match RMS
aout2 gain asig2, krms_comp, ihp, 1
; asig, rms, filter hz, initial (0=clear, 1 prevents clicks)
imakeup = p5 ; NOT USED
outs aout1, aout2
endin
;;;;;;;;;; here's a test sco.
; First uncompressed, then compressed with fast attack & release,
; then fast attack / slow release.
f1 0 1024 10 1 ; sine
;14 at dur ratio gain attack release
i14 1 6 1 1 .000001 .0001
i14 7.5 . 8 1 .000001 .00000001
i14 14 . 8 2 .000001 .5
---------------- paul winkler ------------------
slinkP arts: music, sound, illustration, design, etc.
email=========================slinkp AT ulster DOT net
ARMS online=======================http://reacharms.com
personal page===========http://www.ulster.net/~abigoo/ |