From e407c2efb8ea8573b45df534f5dca8c50bc095ef Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 8 Jan 2020 11:12:58 +0000 Subject: [PATCH] removed the object finder and the pretrained piano examples from nmfmatch help and put it in the example folder --- .../HelpSource/Classes/FluidNMFMatch.schelp | 126 ------------------ .../buffer_compositing/bufcompose-MS-FIR.sc | 4 +- .../Examples/nmf/nmfmatch-object-finding.scd | 74 ++++++++++ .../nmf/nmfmatch-pretrained-piano.scd | 51 +++++++ 4 files changed, 126 insertions(+), 129 deletions(-) create mode 100644 release-packaging/ignore/Examples/nmf/nmfmatch-object-finding.scd create mode 100644 release-packaging/ignore/Examples/nmf/nmfmatch-pretrained-piano.scd diff --git a/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp b/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp index 3aeecc2..1dc37f3 100644 --- a/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp +++ b/release-packaging/HelpSource/Classes/FluidNMFMatch.schelp @@ -182,134 +182,8 @@ z.do({|chan| FluidBufCompose.process(s, ~bases, startChan:chan, numChans: 1, des ) :: -STRONG::Object finder:: - CODE:: -//set some buffers -( -b = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-BaB-SoundscapeGolcarWithDog.wav"); -c = Buffer.new(s); -x = Buffer.new(s); -e = Buffer.new(s); -) - -// train where all objects are present -( -Routine { - FluidBufNMF.process(s,b,130000,150000,0,1, c, x, components:10); - c.query; -}.play; -) - -// wait for the query to print -// then find a component for each item you want to find. You could also sum them. Try to find a component with a good object-to-rest ratio -( - ~dog =4; - {PlayBuf.ar(10,c)[~dog]}.play -) - -( - ~bird = 3; - {PlayBuf.ar(10,c)[~bird]}.play -) - - -// copy at least one other component to a third filter, a sort of left-over channel -( -Routine{ - FluidBufCompose.process(s, x, startChan:~dog, numChans: 1, destination: e); - FluidBufCompose.process(s, x, startChan:~bird, numChans: 1, destStartChan: 1, destination: e, destGain:1); - (0..9).removeAll([~dog,~bird]).do({|chan|FluidBufCompose.process(s,x, startChan:chan, numChans: 1, destStartChan: 2, destination: e, destGain:1)}); - e.query; -}.play; -) -e.plot; - -//using this trained basis we can then see the activation... (wait for 5 seconds before it prints!) -( -{ - var source, blips; - //read the source - source = PlayBuf.ar(2, b); - blips = FluidNMFMatch.kr(source.sum,e,3); - }.plot(5); -) -// ...and use some threshold to 'find' objects... -( -{ - var source, blips; - //read the source - source = PlayBuf.ar(2, b); - blips = Schmidt.kr(FluidNMFMatch.kr(source.sum,e,3),0.5,[10,1,1000]); - }.plot(5); -) - -// ...and use these to sonify them -( -{ - var source, blips, dogs, birds; - //read the source - source = PlayBuf.ar(2, b); - blips = Schmidt.kr(FluidNMFMatch.kr(source.sum,e,3),0.5,[10,1,1000]); - dogs = SinOsc.ar(100,0,Lag.kr(blips[0],0.05,0.15)); - birds = SinOsc.ar(1000,0,Lag.kr(blips[1],0.05,0.05)); - [dogs, birds] + source; - }.play; -) -:: - STRONG::Pretrained piano:: - CODE:: -//load in the sound in and a pretrained basis -( - b = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-SA-UprightPianoPedalWide.wav"); - c = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/filters/piano-dicts.wav"); -) -b.play -c.query - -//use the pretrained bases to compute activations of each notes to drive the amplitude of a resynth -( -{ - var source, resynth; - source = PlayBuf.ar(2, b,loop:1).sum; - resynth = SinOsc.ar((21..108).midicps, 0, FluidNMFMatch.kr(source,c,88,10,4096).madd(0.002)).sum; - [source, resynth] -}.play -) - - -//now sample and hold the same stream to get notes identified, played and sent back via osc -( -{ - var source, resynth, chain, trig, acts; - source = PlayBuf.ar(2,b,loop:1).sum; - - // built in attack detection, delayed until the stable part of the sound - chain = FFT(LocalBuf(256), source); - trig = TDelay.kr(Onsets.kr(chain, 0.5),0.1); - - // samples and holds activation values that are scaled and capped, in effect thresholding them - acts = Latch.kr(FluidNMFMatch.kr(source,c,88,10,4096).linlin(15,20,0,0.1),trig); - - // resynths as in the previous example, with the values sent back to the language - resynth = SinOsc.ar((21..108).midicps, 0, acts).sum; - SendReply.kr(trig, '/activations', acts); - [source, resynth] - // [source, T2A.ar(trig)] - // resynth -}.play -) -// define a receiver for the activations -( - OSCdef(\listener, {|msg| - var data = msg[3..]; - // removes the silent and spits out the indicies as midinote number - data.collect({arg item, i; if (item > 0.01, {i + 21})}).reject({arg item; item.isNil}).postln; - }, '/activations'); -) - -:: STRONG::Strange Resonators:: CODE:: //load the source and declare buffers/arrays diff --git a/release-packaging/ignore/Examples/buffer_compositing/bufcompose-MS-FIR.sc b/release-packaging/ignore/Examples/buffer_compositing/bufcompose-MS-FIR.sc index a270ee5..b13b37a 100644 --- a/release-packaging/ignore/Examples/buffer_compositing/bufcompose-MS-FIR.sc +++ b/release-packaging/ignore/Examples/buffer_compositing/bufcompose-MS-FIR.sc @@ -1,6 +1,5 @@ // A complex example of using composition as an Mid-Side FIR filtering process - // load a stereo buffer and initialise the many destinations ( b = Buffer.read(s,File.realpath(FluidBufCompose.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-SA-UprightPianoPedalWide.wav"); @@ -65,5 +64,4 @@ FluidBufCompose.process(s,e, gain: -3.0.dbamp * -1.0, destination: f, destStartC f.play; // compare with the original -b.play; -:: +b.play; \ No newline at end of file diff --git a/release-packaging/ignore/Examples/nmf/nmfmatch-object-finding.scd b/release-packaging/ignore/Examples/nmf/nmfmatch-object-finding.scd new file mode 100644 index 0000000..7ab2c3d --- /dev/null +++ b/release-packaging/ignore/Examples/nmf/nmfmatch-object-finding.scd @@ -0,0 +1,74 @@ +// using NMF, splitting a small portion, then associating components to targets, then thresholding on these target's activations to find objects. + +//set some buffers +( +b = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-BaB-SoundscapeGolcarWithDog.wav"); +c = Buffer.new(s); +x = Buffer.new(s); +e = Buffer.new(s); +) + +// train where all objects are present +( +Routine { + FluidBufNMF.process(s,b,130000,150000,0,1, c, x, components:10); + c.query; +}.play; +) + +// wait for the query to print +// then find a component for each item you want to find. You could also sum them. Try to find a component with a good object-to-rest ratio +( + ~dog =1; + {PlayBuf.ar(10,c)[~dog]}.play +) + +( + ~bird = 3; + {PlayBuf.ar(10,c)[~bird]}.play +) + + +// copy at least one other component to a third filter, a sort of left-over channel +( +Routine{ + FluidBufCompose.process(s, x, startChan:~dog, numChans: 1, destination: e); + FluidBufCompose.process(s, x, startChan:~bird, numChans: 1, destStartChan: 1, destination: e, destGain:1); + (0..9).removeAll([~dog,~bird]).do({|chan|FluidBufCompose.process(s,x, startChan:chan, numChans: 1, destStartChan: 2, destination: e, destGain:1)}); + e.query; +}.play; +) +e.plot; + +//using this trained basis we can then see the activation... (wait for 5 seconds before it prints!) +( +{ + var source, blips; + //read the source + source = PlayBuf.ar(2, b); + blips = FluidNMFMatch.kr(source.sum,e,3); + }.plot(5); +) + +// ...and use some threshold to 'find' objects... +( +{ + var source, blips; + //read the source + source = PlayBuf.ar(2, b); + blips = Schmidt.kr(FluidNMFMatch.kr(source.sum,e,3),0.5,[10,1,1000]); + }.plot(5); +) + +// ...and use these to sonify them +( +{ + var source, blips, dogs, birds; + //read the source + source = PlayBuf.ar(2, b); + blips = Schmidt.kr(FluidNMFMatch.kr(source.sum,e,3),0.5,[10,1,1000]); + dogs = SinOsc.ar(100,0,Lag.kr(blips[0],0.05,0.15)); + birds = SinOsc.ar(1000,0,Lag.kr(blips[1],0.05,0.05)); + [dogs, birds] + source; + }.play; +) \ No newline at end of file diff --git a/release-packaging/ignore/Examples/nmf/nmfmatch-pretrained-piano.scd b/release-packaging/ignore/Examples/nmf/nmfmatch-pretrained-piano.scd new file mode 100644 index 0000000..d630387 --- /dev/null +++ b/release-packaging/ignore/Examples/nmf/nmfmatch-pretrained-piano.scd @@ -0,0 +1,51 @@ +// Using an 88-components piano base to do polyphonic pitch tracking + +//load in the sound in and a pretrained basis +( + b = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-SA-UprightPianoPedalWide.wav"); + c = Buffer.read(s,File.realpath(FluidNMFMatch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/filters/piano-dicts.wav"); +) +b.play +c.query + +//use the pretrained bases to compute activations of each notes to drive the amplitude of a resynth +( +{ + var source, resynth; + source = PlayBuf.ar(2, b,loop:1).sum; + resynth = SinOsc.ar((21..108).midicps, 0, FluidNMFMatch.kr(source,c,88,10,4096).madd(0.002)).sum; + [source, resynth] +}.play +) + + +//now sample and hold the same stream to get notes identified, played and sent back via osc +( +{ + var source, resynth, chain, trig, acts; + source = PlayBuf.ar(2,b,loop:1).sum; + + // built in attack detection, delayed until the stable part of the sound + chain = FFT(LocalBuf(256), source); + trig = TDelay.kr(Onsets.kr(chain, 0.5),0.1); + + // samples and holds activation values that are scaled and capped, in effect thresholding them + acts = Latch.kr(FluidNMFMatch.kr(source,c,88,10,4096).linlin(15,20,0,0.1),trig); + + // resynths as in the previous example, with the values sent back to the language + resynth = SinOsc.ar((21..108).midicps, 0, acts).sum; + SendReply.kr(trig, '/activations', acts); + [source, resynth] + // [source, T2A.ar(trig)] + // resynth +}.play +) + +// define a receiver for the activations +( + OSCdef(\listener, {|msg| + var data = msg[3..]; + // removes the silent and spits out the indicies as midinote number + data.collect({arg item, i; if (item > 0.01, {i + 21})}).reject({arg item; item.isNil}).postln; + }, '/activations'); +) \ No newline at end of file