removed the object finder and the pretrained piano examples from nmfmatch help and put it in the example folder
parent
ca34201054
commit
e407c2efb8
@ -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;
|
||||||
|
)
|
||||||
@ -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');
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue