Dataset from individual sounds? (SC)

Hey!

I’m in the middle of expanding my live system, also trying to learn something in the process.
Currently, I have a SC script that records and stores automatically individual samples into a folder according to given constraints.

Now, I would like to use FluCoMa to analyze all these samples, allowing me to recall them afterwards using similarities and other criteria.
I actually explored several code examples, but each one I found was basically merging all the sounds into a single buffer and slice it using FluidBufOnsetSlice. Since my samples are already sliced, this operation makes no sense.

So my question is: is there a way to directly produce a dataset from a bunch of individual files, or to store their bounds into a simple buffer of indeces (maybe the latter is a better solution since it involves a single buffer…)?

Thanks so much!

Hi @ardan

There’s nothing that requires you to use monolithic buffers at all. If you don’t need to segment, you can just run analyses on individual buffers and put the results of each analysis into a dataset as a point.

Hi!

Yes, that’s the hard-coded way.
However, having a single buffer to point to is much more handy for my task, that’s why I’m using FluidLoadFolder.

Indeed, I found a workaround, not sure if it’s the most elegant flucoma-ish way to do that, but still it works. I’m open to suggestion!

~source_folder = "/Users/ardan/Desktop/chunks/";

~load_files = FluidLoadFolder(~source_folder);
~load_files.play(s, { ~full_buf = ~load_files.buffer});


~indeces_list= List[];

~load_files.index.keysDo{ |key| 
	var bound = ~load_files.index[key][\bounds][1].postln;
	~indeces_list.add(bound)
};

~indeces_list.addFirst(0).sort.asCollection;
~indeces_buf = Buffer.alloc(s, ~indeces_list.size); 
~indeces_buf.loadCollection(~indeces_list);

Ah right, got you.

Possibly slightly easier to do with SoundFile.collect, here’s an example of making a big concatenated buffer from this post.

s.boot
(
~files=SoundFile.collect("/Users/owen/dev/flucoma-core/Resources/AudioFiles/*");
~frames = ~files.collect{|f| f.numFrames}; 
~totalFrames = ~frames.sum; 
~buf = Buffer.alloc(s, ~totalFrames);
~frameCount = 0; 
~files.do{|f|
	~buf.readChannel(f.path, bufStartFrame:~frameCount, channels:[0]);
	~frameCount = ~frameCount + f.numFrames; 
};
)

If you wanted to keep hold of the list of ‘index’ times, you just do a cumulative sum of the ~frames list as well.

~frames.reduce{|a, b|var old = a.asArray; old ++ (b + old.last)}
2 Likes

Usually when this kind of data gets to the server I want both the start position and the duration of the slices, so I interleave that information language side, then load it to a 2-channel buffer so that I can index into that buffer according to what slice I want to play, then use channel 0 for the start position and channel 1 for the duration.