Tuesday, 18 December 2012

Sonic Field On Sound Cloud

Here are some Sound Cloud tracks created by Sonic Field (newest at top):


Friday, 7 December 2012

New Version Of Sonic Field: 0.2.1

Here is the latest drop:

http://www.sonicfield.co.uk/downloads/SonicField-0-2-1.zip

I have expedited this this minor number release to make the new dynamic range compression patches I have been talking about recently available to everyone. The front page of sonicfield.co.uk has been amended so the download link points to the new version.


Version 0.2.1
=============

This version (0.2.1) of Sonic Field has many enhancements including but not limited to:
1)  Wave limiting and wave maximizing
2)  Automatic reading in a swapped out signals
3)  Enhanced granular system with bounded random grain size
4)  Performance enhancements in the Do engine
5)  Performance enhancements in the parallelisation drier
6)  More accurate line number reporting in errors
7)  Many minor tweaks
8)  Addition of youtube-voice.sfp single task sfp file
9)  Performance counters are working again
10) Work on granular compression in revoice patchs.


Previous version (0.2) of Sonic Field has many enhancements including but not limited to:
1)  Granular synthesis
2)  RBJ IIR Filers (high,low,high-shelf,low-shelf,peaking)
3)  Cleaner implementation of resonance synthesis
4)  Better error handling - fix the line number bug
5)  System hang on error in paralleliser bug fixed
6)  Envelope follower.
7)  Fix to numerous bugs in shaped filters
8)  Addition of shaped butterworth and bessel bandpass filters
9)  Improved FM signal modulation and addition of fm signal generator
10) Addition of shaped power


Thursday, 6 December 2012

Compression-102: Loudness Wars And Extreme Compression

Compression 102, how do we  boost loudness via dynamic range compression to catch people's attention. 

This is not about making audio sound better; it is about making it sound more striking. It is about capturing people's attention and hooking them into a radio program, or the background in a music store. It is about making sales of music, or in advert breaks. This is a fascinating area, though it is important to realise that we are not attempting to make stuff sound better in a classic sense, just louder.

Here is the video - I have put the compression patch used at the bottom of this post:

http://youtu.be/l_75rzdaxkg


Remember! This code is AGPL 3.0



"temp/step-1.wav" ReadFile ^left ^right
{
    (
        (?signal Reverse,1,50)Follow Reverse,
        (?signal        ,1,50)Follow,
    )Mix !shape    
    (?shape,(2,?shape MaxValue)/)NumericVolume   !shape
    (0.04,>shape)DirectMix Clip                  !shape
    (>signal,?shape)Multiply Normalise           !signal
    
    (
        (?signal Normalise,25,25)Follow,
        (?signal Normalise Reverse,25,25)Follow Reverse,
    )Mix !shape
    (?shape,(1,?shape MaxValue)/)NumericVolume !shape
    (0.3,>shape dbs+24)DirectMix               !shape
    (
        >signal,
        >shape 
    )Divide Normalise !signal 
}!envelope-compress

(?left ,2000,6)BesselHighPass         !signal-h 
(?left ,2000,6)BesselLowPass          !signal 
(>signal,150,1,3)RBJPeaking           !signal
?envelope-compress Invoke
(
    (30 Silence,(>signal dbs+6 WaveLimit,2000,6)BesselLowPass)Concatenate,
    >signal-h dbs+6 WaveLimit 
)Mix Normalise dbs+3 WaveLimit !left-new


(?right,2000,6)BesselHighPass         !signal-h 
(?right,2000,6)BesselLowPass          !signal 
(>signal,150,1,3)RBJPeaking           !signal
?envelope-compress Invoke
(
    (30 Silence,(>signal dbs+6 WaveLimit,2000,6)BesselLowPass)Concatenate,
    >signal-h dbs+6 WaveLimit
)Mix Normalise  dbs+3 WaveLimit !right-new

((>left-new,>right-new)StereoMonitor,"temp/tone.wav")WriteFile32

Wednesday, 5 December 2012

Compression 101

I have recently put up a video introducing the basics of audio compression (dynamic range compression) for voice:



The patch used in this video is this one (remember AGPL):



2 SetSwapLimit
"temp/input.wav" ReadFile ^signal
?signal !orig

[Low peak cut]
(?signal,150,3)ButterworthLowPass  !lower
(?signal,150,3)ButterworthHighPass !upper
(>lower,60,2)ButterworthHighPass   !lower
(?lower Normalise,100,100)Follow           !shape
(?shape,(1,?shape MaxValue)/)NumericVolume !shape
(0.1,>shape dbs+48)DirectMix               !shape
(
    >lower,
    >shape 
)Divide !lower

