Merge pull request #55 from flucoma/topic/fix-KrToBuf

Topic/fix kr to buf
nix
Ted Moore 4 years ago committed by GitHub
commit 812a6de010
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,45 +1,75 @@
FluidKrToBuf {
*kr {
arg krStream, buffer;
arg krStream, buffer, krStartChan = 0, krNumChans = -1, destStartFrame = 0;
var endChan;
// fix -1 default
if(krNumChans == -1,{krNumChans = krStream.numChannels - krStartChan});
// what is the last channel that will be used
endChan = (krStartChan + krNumChans) - 1;
if(buffer.isKindOf(Buffer).or(buffer.isKindOf(LocalBuf)),{
if(buffer.numFrames == 0) {"FluidKrToBuf:kr Buffer has 0 frames".warn};
if(buffer.numFrames > 1000) {
Error("FluidKrToBuf:kr Buffer is % frames. This is probably not the buffer you intended.".format(buffer.numFrames)).throw;
// sanity check
if(buffer.numFrames == 0){"% Buffer has 0 frames".format(this.class).warn};
// oopsie check
if(buffer.numFrames > 1000){
Error("% Buffer is % frames. This is probably not the buffer you intended.".format(this.class,buffer.numFrames)).throw;
};
// out of bounds check
if((destStartFrame + krNumChans) > buffer.numFrames,{
Error("% (destStartFrame + krNumChans) > buffer.numFrames".format(this.class)).throw;
});
});
^krStream.numChannels.do{
arg i;
BufWr.kr(krStream[i], buffer, i);
^(krStartChan..endChan).do{
arg kr_i, i;
BufWr.kr(krStream[kr_i], buffer, destStartFrame + i);
}
}
}
FluidBufToKr {
*kr {
arg buffer, numFrames = -1;
arg buffer, startFrame = 0, numFrames = -1;
if((buffer.isKindOf(Buffer).or(buffer.isKindOf(LocalBuf))).not.and(numFrames.isNil),{
Error("FluidBufToKr:kr needs to be passed either an existing buffer or an OutputProxy and a number of frames for the buffer that will be supplied").throw;
});
// out of bounds check
if(startFrame < 0,{Error("% startFrame must be >= 0".format(this.class)).throw;});
if(buffer.isKindOf(Buffer) or: {buffer.isKindOf(LocalBuf)},{
// fix default -1
if(numFrames == -1,{numFrames = buffer.numFrames - startFrame});
if(numFrames == -1,{
numFrames = buffer.numFrames;
// dummy check
if(numFrames < 1,{Error("% numFrames must be >= 1".format(this.class)).throw});
// out of bounds check
if((startFrame+numFrames) > buffer.numFrames,{Error("% (startFrame + numFrames) > buffer.numFrames".format(this.class)).throw;});
},{
// make sure the numFrames give is a positive integer
if((numFrames < 1) || (numFrames.isInteger.not),{
Error("% if no buffer is specified, numFrames must be a value >= 1.".format(this.class)).throw;
});
});
if(numFrames == 0) {"FluidKrToBuf:kr indicated numFrames is zero.".warn};
// oopsie check
if(numFrames > 1000) {
Error("FluidKrToBuf: Buffer is indicated to have % frames. This is probably not the buffer you intended.".format(numFrames)).throw;
Error("%: numframes is % frames. This is probably not what you intended.".format(this.class, numFrames)).throw;
};
if(numFrames > 1,{
^numFrames.collect{
arg i;
BufRd.kr(1,buffer,i,0,0);
BufRd.kr(1,buffer,i+startFrame,0,0);
}
},{
^BufRd.kr(1,buffer,0,0,0);
^BufRd.kr(1,buffer,startFrame,0,0);
});
}
}

@ -4,7 +4,7 @@ categories:: Libraries>FluidCorpusManipulation
related:: Classes/FluidKrToBuf
DESCRIPTION::
Helper pseudo UGen for reading data out of a buffer to a Kr stream. It only reads one-channel buffers, converting them to a Kr stream with as many channels as the number of frames that the buffer is long.
Helper pseudo UGen for reading data out of a buffer to a Kr stream. It only reads one-channel buffers, converting them to a Kr stream.
CLASSMETHODS::
@ -12,10 +12,13 @@ METHOD:: kr
Initialize an instance of this pseudo UGen
ARGUMENT:: buffer
The link::Classes/Buffer:: that this pseudo UGen will read out of. Must be a one-channel buffer.
Either a link::Classes/Buffer:: object or an index opointing to a buffer that this pseudo UGen will read out of. Must be a one-channel buffer.
ARGUMENT:: startFrame
Offset of reading position in the buffer. The default is 0.
ARGUMENT:: numFrames
How many frames the buffer is that will evenutally passed. If providing a buffer directly (instead of as an argument to a SynthDef), the default of -1 will get the number of frames from the buffer passed.
Number of frames to read from the buffer. Needs to be set, if buffer is not a code::Buffer:: object but a buffer index. If code::-1::, read whole buffer starting at code::startFrame::. The default is -1.
returns:: a Kr stream that has the same number of channels as frames in the link::Classes/Buffer::.
@ -24,37 +27,51 @@ INSTANCEMETHODS::
EXAMPLES::
code::
// make a buffer with some data in it
~buf = Buffer.loadCollection(s,[0,1,2,3,4,7]);
// play it on the server and read out of this buffer!
// fill a 1-channel buffer with 7 numbers
~buf = Buffer.loadCollection(s,{exprand(100,4000)} ! 7);
// in a synth, read those numbers out of the buffer and get them as a control stream
(
{
var sig = FluidBufToKr.kr(~buf);
~synth = {
arg buf;
var freqs = FluidBufToKr.kr(buf,numFrames:7);
var sig = SinOsc.ar(freqs.lag(0.03)) * 0.1;
sig.poll;
}.play;
Splay.ar(sig);
}.play(args:[\buf,~buf]);
)
// =============== passing a buffer as an argument ======================
// then you can change what's in the buffer and it will get read out by the synth
~buf.setn(0,{exprand(100,4000)} ! 7);
::
Use with other FluCoMa objects:
code::
// create an neural network for classification
~mlp = FluidMLPClassifier(s);
// load a model that has been pre-trained to classify between a tone and noise, simple, i know, but...
~mlp.read(FluidFilesPath("../Resources/bufToKrExample.json"));
// create a synth that both writes into a buffer (with FluidKrToBuf) and reads
// out of the same buffer (with FluidBufToKr)
// can be used to demonstrate that...
(
~synth = {
arg buf = 999;
FluidKrToBuf.kr(SinOsc.kr(Array.fill(5,{rrand(0.0,1.0)})),buf);
{
var input_buf = LocalBuf(7);
var out_buf = LocalBuf(1);
var sig = Select.ar(ToggleFF.kr(Dust.kr(1)),[SinOsc.ar(440),PinkNoise.ar]);
var analysis = FluidSpectralShape.kr(sig);
FluidKrToBuf.kr(analysis,input_buf);
// you need to specify the 5 so the synth here will know how many channels to make
// the output proxy
FluidBufToKr.kr(buf,5).poll;
// the output prediction is written into a buffer
~mlp.kr(Impulse.kr(30),input_buf,out_buf);
// and FluidBufToKr can be used to read the prediction out into a control rate stream
FluidBufToKr.kr(out_buf).poll;
sig.dup * -30.dbamp
}.play;
// you should see all zeros! (unless your buffer #999 has something in it already!)
)
// ...then after it is running, instantiate the buffer
~buffer = Buffer.alloc(s,5);
// ...then send it to the buffer
~synth.set(\buf,~buffer);
// you should be able to see the sine oscillators now!
::

@ -4,7 +4,7 @@ categories:: Libraries>FluidCorpusManipulation
related:: Classes/FluidBufToKr
DESCRIPTION::
Helper pseudo UGen for writing data into a buffer from a Kr stream. It only works with one-channel buffers. The number of frames in the link::Classes/Buffer:: must be the same as the number of channels in the Kr stream.
Helper pseudo UGen for writing data into a buffer from a Kr stream. It only works with one-channel buffers.
CLASSMETHODS::
@ -15,34 +15,65 @@ ARGUMENT:: krStream
The Kr stream to write into the buffer.
ARGUMENT:: buffer
The link::Classes/Buffer:: to write the Kr stream into.
The buffer to write the Kr stream into. Can be either a link::Classes/Buffer:: object, or an index poiting to a buffer.
returns:: Nothing.
ARGUMENT:: krStartChan
The channel in the code::krStream:: to begin the reading from. The default is 0.
ARGUMENT:: krNumChans
The number of channels in the code::krStream:: to read from starting at code::krStartChan:: The default of -1 will read from code::krStartChan:: to the max number of channels in the code::krStream::.
ARGUMENT:: destStartFrame
The frame in the code::buffer:: to begin writing into. The default is 0.
returns:: This class.
INSTANCEMETHODS::
EXAMPLES::
code::
(
// FluidKrToBuf test
s.waitForBoot{
Routine{
var buf = Buffer.alloc(s,5);
~synth = {
var buf = LocalBuf(512).clear;
var sig = SinOsc.ar([440,441]);
var lfos = Array.fill(512,{arg i; SinOsc.ar(i.linlin(0,511,0.01,0.2))});
FluidKrToBuf.kr(lfos,buf);
sig = Shaper.ar(buf,sig);
sig.dup * -40.dbamp;
}.scope;
)
::
Use with other FluCoMa objects:
code::
s.sync;
// make a new dataset
~ds = FluidDataSet(s);
{
var sig = SinOsc.kr(rrand(1.0.dup(buf.numFrames),4.0));
FluidKrToBuf.kr(sig,buf);
}.play;
// run a synth with varying sounds and an mfcc analysis
(
~synth = {
arg t_trig;
var buf = LocalBuf(13);
var n = 7;
var sig = BPF.ar(PinkNoise.ar.dup(n),LFDNoise1.kr(2.dup(n)).exprange(100,4000)).sum * -20.dbamp;
var mfccs = FluidMFCC.kr(sig,buf.numFrames,startCoeff:1,maxNumCoeffs:buf.numFrames);
1.wait;
// write the real-time mfcc analysis into this buffer so that...
FluidKrToBuf.kr(mfccs,buf);
defer{buf.plot};
}.play;
}
// it can be added to the dataset from that buffer by sending a trig to the synth
FluidDataSetWr.kr(~ds,"point-",PulseCount.kr(t_trig),buf:buf,trig:t_trig);
sig.dup;
}.play;
)
// send a bunch of triggers and...
~synth.set(\t_trig,1);
// see how your dataset grows
~ds.print;
::

@ -0,0 +1,107 @@
{
"labels": {
"labels": [
"tone",
"noise"
],
"rows": 2
},
"mlp": {
"layers": [
{
"activation": 1,
"biases": [
9.475189836135217e-245,
-7.312978302687739e-296,
0.0,
0.0,
0.0
],
"cols": 5,
"rows": 7,
"weights": [
[
-0.7070957130289968,
0.2529529084252004,
-0.6315006118399392,
0.2641365029014226,
-0.11879484878940468
],
[
-0.5210842572299229,
0.25356340881888756,
0.04200241621968997,
0.12583197506255497,
0.2845264672854667
],
[
0.36148051326296066,
0.614748588906755,
0.24204178015383798,
0.6087291285844215,
0.5802812834026664
],
[
-0.05847754423619632,
-0.16475294200213061,
-0.6962199018410693,
0.48955391140174614,
0.3708040237508281
],
[
0.04633987154978883,
0.02745889671058346,
-0.16487516786286913,
0.03808304248049002,
-0.33594219806125813
],
[
-0.3974517302751846,
0.4680556811476128,
-0.6125775823484346,
-0.5770487854150471,
-0.6399818221697359
],
[
-0.6405756468993841,
-0.65821443359875,
-0.1166924540077695,
0.21767428398943345,
0.3338702030112145
]
]
},
{
"activation": 1,
"biases": [
-0.3628999139757816,
-0.42250374321781475
],
"cols": 2,
"rows": 5,
"weights": [
[
-0.31804841180355814,
-0.46839296834399485
],
[
-4.2805091183479895,
4.474227050298208
],
[
0.4747799633725462,
0.4122869489228666
],
[
0.5463246485585964,
0.04662010562772569
],
[
3.913863778074305,
-3.7226634012685995
]
]
}
]
}
}

@ -93,7 +93,7 @@ s.waitForBoot{
)
(
// FluidBufToKr
// FluidBufToKr should throw error
s.waitForBoot{
Routine{
@ -154,7 +154,7 @@ s.waitForBoot{
Routine{
~synth = {
arg buf;
FluidBufToKr.kr(buf,5).poll;
FluidBufToKr.kr(buf,numFrames:5).poll;
}.play;
2.wait;
@ -197,7 +197,7 @@ s.waitForBoot{
arg buf = 999;
FluidKrToBuf.kr(SinOsc.kr(Array.fill(5,{rrand(0.0,1.0)})),buf);
FluidBufToKr.kr(buf,5).poll; ////////// this will work becaues it knows how many frames the buffer will be
FluidBufToKr.kr(buf,numFrames:5).poll; ////////// this will work becaues it knows how many frames the buffer will be
}.play;
2.wait;
@ -208,3 +208,155 @@ s.waitForBoot{
}.play;
};
)
// test start frame:
(
// should skip the 0
s.waitForBoot{
Routine{
var buf = Buffer.loadCollection(s,[0,1,2,3,4,7]);
s.sync;
{
var sig = FluidBufToKr.kr(buf,1);
sig.poll;
}.play;
}.play;
}
)
(
// should be 2,3,4
s.waitForBoot{
Routine{
var buf = Buffer.loadCollection(s,[0,1,2,3,4,7]);
s.sync;
{
var sig = FluidBufToKr.kr(buf,2,3);
sig.poll;
}.play;
}.play;
}
)
(
// last four slots should be 0
s.waitForBoot{
Routine{
var buf = Buffer.loadCollection(s,0.dup(10));
s.sync;
{
FluidKrToBuf.kr(LFDNoise3.kr(1.dup(6)),buf);
}.play;
1.wait;
// defer{buf.plot};
buf.loadToFloatArray(action:{
arg vals;
vals.postln;
});
}.play;
}
)
(
// middle slots should be not zero
s.waitForBoot{
Routine{
var buf = Buffer.loadCollection(s,0.dup(4));
s.sync;
{
FluidKrToBuf.kr(LFDNoise3.kr(1.dup(2)),buf,destStartFrame:1);
}.play;
1.wait;
// defer{buf.plot};
buf.loadToFloatArray(action:{
arg vals;
vals.postln;
});
}.play;
}
)
(
// should throw error
s.waitForBoot{
Routine{
var buf = Buffer.loadCollection(s,0.dup(4));
s.sync;
{
FluidKrToBuf.kr(LFDNoise3.kr(1.dup(2)),buf,destStartFrame:3);
}.play;
1.wait;
// defer{buf.plot};
buf.loadToFloatArray(action:{
arg vals;
vals.postln;
});
}.play;
}
)
(
// should be 0,0,200,3000,0,0
s.waitForBoot{
Routine{
var buf = Buffer.alloc(s,7);
s.sync;
{
var sig = 3.collect{arg i; DC.kr((i+1)*100)};
// sig.poll;
FluidKrToBuf.kr(sig,buf,1,2,2);
}.play;
1.wait;
buf.loadToFloatArray(action:{
arg vals;
vals.postln;
});
}.play;
}
)
(
// should be 100,200,300,400
s.waitForBoot{
Routine{
var buf = Buffer.alloc(s,4);
s.sync;
{
var sig = 4.collect{arg i; DC.kr((i+1)*100)};
// sig.poll;
FluidKrToBuf.kr(sig,buf);
}.play;
1.wait;
buf.loadToFloatArray(action:{
arg vals;
vals.postln;
});
}.play;
}
)

Loading…
Cancel
Save