Friday 3 January 2014

Simple But Very Effective Envelope Compressor Patch

Further Experiments In Extreme Synthesis
Sometimes over engineering is a killer - strip something down and it works better.
I have worked a lot on compression (dynamic range compression) in Sonic Field. I have tried granular compression and wave limiting. These can be quite exciting things but they have not been as musical as I would like. It turns out that a simple 3 band envelope compressor is just the ticket.
This section splits the signal into three bands. The roll off does not need to be steep so I use Bessel filters to help avoid too great an amount of phase rotation:
{
    {(?signal ,200,2000,4)BesselBandPass}Do !signal-m 
    {(?signal     ,2000,4)BesselHighPass}Do !signal-h 
    {(?signal     , 200,4)BesselLowPass}Do  !signal-l 
    >signal-m !signal
    ?envelope-compress Do !signal-m
    >signal-h !signal
    ?envelope-compress Do !signal-h
    >signal-l !signal
    ?envelope-compress Do !signal-l
    (
        ({>signal-l pcnt+50}Do,10),
        ({>signal-m pcnt+30}Do,0),
        ({>signal-h pcnt+20}Do,0)
    )MixAt Normalise 
}!do-it 
On recombination I delay the bass a little which is a psychoacoustic trick to make the bass sound more present and sit better in the rest of the mix. Now - the usual number is around 2.5 ms but I am using 10 - the project does have the word 'extreme' in it.
Then the compressor it self uses an envelope generated from follow the signal in both the forward and reverse directions. This avoids 'pumping' due to note attacks. Pumping can be cool - it that is what you want. But when you need a sharp compression attack (think piano) and don't want everything to go quiet as a distinct dip after transients - the reverse trick is just great:
(
        {(?signal Reverse,1,50)Follow Reverse},
        {(?signal        ,1,50)Follow}
    )DoAll Mix !shape   
I do the compression twice. Once with the above sharp attack and slower decay then a second smoothing run which uses symmetrical attack and decay.
(
        {(?signal Normalise,25,25)Follow},
        {(?signal Normalise Reverse,25,25)Follow Reverse}
    )DoAll Mix !shape
And here is the whole thing.
{

    (1,?compress)- !offset
    (
        {(?signal Reverse,1,50)Follow Reverse},
        {(?signal        ,1,50)Follow}
    )DoAll Mix !shape   

    {(?shape,(1,?shape MaxValue)/)NumericVolume}Do          !shape
    {(?offset,(>shape, ?compress)NumericVolume)DirectMix}Do !shape
    {
        (
            >signal,
            >shape 
        )Divide Normalise
    }Do !signal 
    
    (
        {(?signal Normalise,25,25)Follow},
        {(?signal Normalise Reverse,25,25)Follow Reverse}
    )DoAll Mix !shape
    
    {(?shape,(1,?shape MaxValue)/)NumericVolume}Do          !shape
    {(?offset,(>shape, ?compress)NumericVolume)DirectMix}Do !shape
    
    {
        (
            >signal,
            >shape 
        )Divide Normalise
    }Do 
}!envelope-compress

{
    {(?signal ,200,2000,4)BesselBandPass}Do !signal-m 
    {(?signal     ,2000,4)BesselHighPass}Do !signal-h 
    {(?signal     , 200,4)BesselLowPass}Do  !signal-l 
    >signal-m !signal
    ?envelope-compress Do !signal-m
    >signal-h !signal
    ?envelope-compress Do !signal-h
    >signal-l !signal
    ?envelope-compress Do !signal-l
    (
        ({>signal-l pcnt+50}Do,10),
        ({>signal-m pcnt+30}Do,0),
        ({>signal-h pcnt+20}Do,0)
    )MixAt Normalise 
}!do-it 

"temp/input.wav" ReadFile ^left ^right

[
    As compression happens in two phases - 0.5 is actually
    a lot - more gets silly - 0.9 makes stuff sound all crunchy
    and old school.
]
0.5 !compress

>left  !signal
?do-it Do !left
>right !signal
?do-it Do !right

((>left Done,>right Done),"temp/done.wav")WriteFile32

To demonstrate, here are two pieces. The first does not use the compressor and the second does (at a setting of 0.5). The first has had some work done on the base to bring it out which was not needed on the second as the compressor did it.

No comments:

Post a Comment