(
    >lower,
    >upper 
)Mix  Normalise !signal

[ De-ess ]
(?signal,4000,5)ButterworthLowPass  !lower
(?signal,4000,5)ButterworthHighPass !upper
(?upper Normalise,100,100)Follow           !shape
(?shape,(1,?shape MaxValue)/)NumericVolume !shape
(0.1,>shape dbs+48)DirectMix               !shape
(
    >upper,
    >shape 
)Divide !upper

(
    >lower,
    >upper dbs+3
)Mix  Normalise !signal

{
    (
        (?signal Reverse,1,50)Follow Reverse,
        (?signal        ,1,50)Follow,
    )Mix !shape    
    (?shape,(2,?shape MaxValue)/)NumericVolume   !shape
    (0.04,>shape)DirectMix Clip                  !shape
    (>signal,?shape)Multiply Normalise           !signal
    
    (
        (?signal Normalise,25,25)Follow,
        (?signal Normalise Reverse,25,25)Follow Reverse,
    )Mix !shape
    (?shape,(1,?shape MaxValue)/)NumericVolume !shape
    (0.3,>shape dbs+24)DirectMix               !shape
    (
        >signal,
        >shape 
    )Divide Normalise !signal 
}!envelope-compress

{
    (?signal,50,10)Granulate !grains
    Bunch !output
    (
        >grains,
        {
            ^grain ^time
            (                
                (?time,(?time,?grain length)+,?signal)Cut !sample
                (?grain Rectify MaxValue !v,?gate-point)Gt,
                {
                    (                    
                        (?v,?slam-point)Gt,
                        {
                            (>grain,(?slam-point,?v)/)NumericVolume !grain
                        },
                        {
                            [ Do nothing ]
                        }
                    )Choose Invoke
                }
                ,
                {
                    (>grain,(1,(?gate-point,?v)/)/)NumericVolume !grain
                }
            )Choose Invoke
            ((>grain swapout,>time),>output)AddEnd !output
        }
    )InvokeAll
    >output MixAt Normalise !signal
    
}!compress
{
    0.02 !gate-point
    0.50 !slam-point
    [ Do in pairs to avoid running out of memory ]
    (
        (
            ?compress,
        )DoAll Mix Swapout,
        (
            ?compress,
        )DoAll Mix Swapout,
        (
            ?compress,
        )DoAll Mix Swapout,
        (
            ?compress,
        )DoAll Mix Swapout,
    )Mix Normalise !signal
}!granular-compress

?envelope-compress Invoke

[ Reverb ]
(15 Silence,?signal)Concatenate !note-left
?signal                         !note-right

(>note-left ,1000,0.25)RBJLowPass !note-left
(>note-right,1000,0.25)RBJLowPass !note-right
(
    1,2,
    {    
        !outer
        (
            1,4,
            {
                !t
                {((30,(?t,(24,?outer)*)*)+ Prime Silence,?note-left )Concatenate} Do !nlTask
                {((45,(?t,(15,?outer)*)*)+ Prime Silence,?note-right)Concatenate} Do !nrTask
            
                {((>nlTask Done, -15)Volume,(700,(?t,3)*)-,1)ButterworthLowPass}  Do  !nlTask
                {((>nrTask Done, -15)Volume,(700,(?t,3)*)-,1)ButterworthLowPass}  Do  !nrTask
            
                {(>nlTask Done, ?note-left )Mix Normalise}                        Do !nlTask 
                {(>nrTask Done, ?note-right)Mix Normalise}                        Do !nrTask
                
                ?nlTask Done !note-left
                ?nrTask Done !note-right
            }
        )Repeat
    }
)Repeat
(
    >note-left dbs-12,
    ?signal
)Mix Normalise !left
(
    >note-right dbs-12,
    >signal
)Mix Normalise !right

(>left ,3000,2,6)RBJPeaking  Normalise   !left
(>right,3000,2,6)RBJPeaking  Normalise   !right
(>left, 150,2,12)RBJPeaking  Normalise  !left
(>right,150,2,12)RBJPeaking  Normalise  !right
>left  !signal ?granular-compress Invoke
>signal dbs+6 WaveLimit !left
>right !signal ?granular-compress Invoke
>signal dbs+6 WaveLimit !right

(
    (
        >left,
        >right
    ),"temp/step-1.wav"
)WriteFile32

Friday, 30 November 2012

Speaking Voice Processing

Sonic Field started life as an audio processing project - back to its roots!

