Load and play random samples from a directory?

For my own aural skills practice, I would like a little app that loads and plays a new sample (wav or mp3) from a directory with each press of a GUI button.

Has anyone made such a thing?

I imagine it would be kind of simple to code in SC, and a good adventure, but I would love somewhere to begin if it’s already done.

Thanks!

Hi,

You could either load all samples into memory to begin with, or stream them from disk (which saves memory in case you have a lot of samples). Here is an example of streaming from disk:

( // 1. prep

// folder with samples
~folderpath = "/path/to/your/folder/";
~files = PathName(~folderpath).files;

s.waitForBoot {
  SynthDef(\playFile, { |out, buf|
    Out.ar(out, DiskIn.ar(2, buf).poll);
  }).add;
  
  ~buffer = Buffer.alloc(s, 32768, 2); // assuming stereo files
};
)

( // 2. pick a random file and play it
var file = ~files.choose;
fork {
  ~buffer.close;
  ~buffer.cueSoundFile(file.fullPath, 0);
  s.sync;
  Synth(\playFile, [buf: ~buffer]);
}
)

For me this works with .mp3 files as well as .wav which was a surprise to me! The last time I tried to work with .mp3 files (many years ago) I remember having to use the MP3 quark.

And to make this happen when you press a GUI button, use its action:

(
~window = Window().front;
~button = Button(~window, Rect(10, 10, 50, 30)).string_("Play").action_({
  var file = ~files.choose;
  fork {
    ~buffer.close;
    ~buffer.cueSoundFile(file.fullPath, 0);
    s.sync;
    Synth(\playFile, [buf: ~buffer]);
  };
});
)

worked here with mp3 and flac also! :slight_smile:
but at wrong speed! maybe wrong samplerate or buffer alloc?

ah, yes probably sample rate. Replace in the SynthDef the DiskIn.ar(…) with

VDiskIn.ar(2, buf, BufRateScale.kr(buf))
1 Like

Brilliant thank you!

One question – how do you make the synth stop?

I think (SC pre-newbie really…) that the poll function shows that there is no more sound at the end of the MP3, but the Synth just goes on forever (it keeps writing “UGen Array [0]: 0 \nUGen Array [1]: 0” to the post window).

EDIT: I modified it to be

~nowplaying = Synth(\playFile, [buf: ~buffer]);

Then you can do something like ~nowplaying.free; later. I might put this into the button code so each button frees it or the like.

I still don’t know how to free the synth at the end of the sample, though.

Haven’t tested but this should free the synth when the file is done:

SynthDef(\playFile, { |out, buf|
  var playback = VDiskIn.ar(2, buf, BufRateScale.kr(buf));
  FreeSelfWhenDone.kr(playback);
  Out.ar(out, playback);
}).add;
1 Like

Well, that’s great, thank you! Over the next week or so I hope to have my very own aural skills random player thing!