Previous topic

Recursion

Next topic

Frequency Domain

This Page

Granular Synthesis

Synchronous Generation and Static Allocation

constant NumberOfGrains         { value: 50 }
constant GrainTriggerRate       { value: 15 }
constant GrainDuration          { value: 4.0 }
constant GrainFrequency         { value: 220 }

switch GrainState [NumberOfGrains]      { default: off reset: ResetGrainState }
switch AllGrainsActive                  { default: off reset: none}

trigger ResetGrainState [NumberOfGrains]        {}

signal ImpulseTrainSignal       { default: 0.0 rate: AudioRate domain: AudioDomain }

reaction RequestGrain {
        output:         Index
        onExecution:    ResetGrainIndex
        terminateWhen:  FreeGrainFound or NoFreeGrainAvailable
        internalBlock:  [
                signal Index { default: 1 rate: none domain: AudioDomain reset: ResetGrainIndex },
                trigger ResetGrainIndex         {},
                trigger FreeGrainFound          {},
                trigger NoFreeGrainAvailable    {}
        ]
        streams:        [
                GrainState[Index] >> Select ( whenOn: on whenOff: on ) >> GrainState[Index] >> FreeGrainFound;
                Index + 1 >> Index >> Compare ( value: Size  operator: 'Greater' ) >> NoFreeGrainAvailable;
        ]
}

Oscillator (
        type:                   'Sine'
        frequency:              GrainFrequency
        reset:                  GrainState
)
>> Envelope (
        type:                   'Gaussian'
        size:                   GrainDuration * streamRate / 1000.0
        reset:                  GrainState
        complete:               ResetGrainState
)
>> Mix ()
>> Level ( gain: 1.0 / NumberOfGrains )                                 # Add a smoothing function here
>> AudioOut[1:2];

ImpulseTrain ( frequency: GrainTriggerRate ) >> ImpulseTrainSignal;
GrainState >> And () >> AllGrainsActive;
ImpulseTrainSignal and not AllGrainsActive >> RequestGrain ();          # The output port is left unconnected

Synchronous Generation and Dynamic Allocation

constant        GrainTriggerRate        { value: 15 }
constant        GrainDuration           { value: 4.0 }
constant        GrainFrequency          { value: 220 }
constant        Zero                    { value: 0.0 }

variable        Grains                  { count: GrainCount createWhen: AddGrain destroyWhen: RemoveGrain }
signal          GrainCount              { default: 0 rate: none domain: AudioDomain }
trigger         AddGrain                {}
trigger         RemoveGrain [Grains]    {}

signal          ImpulseTrainStream      { default: 0.0 rate: AudioRate reset: none domain: AudioDomain}
signal          PortSelect              { default: 1 rate: AudioRate reset: none domain: AudioDomain }

ImpulseTrain ( frequency: GrainTriggerRate ) >> ImpulseTrainStream >> AddGrain;

GrainCount >> Compare ( value: 0 operator: 'Equal' ) >> Select ( whenOn: 1 whenOff: 2 ) >> PortSelect;

[
        Zero
        ,
        Oscillator (
                type:           'Sine'
                frequency:      GrainFrequency
        )
        >> Envelope (
                type:           'Gaussian'
                size:           GrainDuration * streamRate / 1000.0
                complete:       RemoveGrain
        )
        >> Mix ()
        >> Level ( gain: 1.0 / GrainCount )                             # Add a smoothing function here
]
>> GetPort ( index: PortSelect )
>> AudioOut[1:2];

Synchronous Generation and Dynamic Allocation with Control

constant        GrainTriggerRate        { value: 15 }
constant        Zero                    { value: 0.0 }

variable        Grains                  { count: GrainCount createWhen: AddGrain destroyWhen: RemoveGrain }
signal          GrainCount              { default: 0 domain: AudioDomain }
trigger         AddGrain                {}
trigger         RemoveGrain [Grains]    {}

signal          GrainDuration [Grains]  { default: 4.0 rate: none }
signal          GrainFrequency [Grains] { default: 15 rate: none }
signal          ImpulseTrainStream      { default: 0.0 rate: AudioRate reset: none domain: AudioDomain }
signal          PortSelect              { default: 1 rate: AudioRate reset: none domain: AudioDomain }

reaction        CaptureControls {
        output:         none
        onExecution:    Reset
        terminateWhen:  Captured
        internalBlock: [
                switch Capture { default: off reset: Reset },
                trigger Reset {}
        ]
        streams:        [
                ControlIn [1:2]
                >> Map ( minimum: [ 1, 55.0 ] maximum: [ 200, 880.0 ] )
                >> SampleHold ( event: Reset )
                >> [ GrainDuration [GrainCount], GrainFrequency [ GrainCount ];
                on >> Captured;
        ]
}

ImpulseTrain ( frequency: GrainTriggerRate ) >> ImpulseTrainStream >> AddGrain >> CaptureControls ();

GrainCount >> Compare ( value: 0 operator: 'Equal' ) >> Select ( whenOn: 1 whenOff: 2 ) >> PortSelect;

[
        Zero
        ,
        Oscillator (
                type:           'Sine'
                frequency:      GrainFrequency
        )
        >> Envelope (
                type:           'Gaussian'
                size:           GrainDuration * streamRate / 1000.0
                complete:       RemoveGrain
        )
        >> Mix ()
        >> Level ( gain: 1.0 / GrainCount  )                            # Add a smoothing function here
]
>> GetPort ( index: PortSelect )
>> AudioOut[1:2];