From 6f88ec98fe5b4833fe82737728776ef94301d303 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 22 Apr 2020 11:49:47 +0100 Subject: [PATCH 1/7] sines - refined example on residual --- release-packaging/HelpSource/Classes/FluidSines.schelp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/release-packaging/HelpSource/Classes/FluidSines.schelp b/release-packaging/HelpSource/Classes/FluidSines.schelp index f419a7c..c34d207 100644 --- a/release-packaging/HelpSource/Classes/FluidSines.schelp +++ b/release-packaging/HelpSource/Classes/FluidSines.schelp @@ -82,6 +82,12 @@ b = Buffer.read(s,File.realpath(FluidSines.class.filenameSymbol).dirname.withTra // as the algorithm resynthesize the sinusoidal peaks, we would expect to get it to work almost perfectly on a sine wave, with these settings that tell the process to tolerate everything as a sinusoid, even short and quiet peaks {FluidSines.ar(SinOsc.ar(mul: 0.1),detectionThreshold: -144,birthLowThreshold: -144,birthHighThreshold: -144,minTrackLen: 1,trackMagRange: 200,trackFreqRange: 1000,trackProb: 0)}.play; +// we can listen to the artefact in solo, amplifying it by 30dB, to hear the 'lobes' - not bad at all! +{FluidSines.ar(SinOsc.ar(mul: 0.1),detectionThreshold: -144,birthLowThreshold: -144,birthHighThreshold: -144,minTrackLen: 1,trackMagRange: 200,trackFreqRange: 1000,trackProb: 0)[1].dup * Line.ar(0,30,1).dbamp}.play; + // as this is a windowed process, the frequency of the peak is good for that full window, and therefore interesting artefacts appear when the pitch is changing. {FluidSines.ar(SinOsc.ar(LFTri.kr(0.1).exprange(220,880),mul: 0.1),detectionThreshold: -144,birthLowThreshold: -144,birthHighThreshold: -144,minTrackLen: 1,trackMagRange: 300,trackFreqRange: 1000,trackProb: 0)}.play; + +// if we solo and amplify the artefacts, they are much more apparent (and interesting) +{FluidSines.ar(SinOsc.ar(LFTri.kr(0.1).exprange(220,880),mul: 0.1),detectionThreshold: -144,birthLowThreshold: -144,birthHighThreshold: -144,minTrackLen: 1,trackMagRange: 300,trackFreqRange: 1000,trackProb: 0)[1].dup * Line.ar(0,30,1).dbamp}.play; :: From e804c90baa9f4a28259abb9943c4ff1d1bd22175 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 22 Apr 2020 12:02:15 +0100 Subject: [PATCH 2/7] changed asInt to asInteger, resolving #44 --- release-packaging/HelpSource/Classes/FluidBufPitch.schelp | 2 +- release-packaging/HelpSource/Classes/FluidBufStats.schelp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidBufPitch.schelp b/release-packaging/HelpSource/Classes/FluidBufPitch.schelp index 3b8f530..f202e83 100644 --- a/release-packaging/HelpSource/Classes/FluidBufPitch.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufPitch.schelp @@ -143,7 +143,7 @@ c = Buffer.new(s); ( Routine{ t = Main.elapsedTime; - FluidBufPitch.process(s, b, features: c,action:{c.loadToFloatArray(action: {|x| d = x.reshape((x.size()/2).asInt, 2)})}); + FluidBufPitch.process(s, b, features: c,action:{c.loadToFloatArray(action: {|x| d = x.reshape((x.size()/2).asInteger, 2)})}); (Main.elapsedTime - t).postln; }.play ) diff --git a/release-packaging/HelpSource/Classes/FluidBufStats.schelp b/release-packaging/HelpSource/Classes/FluidBufStats.schelp index ce83e04..6b9cf4c 100644 --- a/release-packaging/HelpSource/Classes/FluidBufStats.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufStats.schelp @@ -134,10 +134,10 @@ g= Array.new; Routine({ e.doAdjacentPairs({ arg start,end; - FluidBufStats.processBlocking(s,c,(start/512).asInt,((end-start)/512).max(2).asInt,0,1,d,1, action: {d.loadToFloatArray(action: { + FluidBufStats.processBlocking(s,c,(start/512).asInteger,((end-start)/512).max(2).asInteger,0,1,d,1, action: {d.loadToFloatArray(action: { arg array; g = g.add(array[12]); - "% % %\n".postf((start/512).asInt,((end-start)/512).max(2).asInt, array[12]); + "% % %\n".postf((start/512).asInteger,((end-start)/512).max(2).asInteger, array[12]); })}); }); "Done".postln; From 060db23bdc6d15690db3494eb5277cfcb4ab14af Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 22 Apr 2020 12:05:23 +0100 Subject: [PATCH 3/7] corrects the description of the output in loudness --- release-packaging/HelpSource/Classes/FluidLoudness.schelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-packaging/HelpSource/Classes/FluidLoudness.schelp b/release-packaging/HelpSource/Classes/FluidLoudness.schelp index 9a6ffdc..769b236 100644 --- a/release-packaging/HelpSource/Classes/FluidLoudness.schelp +++ b/release-packaging/HelpSource/Classes/FluidLoudness.schelp @@ -32,7 +32,7 @@ ARGUMENT:: maxwindowSize How large can the windowSize be, by allocating memory at instantiation time. This cannot be modulated. RETURNS:: - A 2-channel KR signal with the [pitch, confidence] descriptors. The latency is windowSize. + A 2-channel KR signal with the [loudness, peak] descriptors. The latency is windowSize. EXAMPLES:: From f5e2878dc8a1a65be886d62153dedb151228827e Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 29 Apr 2020 09:31:01 +0100 Subject: [PATCH 4/7] sorted help (filter and settings) of (buf)amp(gate|slice) --- .../HelpSource/Classes/FluidAmpGate.schelp | 16 ++++++++-------- .../HelpSource/Classes/FluidAmpSlice.schelp | 2 +- .../HelpSource/Classes/FluidBufAmpGate.schelp | 14 +++++++------- .../HelpSource/Classes/FluidBufAmpSlice.schelp | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidAmpGate.schelp b/release-packaging/HelpSource/Classes/FluidAmpGate.schelp index 880a960..8fdee5f 100644 --- a/release-packaging/HelpSource/Classes/FluidAmpGate.schelp +++ b/release-packaging/HelpSource/Classes/FluidAmpGate.schelp @@ -19,16 +19,16 @@ ARGUMENT:: in The audio to be processed. ARGUMENT:: rampUp - The number of samples the absolute envelope follower will take to reach the next value when raising. + The number of samples the envelope follower will take to reach the next value when raising. ARGUMENT:: rampDown - The number of samples the absolute envelope follower will take to reach the next value when falling. + The number of samples the envelope follower will take to reach the next value when falling. ARGUMENT:: onThreshold - The threshold in dB of the absolute envelope follower to trigger an onset, aka to go ON when in OFF state. + The threshold in dB of the envelope follower to trigger an onset, aka to go ON when in OFF state. ARGUMENT:: offThreshold - The threshold in dB of the absolute envelope follower to trigger an offset, , aka to go ON when in OFF state. + The threshold in dB of the envelope follower to trigger an offset, , aka to go ON when in OFF state. ARGUMENT:: minSliceLength The length in samples that the Slice will stay ON. Changes of states during that period will be ignored. @@ -37,10 +37,10 @@ ARGUMENT:: minSilenceLength The length in samples that the Slice will stay OFF. Changes of states during that period will be ignored. ARGUMENT:: minLengthAbove - The length in samples that the absolute envelope have to be above the threshold to consider it a valid transition to ON. The Slice will start at the first sample when the condition is met. Therefore, this affects the latency. + The length in samples that the envelope have to be above the threshold to consider it a valid transition to ON. The Slice will start at the first sample when the condition is met. Therefore, this affects the latency. ARGUMENT:: minLengthBelow - The length in samples that the absolute envelope have to be below the threshold to consider it a valid transition to OFF. The Slice will end at the first sample when the condition is met. Therefore, this affects the latency. + The length in samples that the envelope have to be below the threshold to consider it a valid transition to OFF. The Slice will end at the first sample when the condition is met. Therefore, this affects the latency. ARGUMENT:: lookBack The length of the buffer kept before an onset to allow the algorithm, once a new Slice is detected, to go back in time (up to that many samples) to find the minimum amplitude as the Slice onset point. This affects the latency of the algorithm. @@ -49,7 +49,7 @@ ARGUMENT:: lookAhead The length of the buffer kept after an offset to allow the algorithm, once the Slice is considered finished, to wait further in time (up to that many samples) to find a minimum amplitude as the Slice offset point. This affects the latency of the algorithm. ARGUMENT:: highPassFreq - The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. + The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. A frequency of 0 bypasses the filter. ARGUMENT:: maxSize How large can the buffer be for time-critical conditions, by allocating memory at instantiation time. This cannot be modulated. @@ -129,7 +129,7 @@ b = Buffer.read(s,File.realpath(FluidAmpGate.class.filenameSymbol).dirname.withT //have fun with a gate (explore lookahead and lookback, but correct for latency, which will be the greatest of the lookahead and lookback) ( {var env, source = PlayBuf.ar(1,b); - env = FluidAmpGate.ar(source, rampUp:441, rampDown:2205, onThreshold:-27, offThreshold: -31, minSilenceLength:1100, lookBack:441, highPassFreq:20); + env = FluidAmpGate.ar(source, rampUp:441, rampDown:2205, onThreshold:-27, offThreshold: -31, minSilenceLength:4410, lookBack:441, highPassFreq:20); [DelayN.ar(source,delaytime:441/44100), env] }.plot(2, separately:true); ) diff --git a/release-packaging/HelpSource/Classes/FluidAmpSlice.schelp b/release-packaging/HelpSource/Classes/FluidAmpSlice.schelp index 72d87e8..347ddf2 100644 --- a/release-packaging/HelpSource/Classes/FluidAmpSlice.schelp +++ b/release-packaging/HelpSource/Classes/FluidAmpSlice.schelp @@ -43,7 +43,7 @@ ARGUMENT:: minSliceLength The length in samples that the Slice will stay ON. Changes of states during that period will be ignored. ARGUMENT:: highPassFreq - The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. + The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. A frequency of 0 bypasses the filter. RETURNS:: An audio stream with square envelopes around the slices. The latency between the input and the output is dependant on the relation between the two envelope followers. diff --git a/release-packaging/HelpSource/Classes/FluidBufAmpGate.schelp b/release-packaging/HelpSource/Classes/FluidBufAmpGate.schelp index 438208a..70a137f 100644 --- a/release-packaging/HelpSource/Classes/FluidBufAmpGate.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufAmpGate.schelp @@ -41,16 +41,16 @@ ARGUMENT:: indices The index of the buffer where the indices (in sample) of the estimated starting points of slices will be written. The first and last points are always the boundary points of the analysis. ARGUMENT:: rampUp - The number of samples the absolute envelope follower will take to reach the next value when raising. + The number of samples the envelope follower will take to reach the next value when raising. ARGUMENT:: rampDown - The number of samples the absolute envelope follower will take to reach the next value when falling. + The number of samples the envelope follower will take to reach the next value when falling. ARGUMENT:: onThreshold - The threshold in dB of the absolute envelope follower to trigger an onset, aka to go ON when in OFF state. + The threshold in dB of the envelope follower to trigger an onset, aka to go ON when in OFF state. ARGUMENT:: offThreshold - The threshold in dB of the absolute envelope follower to trigger an offset, , aka to go ON when in OFF state. + The threshold in dB of the envelope follower to trigger an offset, , aka to go ON when in OFF state. ARGUMENT:: minSliceLength The length in samples that the Slice will stay ON. Changes of states during that period will be ignored. @@ -59,10 +59,10 @@ ARGUMENT:: minSilenceLength The length in samples that the Slice will stay OFF. Changes of states during that period will be ignored. ARGUMENT:: minLengthAbove - The length in samples that the absolute envelope have to be above the threshold to consider it a valid transition to ON. The Slice will start at the first sample when the condition is met. Therefore, this affects the latency. + The length in samples that the envelope have to be above the threshold to consider it a valid transition to ON. The Slice will start at the first sample when the condition is met. Therefore, this affects the latency. ARGUMENT:: minLengthBelow - The length in samples that the absolute envelope have to be below the threshold to consider it a valid transition to OFF. The Slice will end at the first sample when the condition is met. Therefore, this affects the latency. + The length in samples that the envelope have to be below the threshold to consider it a valid transition to OFF. The Slice will end at the first sample when the condition is met. Therefore, this affects the latency. ARGUMENT:: lookBack The length of the buffer kept before an onset to allow the algorithm, once a new Slice is detected, to go back in time (up to that many samples) to find the minimum amplitude as the Slice onset point. This affects the latency of the algorithm. @@ -71,7 +71,7 @@ ARGUMENT:: lookAhead The length of the buffer kept after an offset to allow the algorithm, once the Slice is considered finished, to wait further in time (up to that many samples) to find a minimum amplitude as the Slice offset point. This affects the latency of the algorithm. ARGUMENT:: highPassFreq - The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. + The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. A frequency of 0 bypasses the filter. ARGUMENT:: action A Function to be evaluated once the offline process has finished and indices instance variables have been updated on the client side. The metric will be passed indices as an argument. diff --git a/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp b/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp index 1cdf44b..59e2c8a 100644 --- a/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp @@ -65,7 +65,7 @@ ARGUMENT:: minSliceLength The length in samples that the Slice will stay ON. Changes of states during that period will be ignored. ARGUMENT:: highPassFreq - The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. + The frequency of the fourth-order Linkwitz–Riley high-pass filter (https://en.wikipedia.org/wiki/Linkwitz%E2%80%93Riley_filter). This is done first on the signal to minimise low frequency intermodulation with very fast ramp lengths. A frequency of 0 bypasses the filter. ARGUMENT:: action A Function to be evaluated once the offline process has finished and indices instance variables have been updated on the client side. The metric will be passed indices as an argument. From 1f2ad13c0daee652608d2e44002c115d88e51856 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 29 Apr 2020 12:44:47 +0100 Subject: [PATCH 5/7] fixing sound quality of strange resonator example in nmfmatch --- release-packaging/HelpSource/Classes/FluidNMFMatch.schelp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp b/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp index d4202e2..9c44521 100644 --- a/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp +++ b/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp @@ -216,7 +216,7 @@ FluidBufSpectralShape.process(s, c, features: ~spectralshapes, action:{ }); ) -//7 shapes (track) x 8 components (tracks) x 7 stats(frames) +//the interleave format is 7 stats(frames) x 8 components in the source as tracks x 7 shapes (tracks) ~stats.query ~centroids.size() @@ -230,8 +230,8 @@ x = { var sound = PlayBuf.ar(1,b,loop:1); var harm, perc; # harm, perc = FluidHPSS.ar(sound, maskingMode:1, harmThreshFreq1: 0.005869, harmThreshAmp1: -9.6875, harmThreshFreq2: 0.006609, harmThreshAmp2: -4.375, hopSize:256); - Out.ar(~splitaudio, harm); - Out.kr(~nmfenvs, FluidNMFMatch.kr(sound, ~bases, maxComponents:8, hopSize:256, fftSize:2048)); + Out.ar(~splitaudio, (harm / 4) + perc); + Out.kr(~nmfenvs, FluidNMFMatch.kr(DelayN.ar(sound,delaytime: ((17-1)*256)/44100), ~bases, maxComponents:8, hopSize:256, fftSize:2048)); Out.ar(0,perc.dup) }.play; ) @@ -241,7 +241,7 @@ x = { 8.do({ arg i; { - var audio = BPF.ar(In.ar(~splitaudio,1), ~centroids[i],0.01,LagUD.kr(In.kr(~nmfenvs,8)[i],0.001,0.01,0.1)); + var audio = BPF.ar(In.ar(~splitaudio,1), ~centroids[i],0.0015,Lag.kr(In.kr(~nmfenvs,8)[i] * 2,0.022)); Out.ar(0,Pan2.ar(audio, (i / 14) - 0.25)); }.play(x,addAction: \addAfter); }); From 6f4a2abb70dd7aaa702b38f97d399b58798f40bd Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 29 Apr 2020 14:40:56 +0100 Subject: [PATCH 6/7] missing explanation in bufampslice demo --- release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp b/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp index 59e2c8a..f5739cc 100644 --- a/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufAmpSlice.schelp @@ -86,7 +86,7 @@ c = Buffer.new(s); b.play b.plot -// +//process with symmetrical thresholds FluidBufAmpSlice.process(s, b,indices: c,fastRampUp: 5,fastRampDown: 50,slowRampUp: 220,slowRampDown: 220, onThreshold: 10, offThreshold: 10,floor: -60); c.query c.getn(0,c.numFrames,{|item|item.postln;}) From 5c3e2b78ff0ecc4f79e007705858393b7fd4c970 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 29 Apr 2020 14:56:23 +0100 Subject: [PATCH 7/7] bufstats: less ugly presentation of the stats at the end --- release-packaging/HelpSource/Classes/FluidBufStats.schelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-packaging/HelpSource/Classes/FluidBufStats.schelp b/release-packaging/HelpSource/Classes/FluidBufStats.schelp index 6b9cf4c..02ab8c8 100644 --- a/release-packaging/HelpSource/Classes/FluidBufStats.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufStats.schelp @@ -175,5 +175,5 @@ FluidBufStats.process(s, b, stats:c, numDerivs:1, action:{c.getn(0,c.numFrames * //looking at the result is not easy to grasp, since it is interleaved: first number is mean of L, second is mean of R, third is stddev of L, fourth is stddev or R //this will make it tidier - the first value of each line is Left, the second is Right -d.reshape(14,2).do({|x,i|["mean\t\t","stddev\t\t","skew\t\t\t", "kurtosis\t", "min\t\t\t", "median\t\t", "max\t\t\t","d-mean\t","d-stddev\t","d-skew\t\t", "d-kurtosis", "d-min\t\t", "d-median\t", "d-max\t\t"].at(i).post;x.round(0.01).postln}) +d.reshape(14,2).do({|x,i|["mean\t\t","stddev\t\t","skew\t\t\t", "kurtosis\t", "min\t\t\t", "median\t\t", "max\t\t\t","d-mean\t","d-stddev\t","d-skew\t\t", "d-kurtosis", "d-min\t\t", "d-median\t", "d-max\t\t"].at(i).post;x.round(0.01).postln});"".postln; ::