Manoloide & Audio Recording

I haven't written in a while. Zoom sessions have occupied most of the time and power and there is little desire to be in front of the computer.

Still, i already had this reference to add to the authors and artists:

Manolo Gamboa Naon

Creative Coder – Generative Designer
manoloide.com
La Plata, Argentina

You have an absolutely fantastic job.

And in recent classes, we've developed interesting techniques, like buttons that alter the images and sounds inside —one day we have to talk about inheritance—propagation of effects between objects —metronomes like the reactable one—and most interestingly, it was a little sketch that records "all" the audio that comes out of the interaction in the sketch.

In fact, the credits go to Mateus Lima, because it was he to first figure out how to solve the loading of an audio file with a buffer / sampler object instead of an AudioFile, as well as the patch function()

Here is the commented code:

<html><body><pre></body></html>
<span style="color: #33997E;">import</span> ddf.minim.*;
<span style="color: #33997E;">import</span> ddf.minim.ugens.*;

<span style="color: #666666;">global sound control</span>
Minim minim;

<span style="color: #666666;">global memory control variable (for recording)</span>
MultiChannelBuffer sampleBuffer;
Sampler sampler;       <span style="color: #666666;">// alternative object to "upload" audio files</span>

<span style="color: #666666;">global "output" control</span>
AudioOutput output;

<span style="color: #666666;">object that allows you to make the overall recording of the sound</span>
AudioRecorder recorder;


<span style="color: #666666;">custom objects</span>
SoundObject s1;
SoundObje[]ct sounds;   <span style="color: #666666;">// in the future we have to convert this into an ArrayList</span>

<span style="color: #666666;">to turn recording on and off</span>
<span style="color: #E2661A;">boolean</span> recorded = <span style="color: #33997E;">false</span>;

<span style="color: #33997E;">void</span> <span style="color: #006699;"><b>setup</b></span>() {
<span style="color: #006699;">size</span>(512, 200);

<span style="color: #666666;">// create Minim and an AudioOutput</span>
minim = <span style="color: #33997E;">new</span> Minim (<span style="color: #33997E;">this</span>);
output = minim.getLineOut();


<span style="color: #666666;">// construct a new MultiChannelBuffer with 2 channels and 1024 sample frames.</span>
<span style="color: #666666;">// in our particular case, it doesn't really matter what we choose for these</span>
<span style="color: #666666;">// two values because loadFileIntoBuffer will reconfigure the buffer</span>
<span style="color: #666666;">// to match the channel count and length of the file.</span>
sampleBuffer = <span style="color: #33997E;">new</span> MultiChannelBuffer( 1, 1024 );

<span style="color: #666666;">// we pass the buffer to the method and Minim will reconfigure it to match</span>
<span style="color: #666666;">// the file.</span> if the file doesn't exist, or there is some other problen with
<span style="color: #666666;">// loading it, the function will return 0 as the sample rate.</span>
<span style="color: #E2661A;">float</span> sampleRate = minim.loadFileIntoBuffer( <span style="color: #7D4793;">"groove.mp3",</span>sampleBuffer);


<span style="color: #666666;">// make sure the file load worked</span>
<span style="color: #666666;">// create a sampler that will use our buffer to generate audio.</span>
<span style="color: #666666;">// we must provide the sample rate of the audio and the number of voices.</span> 
sampler = <span style="color: #33997E;">new</span> Sampler (sampleBuffer, sampleRate, 1);

<span style="color: #666666;">// and finally, connect to the output so we can hear it (when played/triggered)</span>
sampler.patch (output);

<span style="color: #666666;">// create an AudioRecorder that will record from in to the specified filename.</span>
<span style="color: #666666;">// the file will be located in the sketch's main folder.</span>
recorder = minim.createRecorder (output, <span style="color: #7D4793;">"myrecording.wav");</span>

recorded = <span style="color: #33997E;">false</span>;

<span style="color: #666666;">// create a list of sound playing objects</span>
sounds = <span style="color: #33997E;">new</span> SoundObject[10];

<span style="color: #666666;">// place them on stage and individual sounds into them</span>
<span style="color: #669900;">for</span> (<span style="color: #E2661A;">int</span> i = 0; i &lt; 10; i++) {
sounds = <span style="colo[i]r: #33997E;">new</span> SoundObject<span style="color: #006699;">(random</span><span style="color: #D94A7A;">(width),</span> <span style="color: #006699;">random</span><span style="color: #D94A7A;">(height),</span> <span style="color: #006699;">random</span>(30, 90), <span style="color: #7D4793;">"s0.mp3"</span>);
}
}


<span style="color: #33997E;">void</span> <span style="color: #006699;"><b>draw</b></span>() {
<span style="color: #006699;">fill</span>(200);

<span style="color: #669900;">if</span> (recorder.isRecording() ){
<span style="color: #006699;">text</span>(<span style="color: #7D4793;">"Now recording, press the r key to stop recording."</span>, 5, 15);
} <span style="color: #669900;">else</span> <span style="color: #669900;">if</span> ( !recorded ) {
<span style="color: #006699;">text</span>(<span style="color: #7D4793;">"Press the r key to start recording."</span>, 5, 15);
} <span style="color: #669900;">else</span> (
<span style="color: #006699;">text</span>(<span style="color: #7D4793;">"Press the s key to save the recording to disk and play it back in the sketch."</span>, 5, 15);
}


<span style="color: #669900;">for</span> (<span style="color: #E2661A;">int</span> i = 0; i &lt; 10; i++) {

sounds.updat[i]e();
sounds.displ[i]ay();
}
}