The following script uses envelope followers to remove background rumble from the recording without taking out the lows from the voice. It also has a de-esser which is much the same thing but for high frequencies. Some light reverb is use via a very simple algorithm which folds the signal back on its self. This reverb' is seeded using a bit of Haas effect form the mono code.

The script also does some gating to remove noise between the words and compression of the over all signal to make the volume even through out. It does have a nasty habit of not catching very short audio spikes which end up left in the signal. I need to figure out how to fix this, but it is so rare that a manual tweak in Audacity does the trick.


(>left, 150,2,12)RBJPeaking  Normalise  !left
(>right,150,2,12)RBJPeaking  Normalise  !right


The above filters then make the voice sound deeper. The values would need tweaking for a female voice.

Here is a video where I used the script to process my voice:
http://youtu.be/7qhoXL7EKYs

Here is the script:
"temp/input.wav" ReadFile ^signal
?signal !orig

[Low peak cut]
(?signal,150,3)ButterworthLowPass  !lower
(?signal,150,3)ButterworthHighPass !upper
(>lower,60,2)ButterworthHighPass   !lower
(?lower Normalise,100,100)Follow           !shape
(?shape,(1,?shape MaxValue)/)NumericVolume !shape
(0.1,>shape dbs+48)DirectMix               !shape
(
    >lower,
    >shape 
)Divide !lower

(
    >lower,
    >upper 
)Mix  Normalise !signal

[ De-ess ]
(?signal,4000,5)ButterworthLowPass  !lower
(?signal,4000,5)ButterworthHighPass !upper
(?upper Normalise,100,100)Follow           !shape
(?shape,(1,?shape MaxValue)/)NumericVolume !shape
(0.1,>shape dbs+48)DirectMix               !shape
(
    >upper,
    >shape 
)Divide !upper

(
    >lower,
    >upper dbs+3
)Mix  Normalise !signal


(
    (?signal Reverse,1,50)Follow Reverse,
    (?signal        ,1,50)Follow,
)Mix !shape    
(?shape,(2,?shape MaxValue)/)NumericVolume   !shape
(0.04,>shape)DirectMix Clip                  !shape
(>signal,?shape)Multiply Normalise           !signal

(
    (?signal Normalise,25,25)Follow,
    (?signal Normalise Reverse,25,25)Follow Reverse,
)Mix !shape
(?shape,(1,?shape MaxValue)/)NumericVolume !shape
(0.3,>shape dbs+24)DirectMix               !shape
(
    >signal,
    >shape 
)Divide Normalise !signal 

[ Reverb ]
(15 Silence,?signal)Concatenate !note-left
?signal                         !note-right

(>note-left ,1000,0.25)RBJLowPass !note-left
(>note-right,1000,0.25)RBJLowPass !note-right
(
    1,2,
    {    
        !outer
        (
            1,4,
            {
                !t
                {((30,(?t,(24,?outer)*)*)+ Prime Silence,?note-left )Concatenate} Do !nlTask
                {((45,(?t,(15,?outer)*)*)+ Prime Silence,?note-right)Concatenate} Do !nrTask
            
                {((>nlTask Done, -15)Volume,(700,(?t,3)*)-,1)ButterworthLowPass}  Do  !nlTask
                {((>nrTask Done, -15)Volume,(700,(?t,3)*)-,1)ButterworthLowPass}  Do  !nrTask
            
                {(>nlTask Done, ?note-left )Mix Normalise}                        Do !nlTask 
                {(>nrTask Done, ?note-right)Mix Normalise}                        Do !nrTask
                
                ?nlTask Done !note-left
                ?nrTask Done !note-right
            }
        )Repeat
    }
)Repeat
(
    >note-left dbs-20,
    ?signal
)Mix Normalise !left
(
    >note-right dbs-20,
    >signal
)Mix Normalise !right

(>left ,3000,2,6)RBJPeaking Normalise   !left
(>right,3000,2,6)RBJPeaking Normalise   !right
(>left, 150,2,12)RBJPeaking  Normalise  !left
(>right,150,2,12)RBJPeaking  Normalise  !right

(
    (
        >left,
        >right
    )StereoMonitor,"temp/tone.wav"
)WriteFile32


Tuesday, 27 November 2012

Working With The Sonic Field Console


Having A Console Makes A Huge Difference To Productivity And Creativity

Up until now the productivity of Sonic Field has been severely limited by the need to re-run a patch every time it is edited; this make playing around with sound a very slow process indeed. The addition of the Console processor opens up a whole new arena of rapid sound development from Sonic Field. It also opens up lots of possibilities for fun.

The implementation of Console at the time of writing this is about as simple as it is possible to be. In agile style, I got something working and will use it to find out ways to improve it.

How It Works
At any point in a patch the Processor Console can be used. This will start interacting with the console. It simply reads from Standard Input. This works OK with the Eclipse console which Sonic Field gets when run under Eclipse. The console accepts lines of input. If a line consist of just:
%end%
then the console processor stops and the next processor in the patch is run.

The Console accumulates a patch. Each line of input is added to the patch. When an line consisting of :
%
and nothing else is entered, the current accumulated patch is parsed and run. This allows for complex patches to be either typed or pasted into the console window and then run. The patch runs in the context (same store values) as the patch which contained the original Console processor. However, there is a difference.

When a patch launched from the command line (or Eclipse) causes an error Sonic Field shuts down. Patches entered in the Console to not cause Sonic Field to shut down in this way. If you make a mistake in the Console Sonic Field will tell you something about the mistake and then just start reading from Standard Input again.

One Small Issue:
At the time of writing there is a slight issue in that if there is a layout problem with code inside a code block which is entered into the Console Sonic Field gets the code block tracking system a bif stuffed up. If, after a patch layout problem, you keep getting 'unmatched brace' errors, then enter
}
%

An Example:
Below is a slightly abridged example form the Eclipse console of me working on a bass/rhythm line in Sonic Field

SFPL: [3]1 >> Sonic Field Thread Factory:
SFPL: [3]1 >> ---------------------------
SFPL: [3]1 >> Found CPUs: 8
SFPL: [3]1 >> Initial Max Threads: 16
Parsing: scripts/play/FastBass.sfpl size: 866
SFPL: [532]1 >> Sonic Field Version 0.2 Starting Processing
SFPL: [532]1 >> ============================================
?play invoke
%
(
(0,2.0),
((?bt,2)*,0),
((?bt,4)*,2)
)NumericShape !qEnv
%
?play invoke
%
{
((?bt,4)*,?pitch)SinWave MakeSawTooth dbs+3 Saturate Normalise !signal
(?qEnv,4)DirectRelength !qsEnv
(?qsEnv,?qsEnv,?qsEnv,?qsEnv,?qsEnv)Concatenate !qsEnv
(0,?signal Length,>qsEnv)Cut !qsEnv
(?pitchEnv,4)DirectRelength !psEnv
(?psEnv,?psEnv,?psEnv,?psEnv,?psEnv)Concatenate !psEnv
(0,?signal Length,>psEnv)Cut !psEnv
(>signal,?psEnv,?qsEnv)ShapedLadderLowPass Normalise !signal
>signal Normalise !signal
(>signal,2)Power Normalise !signal
(>signal,?pitch,1,24)RBJPeaking Normalise !signal Monitor
}!play
%
?play invoke
%
"A2" Note !pitch
?play invoke
%
com.nerdscentral.sfpl.SFPL_RuntimeException: Runtime Exception at key word Invoke
operand: '109.99999987361397'
at line: 0, colum 30 in Console
at com.nerdscentral.sfpl.SFPL_Runner.Invoke(SFPL_Runner.java:103)
at com.nerdscentral.audio.io.SF_Console.Interpret(SF_Console.java:57)
at com.nerdscentral.sfpl.SFPL_Runner.Invoke(SFPL_Runner.java:87)
at com.nerdscentral.sfpl.SFPL_Runner.Invoke(SFPL_Runner.java:64)
at com.nerdscentral.sfpl.RenderRunnerImp.runParser(RenderRunnerImp.java:163)
at com.nerdscentral.sfpl.RenderRunnerImp.render(RenderRunnerImp.java:65)
at com.nerdscentral.sfpl.RenderRunner.main(RenderRunner.java:25)
Caused by: com.nerdscentral.sfpl.SFPL_RuntimeException: Failed to resolve type: class java.lang.Double
at com.nerdscentral.sfpl.Caster.describeSFPLType(Caster.java:55)
at com.nerdscentral.sfpl.Caster.throwConversion(Caster.java:49)
at com.nerdscentral.sfpl.Caster.makeBunch(Caster.java:68)
at com.nerdscentral.sfpl.SFPL_Parser$cInvoke.Interpret(SFPL_Parser.java:1166)
at com.nerdscentral.sfpl.SFPL_Runner.Invoke(SFPL_Runner.java:87)
... 6 more
"A2" Note !pitch

