Manoloide & Gravação de Audio

Já cá não escrevo há algum tempo. As sessões em Zoom têm ocupado a maioria do tempo e energia e resta pouca vontade de estar à frente do computador.

Ainda assim, já tinha esta referência para adicionar aos autores e artistas:

Manolo Gamboa Naon

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

Tem um trabalho absolutamente fantástico.

E, nas últimas aulas, temos desenvolvido técnicas interessantes, como botões que alteram as imagens e sons no seu interior — um dia temos que falar sobre inheritance — propagação de efeitos entre objetos — metrónomos como o do reactable — e o mais interessante, foi um pequeno sketch que grava “todo” o áudio que sai da interação no sketch.

Na realidade, os créditos vão para o Mateus Lima, pois foi ele a descobrir primeiro como resolver o carregamento de um ficheiro de audio com um buffer/sampler object em vez de um AudioFile, bem como da função patch()

Fica aqui o código comentado:

import ddf.minim.*;
import ddf.minim.ugens.*;

// controlo global de som
Minim minim;

// variável global de controlo de memória (para gravação)
MultiChannelBuffer sampleBuffer;
Sampler sampler;       // objeto alternativo para "carregar" ficheiros de audio 

// controlo global do "output"   
AudioOutput output;

// objeto que permite fazer a gravação global do som
AudioRecorder recorder;


// objetos custom
SoundObject s1;  
SoundObject[] sounds;   // no futuro temos que converter isto numa ArrayList

// para ativar e desativar a gravação
boolean recorded = false;

void setup() {
  size(512, 200);

  // create Minim and an AudioOutput
  minim  = new Minim(this);
  output = minim.getLineOut();


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

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


  // make sure the file load worked
  // create a sampler that will use our buffer to generate audio.
  // we must provide the sample rate of the audio and the number of voices. 
  sampler = new Sampler( sampleBuffer, sampleRate, 1 );
 
  // and finally, connect to the output so we can hear it (when played/triggered)
  sampler.patch( output );

  // create an AudioRecorder that will record from in to the filename specified.
  // the file will be located in the sketch's main folder.
  recorder = minim.createRecorder(output, "myrecording.wav");

  recorded = false;

  // create a list of sound playing objects
  sounds = new SoundObject[10];
  
  // place them on stage and individual sounds into them
  for (int i = 0; i < 10; i++) {
    sounds[i] = new SoundObject(random(width), random(height), random(30, 90), "s0.mp3");
  }
}


void draw() {
  fill(200);

  if ( recorder.isRecording() ){
    text("Now recording, press the r key to stop recording.", 5, 15);
  } else if ( !recorded ) {
    text("Press the r key to start recording.", 5, 15);
  } else {
    text("Press the s key to save the recording to disk and play it back in the sketch.", 5, 15);
  }


  for (int i = 0; i < 10; i++) {

    sounds[i].update();
    sounds[i].display();
  }
}

void keyPressed() {
  if ( key == ' ' && sampler != null ) {
    sampler.trigger();
  }
}


void keyReleased() {

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

class SoundObject {
 
  // objetos/variáveis privadas/locais de cada objeto
  MultiChannelBuffer mySampleBuffer;  // isto vai carregar o ficheiro de audio para cada objeto
  Sampler            mysampler;       // isto vai permitir enviar o audio de cada um para o lineout global
  
  float x, y;  // posição
  float w;     // tamanho
  
  color c;
  
  // construtor com o "nome" do ficheiro de audio para carregar neste objeto
  SoundObject(float px, float py, float pw, String ps) {
    
    mySampleBuffer     = new MultiChannelBuffer( 1, 1024 );
    float mySampleRate = minim.loadFileIntoBuffer( ps, mySampleBuffer );
    
    mysampler = new Sampler( mySampleBuffer, mySampleRate, 1 ); 
    mysampler.patch( output );  
    
    x = px;
    y = py;
    w = pw;
    c = color(200, 0, 0);
  }
  
  // simple playback when mouseover pressed
  void update() {
    if(dist(mouseX, mouseY, x, y) < w/2) {
      c = color(0, 200, 0);
      if(mousePressed) {
        soundPlay();    // fizemos uma função AKA método privado para o objeto para poder fazer playback a partir do prórpio objeto, ou a partir do programa principal
      }
    } else {
      c = color(200, 0, 0);
    }
    
  }
  
  void display() {
   
    fill(c);
    noStroke();
    ellipse(x, y, w, w);
    
  }
  
  void soundPlay(){
    mysampler.trigger();
    // podem colocar outras coisas aqui quando toca o som… modificar cor… forma…?
  }
  
}

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *