You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
349 lines
9.3 KiB
Plaintext
349 lines
9.3 KiB
Plaintext
// first run this code - it will sample 40 random points
|
|
// you can add more points if you want
|
|
// you must 'train' it
|
|
// then run the playing target at line 335 below and press 'predict'
|
|
(
|
|
Window.closeAll;
|
|
s.waitForBoot{
|
|
Task{
|
|
var win = Window(bounds:Rect(100,100,1000,800));
|
|
var label_width = 120;
|
|
var item_width = 300;
|
|
var mfcc_multslider;
|
|
var nMFCCs = 13;
|
|
var mfccbuf = Buffer.alloc(s,nMFCCs);
|
|
var parambuf = Buffer.alloc(s,3);
|
|
var id_counter = 0;
|
|
var continuous_training = false;
|
|
var mfcc_ds = FluidDataSet(s);
|
|
var param_ds = FluidDataSet(s);
|
|
var mfcc_ds_norm = FluidDataSet(s);
|
|
var param_ds_norm = FluidDataSet(s);
|
|
var scaler_params = FluidNormalize(s);
|
|
var scaler_mfcc = FluidNormalize(s);
|
|
var nn = FluidMLPRegressor(s,[3,3],FluidMLPRegressor.sigmoid,FluidMLPRegressor.sigmoid,learnRate:0.05,batchSize:5,validation:0);
|
|
var synth, loss_st;
|
|
var param_sliders = Array.newClear(3);
|
|
var statsWinSl, hidden_tf, batchSize_nb, momentum_nb, learnRate_nb, maxIter_nb, outAct_pum, act_pum;
|
|
var add_point = {
|
|
var id = "point-%".format(id_counter);
|
|
mfcc_ds.addPoint(id,mfccbuf);
|
|
param_ds.addPoint(id,parambuf);
|
|
id_counter = id_counter + 1;
|
|
};
|
|
var train = {
|
|
scaler_mfcc.fitTransform(mfcc_ds,mfcc_ds_norm,{
|
|
scaler_params.fitTransform(param_ds,param_ds_norm,{
|
|
// mfcc_ds.print;
|
|
// param_ds.print;
|
|
nn.fit(mfcc_ds_norm,param_ds_norm,{
|
|
arg loss;
|
|
// loss.postln;
|
|
defer{loss_st.string_("loss: %".format(loss))};
|
|
if(continuous_training,{
|
|
train.value;
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|
|
var display_mlp_params = {
|
|
var params = nn.prGetParams;
|
|
var n_layers = params[1];
|
|
var layers_string = "";
|
|
|
|
// params.postln;
|
|
|
|
n_layers.do({
|
|
arg i;
|
|
if(i > 0,{layers_string = "% ".format(layers_string)});
|
|
layers_string = "%%".format(layers_string,params[2+i]);
|
|
});
|
|
|
|
nn.maxIter_(maxIter_nb.value);
|
|
nn.learnRate_(learnRate_nb.value);
|
|
nn.momentum_(momentum_nb.value);
|
|
nn.batchSize_(batchSize_nb.value);
|
|
|
|
defer{
|
|
hidden_tf.string_(layers_string);
|
|
act_pum.value_(nn.activation);
|
|
outAct_pum.value_(nn.outputActivation);
|
|
/* maxIter_nb.value_(nn.maxIter);
|
|
learnRate_nb.value_(nn.learnRate);
|
|
momentum_nb.value_(nn.momentum);
|
|
batchSize_nb.value_(nn.batchSize);*/
|
|
};
|
|
};
|
|
|
|
~in_bus = Bus.audio(s);
|
|
|
|
s.sync;
|
|
|
|
synth = {
|
|
arg vol = -15, isPredicting = 0, avg_win = 0, smooth_params = 0;
|
|
var params = FluidStats.kr(FluidBufToKr.kr(parambuf),ControlRate.ir * smooth_params * isPredicting)[0];
|
|
var msig = SinOsc.ar(params[1],0,params[2] * params[1]);
|
|
var csig = SinOsc.ar(params[0] + msig);
|
|
// var sound_in = SoundIn.ar(0);
|
|
var sound_in = In.ar(~in_bus);
|
|
var analysis_sig, mfccs, trig, mfccbuf_norm, parambuf_norm;
|
|
|
|
csig = BLowPass4.ar(csig,16000);
|
|
csig = BHiPass4.ar(csig,40);
|
|
analysis_sig = Select.ar(isPredicting,[csig,sound_in]);
|
|
mfccs = FluidMFCC.kr(analysis_sig,nMFCCs,startCoeff:1,maxNumCoeffs:nMFCCs);
|
|
trig = Impulse.kr(30);
|
|
mfccbuf_norm = LocalBuf(nMFCCs);
|
|
parambuf_norm = LocalBuf(3);
|
|
|
|
mfccs = FluidStats.kr(mfccs,ControlRate.ir * avg_win)[0];
|
|
FluidKrToBuf.kr(mfccs,mfccbuf);
|
|
|
|
scaler_mfcc.kr(trig * isPredicting,mfccbuf,mfccbuf_norm);
|
|
nn.kr(trig * isPredicting,mfccbuf_norm,parambuf_norm);
|
|
scaler_params.kr(trig * isPredicting,parambuf_norm,parambuf,invert:1);
|
|
|
|
SendReply.kr(trig * isPredicting,"/params",params);
|
|
SendReply.kr(trig,"/mfccs",mfccs);
|
|
|
|
csig = csig.dup;
|
|
csig * Select.kr(isPredicting,[vol.dbamp,FluidLoudness.kr(sound_in)[0].dbamp]);
|
|
}.play;
|
|
|
|
s.sync;
|
|
|
|
win.view.decorator_(FlowLayout(Rect(0,0,win.bounds.width,win.bounds.height)));
|
|
|
|
|
|
param_sliders[0] = EZSlider(win,Rect(0,0,item_width,20),"carrier freq",\freq.asSpec,{arg sl; parambuf.set(0,sl.value)},440,true,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
param_sliders[1] = EZSlider(win,Rect(0,0,item_width,20),"mod freq",\freq.asSpec,{arg sl; parambuf.set(1,sl.value)},100,true,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
param_sliders[2] = EZSlider(win,Rect(0,0,item_width,20),"index",ControlSpec(0,20),{arg sl; parambuf.set(2,sl.value)},10,true,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
EZSlider(win,Rect(0,0,item_width,20),"params avg smooth",nil.asSpec,{arg sl; synth.set(\avg_win,sl.value)},0,true,label_width);
|
|
win.view.decorator.nextLine;
|
|
|
|
StaticText(win,Rect(0,0,label_width,20)).string_("% MFCCs".format(nMFCCs));
|
|
win.view.decorator.nextLine;
|
|
|
|
statsWinSl = EZSlider(win,Rect(0,0,item_width,20),"mfcc avg smooth",nil.asSpec,{arg sl; synth.set(\avg_win,sl.value)},0,true,label_width);
|
|
win.view.decorator.nextLine;
|
|
|
|
mfcc_multslider = MultiSliderView(win,Rect(0,0,item_width,200))
|
|
.size_(nMFCCs)
|
|
.elasticMode_(true);
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
Button(win,Rect(0,0,100,20))
|
|
.states_([["Add Point"]])
|
|
.action_{
|
|
add_point.value;
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
// spacer
|
|
StaticText(win,Rect(0,0,label_width,20));
|
|
win.view.decorator.nextLine;
|
|
|
|
// MLP Parameters
|
|
StaticText(win,Rect(0,0,label_width,20)).align_(\right).string_("hidden layers");
|
|
hidden_tf = TextField(win,Rect(0,0,item_width - label_width,20))
|
|
.string_(nn.hiddenLayers.asString.replace(", "," ")[2..(nn.hiddenLayers.asString.size-3)])
|
|
.action_{
|
|
arg tf;
|
|
var hidden_ = "[%]".format(tf.string.replace(" ",",")).interpret;
|
|
nn.hiddenLayers_(hidden_);
|
|
// nn.prGetParams.postln;
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
StaticText(win,Rect(0,0,label_width,20)).align_(\right).string_("activation");
|
|
act_pum = PopUpMenu(win,Rect(0,0,item_width - label_width,20))
|
|
.items_(["identity","sigmoid","relu","tanh"])
|
|
.value_(nn.activation)
|
|
.action_{
|
|
arg pum;
|
|
nn.activation_(pum.value);
|
|
// nn.prGetParams.postln;
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
StaticText(win,Rect(0,0,label_width,20)).align_(\right).string_("output activation");
|
|
outAct_pum = PopUpMenu(win,Rect(0,0,item_width - label_width,20))
|
|
.items_(["identity","sigmoid","relu","tanh"])
|
|
.value_(nn.outputActivation)
|
|
.action_{
|
|
arg pum;
|
|
nn.outputActivation_(pum.value);
|
|
|
|
// nn.prGetParams.postln;
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
maxIter_nb = EZNumber(win,Rect(0,0,item_width,20),"max iter",ControlSpec(1,10000,step:1),{
|
|
arg nb;
|
|
nn.maxIter_(nb.value.asInteger);
|
|
|
|
// nn.prGetParams.postln;
|
|
},nn.maxIter,false,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
learnRate_nb = EZNumber(win,Rect(0,0,item_width,20),"learn rate",ControlSpec(0.001,1.0),{
|
|
arg nb;
|
|
nn.learnRate_(nb.value);
|
|
|
|
// nn.prGetParams.postln;
|
|
},nn.learnRate,false,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
momentum_nb = EZNumber(win,Rect(0,0,item_width,20),"momentum",ControlSpec(0,1),{
|
|
arg nb;
|
|
nn.momentum_(nb.value);
|
|
|
|
// nn.prGetParams.postln;
|
|
},nn.momentum,false,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
batchSize_nb = EZNumber(win,Rect(0,0,item_width,20),"batch size",ControlSpec(1,1000,step:1),{
|
|
arg nb;
|
|
nn.batchSize_(nb.value.asInteger);
|
|
|
|
// nn.prGetParams.postln;
|
|
},nn.batchSize,false,label_width);
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
Button(win,Rect(0,0,100,20))
|
|
.states_([["Train"]])
|
|
.action_{
|
|
train.value;
|
|
};
|
|
|
|
Button(win,Rect(0,0,200,20))
|
|
.states_([["Continuous Training Off"],["Continuous Training On"]])
|
|
.action_{
|
|
arg but;
|
|
continuous_training = but.value.asBoolean;
|
|
train.value;
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
loss_st = StaticText(win,Rect(0,0,item_width,20)).string_("loss:");
|
|
|
|
win.view.decorator.nextLine;
|
|
Button(win,Rect(0,0,100,20))
|
|
.states_([["Not Predicting"],["Predicting"]])
|
|
.action_{
|
|
arg but;
|
|
synth.set(\isPredicting,but.value);
|
|
};
|
|
|
|
win.view.decorator.nextLine;
|
|
|
|
Button(win,Rect(0,0,100,20))
|
|
.states_([["Save"]])
|
|
.action_{
|
|
Dialog.savePanel({
|
|
arg path;
|
|
nn.dump{
|
|
arg mlp_dict;
|
|
scaler_params.dump{
|
|
arg scaler_params_dict;
|
|
scaler_mfcc.dump{
|
|
arg scaler_mfcc_dict;
|
|
var dict = Dictionary.new;
|
|
dict['mlp'] = mlp_dict;
|
|
dict['scaler_params'] = scaler_params_dict;
|
|
dict['scaler_mfcc'] = scaler_mfcc_dict;
|
|
|
|
dict.writeArchive(path);
|
|
};
|
|
};
|
|
};
|
|
|
|
});
|
|
};
|
|
|
|
Button(win,Rect(0,0,100,20))
|
|
.states_([["Open"]])
|
|
.action_{
|
|
Dialog.openPanel({
|
|
arg path;
|
|
var dict = Object.readArchive(path);
|
|
|
|
nn.load(dict['mlp'].postln,{display_mlp_params.value});
|
|
scaler_params.load(dict['scaler_params'].postln);
|
|
scaler_mfcc.load(dict['scaler_mfcc'].postln);
|
|
});
|
|
};
|
|
|
|
win.bounds_(win.view.decorator.used);
|
|
win.front;
|
|
|
|
OSCdef(\mfccs,{
|
|
arg msg;
|
|
// msg.postln;
|
|
defer{
|
|
mfcc_multslider.value_(msg[3..].linlin(-40,40,0,1));
|
|
};
|
|
},"/mfccs");
|
|
|
|
OSCdef(\params,{
|
|
arg msg;
|
|
// msg.postln;
|
|
defer{
|
|
param_sliders.do{
|
|
arg sl, i;
|
|
sl.value_(msg[3 + i]);
|
|
};
|
|
};
|
|
},"/params");
|
|
|
|
s.sync;
|
|
|
|
statsWinSl.valueAction_(0.0);
|
|
|
|
40.do{
|
|
var cfreq = exprand(100.0,1000.0);
|
|
var mfreq = exprand(100.0,min(cfreq,500.0));
|
|
var index = rrand(0.0,8.0);
|
|
var arr = [cfreq,mfreq,index];
|
|
parambuf.setn(0,arr);
|
|
0.1.wait;
|
|
add_point.value;
|
|
0.1.wait;
|
|
arr.postln;
|
|
param_ds.print;
|
|
"\n\n".postln;
|
|
};
|
|
|
|
}.play(AppClock);
|
|
};
|
|
)
|
|
|
|
(
|
|
Routine{
|
|
~path = FluidFilesPath("Tremblay-CEL-GlitchyMusicBoxMelo.wav");
|
|
~test_buf = Buffer.readChannel(s,~path,channels:[0]);
|
|
s.sync;
|
|
{
|
|
var sig = PlayBuf.ar(1,~test_buf,BufRateScale.ir(~test_buf),doneAction:2);
|
|
Out.ar(0,sig);
|
|
sig;
|
|
}.play(outbus:~in_bus);
|
|
}.play;
|
|
)
|
|
|
|
s.record;
|
|
s.stopRecording |