%
?play println
%
com.nerdscentral.sfpl.SFPL_Runner@c6824d9
?play println
%
com.nerdscentral.sfpl.SFPL_Runner@c6824d9
?play invoke
%
{
((?bt,4)*,?pitch)SinWave MakeSawTooth dbs+3 Saturate Normalise !signal
(?qEnv,4)DirectRelength !qsEnv
(?qsEnv,?qsEnv,?qsEnv,?qsEnv,?qsEnv)Concatenate !qsEnv
(0,?signal Length,>qsEnv)Cut !qsEnv
(?pitchEnv,4)DirectRelength !psEnv
(?psEnv,?psEnv,?psEnv,?psEnv,?psEnv)Concatenate !psEnv
(0,?signal Length,>psEnv)Cut !psEnv
(>signal,?psEnv,?qsEnv)ShapedLadderLowPass Normalise !signal
>signal Normalise !signal
(>signal,2)Power Normalise !signal
(>signal,?pitch,1,24)RBJPeaking Normalise dbs+3 Saturate Normalise !signal
?bt WhiteNoise MakeTriangle Normalise !signalb
(
>signal,>signalb
)Concatenate !signal Monitor
}!play
%
?play invoke
%

?play invoke
%

{
((?bt,4)*,?pitch)SinWave MakeSawTooth dbs+3 Saturate Normalise !signal
(?qEnv,4)DirectRelength !qsEnv
(?qsEnv,?qsEnv,?qsEnv,?qsEnv,?qsEnv)Concatenate !qsEnv
(0,?signal Length,>qsEnv)Cut !qsEnv
(?pitchEnv,4)DirectRelength !psEnv
(?psEnv,?psEnv,?psEnv,?psEnv,?psEnv)Concatenate !psEnv
(0,?signal Length,>psEnv)Cut !psEnv
(>signal,?psEnv,?qsEnv)ShapedLadderLowPass Normalise !signal
>signal Normalise !signal
(>signal,2)Power Normalise !signal
?bt WhiteNoise MakeSawTooth !signalb
(?signalb,(?pitch,4)*,24,1.5)RBJLowShelf !signalb
(
((0,0),(100,1),(?signalb Length,0))NumericShape,
>signalb
)Multiply Normalise !signalb
(
>signal,>signalb
)Concatenate !signal
(>signal,?pitch,1,24)RBJPeaking Normalise dbs+3 Saturate Normalise !signal Monitor
}!play
%
?play invoke
%

{
((?bt,4)*,?pitch)SinWave MakeSawTooth dbs+3 Saturate Normalise !signal
(?qEnv,4)DirectRelength !qsEnv
(?qsEnv,?qsEnv,?qsEnv,?qsEnv,?qsEnv)Concatenate !qsEnv
(0,?signal Length,>qsEnv)Cut !qsEnv
(?pitchEnv,4)DirectRelength !psEnv
(?psEnv,?psEnv,?psEnv,?psEnv,?psEnv)Concatenate !psEnv
(0,?signal Length,>psEnv)Cut !psEnv
(>signal,?psEnv,?qsEnv)ShapedLadderLowPass Normalise !signal
>signal Normalise !signal
(>signal,2)Power Normalise !signal
?bt WhiteNoise MakeSawTooth !signalb
(?signalb,(?pitch,4)*,1.5,24)RBJLowShelf !signalb
(
((0,0),(100,1),(?signalb Length,0))NumericShape,
>signalb
)Multiply Normalise !signalb
(
>signal,>signalb
)Concatenate !signal
(>signal,?pitch,1,24)RBJPeaking Normalise dbs+3 Saturate Normalise !signal Monitor
}!play
%
?play invoke
%
{
((?bt,4)*,?pitch)SinWave MakeSawTooth dbs+3 Saturate Normalise !signal
(?qEnv,4)DirectRelength !qsEnv
(?qsEnv,?qsEnv,?qsEnv,?qsEnv,?qsEnv)Concatenate !qsEnv
(0,?signal Length,>qsEnv)Cut !qsEnv
(?pitchEnv,4)DirectRelength !psEnv
(?psEnv,?psEnv,?psEnv,?psEnv,?psEnv)Concatenate !psEnv
(0,?signal Length,>psEnv)Cut !psEnv
(>signal,?psEnv,?qsEnv)ShapedLadderLowPass Normalise !signal
>signal Normalise !signal
(>signal,2)Power Normalise !signal
?bt WhiteNoise MakeSawTooth !signalb
(?signalb,(?pitch,2)*,1.5,24)RBJLowShelf !signalb
(
((0,0),(100,1),(?signalb Length,0))NumericShape,
>signalb
)Multiply Normalise !signalb
(
>signal,>signalb dbs+12
)Concatenate !signal
(>signal,?pitch,1,24)RBJPeaking Normalise dbs+3 Saturate Normalise !signal Monitor
}!play
%
?play invoke
%
?signal monitor
%
((?signal),"temp/tone.wav")WriteFile32
%