diff --git a/release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, 01).scd b/release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, 01).scd deleted file mode 100644 index 588c7da..0000000 --- a/release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, 01).scd +++ /dev/null @@ -1,285 +0,0 @@ -/* -================================================= -| | -| LOAD AND ANALYZE THE SOURCE MATERIAL | -| | -================================================= -*/ - -( -// ============= 1. LOAD SOME FILES TO BE THE SOURCE MATERIAL =================== -// put your own folder path here! it's best if they're all mono for now. -~source_files_folder = "/Users/macprocomputer/Desktop/audio_files/"; - -~loader = FluidLoadFolder(~source_files_folder); // this is a nice helper class that will load a bunch of files from a folder. -~loader.play(s,{ // .play will cause it to *actually* do the loading - - // we really just want access to the buffer. there is also a .index with some info about the files - // but we'll igore that for now - ~source_buf = ~loader.buffer; - - "all files loaded".postln; - - // double check if they're all mono? the buffer of the loaded files will have as many channels as the file with the most channels - // so if this is 1, then we know all the files were mono. - "num channels: %".format(~source_buf.numChannels).postln -}); -) - -~loader.buffer -~loader.index.dopostln -// ~source_buf.plot -FluidBufNMF - -( -// ==================== 2. SLICE THE SOURCE MATERIAL ACCORDING TO SPECTRAL ONSETS ========================= -~source_indices_buf = Buffer(s); // a buffer for writing the indices into -FluidBufOnsetSlice.process(s,~source_buf,indices:~source_indices_buf,metric:9,threshold:0.15,minSliceLength:9,action:{ // do the slicing - ~source_indices_buf.loadToFloatArray(action:{ - arg indices_array; - - // post the results so that you can tweak the parameters and get what you want - "found % slices".format(indices_array.size-1).postln; - "average length: % seconds".format((~source_buf.duration / (indices_array.size-1)).round(0.001)).postln; - }) -}); -) - -( -// =========================== 3. DEFINE A FUNCTION FOR DOING THE ANALYSIS =================================== -~analyze_to_dataset = { - arg audio_buffer, slices_buffer, action; // the audio buffer to analyze, a buffer with the slice points, and an action to execute when done - ~nmfccs = 13; - Routine{ - var features_buf = Buffer(s); // a buffer for writing the MFCC analyses into - var stats_buf = Buffer(s); // a buffer for writing the statistical summary of the MFCC analyses into - var flat_buf = Buffer(s); // a buffer for writing only he mean MFCC values into - var dataset = FluidDataSet(s); // the dataset that all of these analyses will be stored in - slices_buffer.loadToFloatArray(action:{ // get the indices from the server loaded down to the language - arg slices_array; - - // iterate over each index in this array, paired with this next neighbor so that we know where to start - // and stop the analysis - slices_array.doAdjacentPairs{ - arg start_frame, end_frame, slice_index; - var num_frames = end_frame - start_frame; - - "analyzing slice: % / %".format(slice_index + 1,slices_array.size - 1).postln; - - // mfcc analysis, hop over that 0th coefficient because it relates to loudness and here we want to focus on timbre - FluidBufMFCC.process(s,audio_buffer,start_frame,num_frames,features:features_buf,startCoeff:1,numCoeffs:~nmfccs).wait; - - // get a statistical summary of the MFCC analysis for this slice - FluidBufStats.process(s,features_buf,stats:stats_buf).wait; - - // extract and flatten just the 0th frame (numFrames:1) of the statistical summary (because that is the mean) - FluidBufFlatten.process(s,stats_buf,numFrames:1,destination:flat_buf).wait; - - // now that the means are extracted and flattened, we can add this datapoint to the dataset: - dataset.addPoint("slice-%".format(slice_index),flat_buf); - }; - }); - - action.value(dataset); // execute the function and pass in the dataset that was created! - }.play; -}; -) - -( -// =================== 4. DO THE ANALYSIS ===================== -~analyze_to_dataset.(~source_buf,~source_indices_buf,{ // pass in the audio buffer of the source, and the slice points - arg ds; - ~source_dataset = ds; // set the ds to a global variable so we can access it later - ~source_dataset.print; -}); -) - -/* -================================================= -| | -| LOAD AND ANALYZE THE TARGET | -| | -================================================= -*/ - -( -// ============= 5. LOAD THE FILE =================== -~target_path = File.realpath(FluidBufPitch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Nicol-LoopE-M.wav"; -~target_buf = Buffer.read(s,~target_path); -) - -( -// ============= 6. SLICE =================== -~target_indices_buf = Buffer(s); -FluidBufOnsetSlice.process(s,~target_buf,indices:~target_indices_buf,metric:9,threshold:0.5,action:{ - ~target_indices_buf.loadToFloatArray(action:{ - arg indices_array; - - // post the results so that you can tweak the parameters and get what you want - "found % slices".format(indices_array.size-1).postln; - "average length: % seconds".format((~target_buf.duration / (indices_array.size-1)).round(0.001)).postln; - }) -}); -) - -( -// =========== 7. USE THE SAME ANALYSIS FUNCTION -~analyze_to_dataset.(~target_buf,~target_indices_buf,{ - arg ds; - ~target_dataset = ds; - ~target_dataset.print; -}); -) - -( -// ======================= 8. TEST DRUM LOOP PLAYBACK ==================== -// play back the drum slices with a .wait in between so we hear the drum loop -Routine{ - ~target_indices_buf.loadToFloatArray(action:{ - arg target_indices_array; - - // prepend 0 (the start of the file) to the indices array - target_indices_array = [0] ++ target_indices_array; - - // append the total number of frames to know how long to play the last slice for - target_indices_array = target_indices_array ++ [~target_buf.numFrames]; - - - inf.do{ // loop for infinity - arg i; - - // get the index to play by modulo one less than the number of slices (we don't want to *start* playing from the - // last slice point, because that's the end of the file!) - var index = i % (target_indices_array.size - 1); - - // nb. that the minus one is so that the drum slice from the beginning of the file to the first index is call "-1" - // this is because that slice didn't actually get analyzed - var slice_id = index - 1; - var start_frame = target_indices_array[index]; - var dur_frames = target_indices_array[index + 1] - start_frame; - var dur_secs = dur_frames / ~target_buf.sampleRate; - - "playing slice: %".format(slice_id).postln; - - { - var sig = PlayBuf.ar(1,~target_buf,BufRateScale.ir(~target_buf),0,start_frame,0,2); - var env = EnvGen.kr(Env([0,1,1,0],[0.03,dur_secs-0.06,0.03]),doneAction:2); - sig = sig * env; // include this env if you like, but keep the line above because it will free the synth after the slice! - sig.dup; - }.play; - dur_secs.wait; - }; - }); -}.play; -) - -/* -================================================= -| | -| KDTREE THE DATA AND DO THE LOOKUP | -| | -================================================= -*/ - -( // ========== 9. FIT THE KDTREE TO THE SOURCE DATASET SO THAT WE CAN QUICKLY LOOKUP NEIGHBORS =============== -Routine{ - ~kdtree = FluidKDTree(s,10); - s.sync; - ~kdtree.fit(~source_dataset,{ - "kdtree fit".postln; - }); -}.play; -) - -( -// ========= 10. A LITTLE HELPER FUNCTION THAT WILL PLAY BACK A SLICE FROM THE SOURCE BY JUST PASSING THE INDEX ============= -~play_source_index = { - arg index; - { - var start_frame = Index.kr(~source_indices_buf,index); // lookup the start frame with the index *one the server* using Index.kr - var end_frame = Index.kr(~source_indices_buf,index+1); // same for the end frame - var num_frames = end_frame - start_frame; - var dur_secs = num_frames / SampleRate.ir(~source_buf); - var sig = PlayBuf.ar(1,~source_buf,BufRateScale.ir(~source_buf),0,start_frame,0,Done.freeSelf); - var env = EnvGen.kr(Env([0,1,1,0],[0.03,dur_secs-0.06,0.03]),doneAction:Done.freeSelf); - // sig = sig * env; // include this env if you like, but keep the line above because it will free the synth after the slice! - sig.dup; - }.play; -}; -) - -~target_dataset.print; - -( -// ======================= 11. TEST DRUM LOOP PLAYBACK ==================== -// play back the drum slices with a .wait in between so we hear the drum loop -// is is very similar to step 8 above, but now instead of playing the slice of -// the drum loop, it get's the analysis of the drum loop's slice into "query_buf", -// then uses that info to lookup the nearest neighbour in the source dataset and -// play that slice -Routine{ - var query_buf = Buffer.alloc(s,~nmfccs); // a buffer for doing the neighbor lookup with - ~target_indices_buf.loadToFloatArray(action:{ - arg target_indices_array; - - // prepend 0 (the start of the file) to the indices array - target_indices_array = [0] ++ target_indices_array; - - // append the total number of frames to know how long to play the last slice for - target_indices_array = target_indices_array ++ [~target_buf.numFrames]; - - - inf.do{ // loop for infinity - arg i; - - // get the index to play by modulo one less than the number of slices (we don't want to *start* playing from the - // last slice point, because that's the end of the file!) - var index = i % (target_indices_array.size - 1); - - // nb. that the minus one is so that the drum slice from the beginning of the file to the first index is call "-1" - // this is because that slice didn't actually get analyzed - var slice_id = index - 1; - var start_frame = target_indices_array[index]; - var dur_frames = target_indices_array[index + 1] - start_frame; - - // this will be used to space out the source slices according to the target timings - var dur_secs = dur_frames / ~target_buf.sampleRate; - - "target slice: %".format(slice_id).postln; - - // as long as this slice is not the one that starts at the beginning of the file (-1) and - // not the slice at the end of the file (because neither of these have analyses), let's - // do the lookup - if((slice_id >= 0) && (slice_id < (target_indices_array.size - 3)),{ - - // use the slice id to (re)create the slice identifier and load the data point into "query_buf" - ~target_dataset.getPoint("slice-%".format(slice_id.asInteger),query_buf,{ - // once it's loaded, use that buffer as the input to lookup the nearest - // neighbour data point in the kdtree of source slices - ~kdtree.kNearest(query_buf,{ - arg nearest; - var nearest_index; - - nearest.postln; - - // peel off just the integer part of the slice to use in the helper function - nearest_index = nearest.choose.asString.split($-)[1].asInteger; - nearest_index.postln; - ~play_source_index.(nearest_index); - }); - }); - }); - - // if you want to hear the drum set along side the neighbor slices, uncomment this function - { - var sig = PlayBuf.ar(1,~target_buf,BufRateScale.ir(~target_buf),0,start_frame,0,2); - var env = EnvGen.kr(Env([0,1,1,0],[0.03,dur_secs-0.06,0.03]),doneAction:2); - // sig = sig * env; // include this env if you like, but keep the line above because it will free the synth after the slice! - sig.dup * -8.dbamp; - }.play; - - dur_secs.wait; - }; - }); -}.play; -) \ No newline at end of file diff --git a/release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, 02 with Scalers).scd b/release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, with Scalers).scd similarity index 100% rename from release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, 02 with Scalers).scd rename to release-packaging/Examples/Guides/Audio Query (Replace Drum Sounds with other Sounds, with Scalers).scd diff --git a/release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (01 a lot in language).scd b/release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (01 a lot in language).scd deleted file mode 100644 index 5d1622c..0000000 --- a/release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (01 a lot in language).scd +++ /dev/null @@ -1,80 +0,0 @@ -( -~counter = 0; -~predicting = false; -~prediction_buf = Buffer.alloc(s,10); -Window.closeAll; -~win = Window("MLP Regressor",Rect(0,0,1000,400)); -~multisliderview = MultiSliderView(~win,Rect(0,0,400,400)) -.size_(10) -.elasticMode_(true) -.action_({ - arg msv; - // ~synth.set(\val,msv.value); - // msv.value.postln; - ~y_buf.setn(0,msv.value); -}); - -Slider2D(~win,Rect(400,0,400,400)) -.action_({ - arg s2d; - [s2d.x,s2d.y].postln; - ~x_buf.setn(0,[s2d.x,s2d.y]); - - if(~predicting,{ - ~nn.predictPoint(~x_buf,~y_buf,{ - ~y_buf.getn(0,10,{ - {~multisliderview.value_(prediction_values)}.defer; - }); - }); - }); -}); - -Button(~win,Rect(800,0,200,20)) -.states_([["Add Point"]]) -.action_({ - arg but; - var id = "example-%".format(~counter); - ~ds_input.addPoint(id,~x_buf); - ~ds_output.addPoint(id,~y_buf); - ~counter = ~counter + 1; - - ~ds_input.print; - ~ds_output.print; -}); - -Button(~win,Rect(800,20,200,20)) -.states_([["Train"]]) -.action_({ - arg but; - ~nn.fit(~ds_input,~ds_output,{ - arg loss; - "loss: %".format(loss).postln; - }); -}); - -Button(~win,Rect(800,40,200,20)) -.states_([["Not Predicting",Color.yellow,Color.black],["Is Predicting",Color.green,Color.black]]) -.action_({ - arg but; - ~predicting = but.value.asBoolean; -}); - -~win.front; - -~ds_input = FluidDataSet(s); -~ds_output = FluidDataSet(s); -~x_buf = Buffer.alloc(s,2); -~y_buf = Buffer.alloc(s,10); -~nn = FluidMLPRegressor(s,[7],FluidMLPRegressor.sigmoid,FluidMLPRegressor.sigmoid,learnRate:0.1,batchSize:1,validation:0); - -~synth = { - //arg val = #[0,0,0,0,0,0,0,0,0,0]; - var val = FluidBufToKr.kr(~y_buf) - var osc1, osc2, feed1, feed2, base1=69, base2=69, base3 = 130; - #feed2,feed1 = LocalIn.ar(2); - osc1 = MoogFF.ar(SinOsc.ar((((feed1 * val[0]) + val[1]) * base1).midicps,mul: (val[2] * 50).dbamp).atan,(base3 - (val[3] * (FluidLoudness.kr(feed2, 1, 0, hopSize: 64)[0].clip(-120,0) + 120))).lag(128/44100).midicps, val[4] * 3.5); - osc2 = MoogFF.ar(SinOsc.ar((((feed2 * val[5]) + val[6]) * base2).midicps,mul: (val[7] * 50).dbamp).atan,(base3 - (val[8] * (FluidLoudness.kr(feed1, 1, 0, hopSize: 64)[0].clip(-120,0) + 120))).lag(128/44100).midicps, val[9] * 3.5); - Out.ar(0,LeakDC.ar([osc1,osc2],mul: 0.1)); - LocalOut.ar([osc1,osc2]); -}.play; -) \ No newline at end of file diff --git a/release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (02 all on server).scd b/release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (all on server).scd similarity index 100% rename from release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (02 all on server).scd rename to release-packaging/Examples/Guides/Neural Network Controls Synth from 2D space (all on server).scd