constant Size { value: 1024 }
signal InputBuffer [Size] { default: 0.0 rate: none }
signal OutputBuffer [Size] { default: 0.0 rate: none }
complex Spectrum [ Size / 2 + 1] { default: [ 0.0, 0.0 ] rate: AudioRate / ( Size / 2 ) }
complex BrickWall [ Size / 2 + 1] { default: [ 0.0, 0.0 ] rate: none }
[ 1.0, 1.0 ] >> BrickWall [ 1 : Size / 4 ];
InputBuffer >> RealFFT () >> Spectrum;
[ Spectrum, BrickWall ] >> CxMultiply () >> RealIFFT () >> OutputBuffer;
AudioIn >> FillBundle ( size: Size hopSize: Size / 2 ) >> InputBuffer;
OutputBuffer >> OverlapAdd ( size: Size overlapSize: Size / 2 ) >> GetSample ( size: Size ) >> AudioOut;
Module: FillBundle
module FillBundle {
input: Input
output: Outputs
propertyName: [ 'size', 'hopSize' ]
propertyDirection: in
propertyBlock: [
constant Size { value: 128 },
constant HopSize { value: Size / 2 }
]
constraints: [
Size >> Compare ( value: 1 operator: 'LessOrEqual' ) >> Error ( message: "'size' should be a positive integer greater than one" );
HopSize >> Compare (value: 0 operator: 'LessOrEqual' ) >> Error ( message: "'hopSize' should be a positive integer" );
HopSize >> Compare (value: Size operator: 'Greater' ) >> Error ( message: "'hopSize' should be less than 'size'" );
]
internalBlock: [
signal Input { rate: none },
signal Outputs [Size] { rate: none },
signal Samples [Size] { rate: none },
signal Index { default: 1 rate: none reset: ResetIndex },
signal SampleCount { default: 0 rate: none reset: ResetSampleCount },
reaction RenderBuffer {
output: Outputs
onExecution: Reset
terminateWhen: Done
internalBlocks: [
signal Outputs [Size] { rate: none },
switch Done { default: off reset: Reset },
trigger Reset {}
]
streams: [
Index
>> Compare ( value: 1 operator: 'Equal' )
>> Select (
whenOn: Samples
whenOff: [ Samples[ Index : Size ], Samples[ 1 : Index - 1 ] ] # MANY TO ONE CONNECTION // signal SortIndex needed
)
>> Outputs;
on >> Done;
]
},
trigger ResetIndex {},
trigger ResetSampleCount {}
]
streams: [
Input >> Samples [Index];
Index + 1 >> Index >> Compare ( value: Size operator: 'Greater' ) >> ResetIndex;
SampleCount + 1 >> SampleCount >> Compare ( value: HopSize operator: 'Equal' ) >> ResetSampleCount >> RenderBuffer () >> Outputs;
]
}
Module: OverlapAdd
module OverlapAdd {
input: Inputs
output: Outputs
propertyName: [ 'size', 'overlapSize' ]
propertyDirection: in
propertyBlock: [
constant Size { value: 128 },
constant OverlapSize { value: Size / 2 },
]
constraints: none
internalBlock: [
signal Inputs [Size] { rate: none },
signal Outputs [Size] { rate: none },
signal Index { default: 1 rate: none reset: ResetIndex },
trigger ResetIndex {},
reaction RenderBuffer {
output: RenderedBuffer
onExecution: ResetReadIndex
terminateWhen: RenderingComplete
internalBlock: [
signal RenderedBuffer [Size] { rate: none },
signal WriteIndex { default: 1 rate: none reset: ResetWriteIndex },
signal ReadIndex { default: 1 rate: none reset: ResetReadIndex },
signal ValueWhenOn { rate: none },
signal ValueWhenOff { rate: none },
trigger ResetWriteIndex {},
trigger ResetReadIndex {},
trigger RenderingComplete {}
]
streams: [
ReadIndex
>> Compare ( value: 1 operator: 'Equal' )
>> Select (
whenOn: Index
whenOff: WriteIndex + 1
)
>> WriteIndex
>> Compare ( value: Size operator: 'Greater' )
>> ResetWriteIndex;
Inputs >> GetPort ( index: ReadIndex ) >> ValueWhenOn;
[ Inputs , Outputs ] >> GetPort ( index: [ ReadIndex, WriteIndex] ) >> Add () >> ValueWhenOff;
ReadIndex
>> Compare ( value: Size - OverlapSize operator: 'Greater' )
>> Select (
whenOn: ValueWhenOn
whenOff: ValueWhenOff
)
>> SetPort ( index: WriteIndex )
>> RenderedBuffer;
ReadIndex + 1 >> ReadIndex >> Compare ( value: Size operator: 'Greater' ) >> RenderingComplete;
]
}
]
streams: [
RenderBuffer () >> Outputs;
Index + OverlapSize >> Index >> Compare ( value: Size operator: 'Greater' ) >> ResetIndex;
]
}
Module: GetSample
module GetSample {
input: Input
output: Output
propertyName: 'size'
propertyDirection: in
propertyBlock: constant Size { value: 128 }
constraints: Size >> Compare ( value: 1 operator: 'LessOrEqual' ) >> Error ( message: "'size' should be a positive integer greater than one" );
internalBlock: [
signal Input [Size] { rate: none },
signal Output { rate: streamRate },
signal Index { default: 1 rate: streamRate reset: ResetIndex },
trigger ResetIndex {}
]
streams: [
Input[Index] >> Output;
Index + 1 >> Index >> Compare ( value: Size operator: 'Greater' ) >> ResetIndex;
]
}