<span style="color: #33997E;">void</span> <span style="color: #006699;"><b>(keyPressed)</b></span>{
<span style="color: #669900;">if</span> ( <span style="color: #D94A7A;">key</span> == <span style="color: #7D4793;">' ' &</span> sampler != <span style="color: #33997E;">null</span> ) {
sampler.trigger();
}
}


<span style="color: #33997E;">void</span> <span style="color: #006699;"><b>keyReleased</b></span>() {

<span style="color: #669900;">if</span> ( <span style="color: #D94A7A;">key</span> == <span style="color: #7D4793;">'r'</span> ) {
<span style="color: #666666;">// to indicate that you want to start or stop capturing audio data, you must call</span>
<span style="color: #666666;">// beginRecord() and endRecord() on the AudioRecorder object.</span> You can start and stop
<span style="color: #666666;">// as many times as you like, the audio data will be appended to the end of the buffer</span>
<span style="color: #666666;">// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).</span> 
<span style="color: #669900;">if</span> (recorder.isRecording() ) 
{
recorder. <span style="color: #006699;">endRecord</span>();
} <span style="color: #669900;">else</span> 
{
recorder. <span style="color: #006699;">beginRecord</span>();
}
}
<span style="color: #669900;">if</span> ( <span style="color: #D94A7A;">key</span> == <span style="color: #7D4793;">'s'</span> )
{
<span style="color: #666666;">// we've filled the file out buffer,</span>
<span style="color: #666666;">// now write it to the file we specified in createRecorder</span>
<span style="color: #666666;">// in the case of buffered recording, if the buffer is large,</span>
<span style="color: #666666;">// this will appear to freeze the sketch for sometime</span>
<span style="color: #666666;">// in the case of streamed recording,</span>
<span style="color: #666666;">// it will not freeze as the data is already in the file and all that is being done</span>
<span style="color: #666666;">// is closing the file.</span>
<span style="color: #666666;">// the method returns the recorded audio as an AudioRecording,</span>
<span style="color: #666666;">// see the example AudioRecorder &gt;&gt; RecordAndPlayback for more about that</span>
recorder. <span style="color: #006699;">save</span>();
<span style="color: #006699;">println</span>(<span style="color: #7D4793;">"Done saving."</span>);
}
}



<html><body><pre></body></html>
<span style="color: #33997E;">class</span> SoundObject (

<span style="color: #666666;">// objects/private variables/locations of each object</span>
MultiChannelBuffer mySampleBuffer;  <span style="color: #666666;">// this will load the audio file for each object</span>
Sampler mysampler;       <span style="color: #666666;">// this will allow you to send each audio to the global lineout</span>

<span style="color: #E2661A;">float</span> x, y;  <span style="color: #666666;">// position</span>
<span style="color: #E2661A;">float</span> w;     <span style="color: #666666;">// size</span>

<span style="color: #E2661A;">color</span> c;

<span style="color: #666666;">// constructor with the "name" of the audio file to load on this object</span>
SoundObject<span style="color: #E2661A;">(float</span> px, <span style="color: #E2661A;">float</span> py, <span style="color: #E2661A;">float</span> pw, <span style="color: #E2661A;">string</span> ps) {

mySampleBuffer = <span style="color: #33997E;">new</span> MultiChannelBuffer( 1, 1024 );
<span style="color: #E2661A;">float</span> mySampleRate = minim.loadFileIntoBuffer (ps, mySampleBuffer);

mysampler = <span style="color: #33997E;">new</span> Sampler ( mySampleBuffer, mySampleRate, 1 ); 
mysampler.patch (output);

x = px;
y = py;
w = pw;
c = <span style="color: #006699;">color</span>(200, 0, 0);
}

<span style="color: #666666;">// simple playback when mouseover pressed</span>
<span style="color: #33997E;">void</span> update() {
<span style="color: #669900;">if</span><span style="color: #006699;">(dist</span><span style="color: #D94A7A;">(mouseX,</span> <span style="color: #D94A7A;">mouseY,</span>x, y) &lt; w/2) {
c = <span style="color: #006699;">color</span>(0, 200, 0);
<span style="color: #669900;">if</span><span style="color: #D94A7A;">(mousePressed)</span>{
soundPlay();    <span style="color: #666666;">// we made a private aka method function for the object to be able to playback from the object itself, or from the main program</span>
}
} <span style="color: #669900;">else</span> (
c = <span style="color: #006699;">color</span>(200, 0, 0);
}

}

<span style="color: #33997E;">void</span> display() {

<span style="color: #006699;">fill</span>(c);
<span style="color: #006699;">noStroke</span>();
<span style="color: #006699;">ellipse</span>(x, y, w, w);

}

<span style="color: #33997E;">void</span> soundPlay(){
mysampler.trigger();
<span style="color: #666666;">// can put other things here when you play the sound... modify color... form...?</span>
}

}

Leave a comment

Your email address will not be published.