How can i map my midi-keyboard to the minim oscilator?

edited January 2016 in Questions about Code

Hey there everyone!

I just recently got into processing and it is great.

Anyways, I was just learning some things about midi and and audio-processing with the midibus and minim. I wanted to write a code where I could control the minim-oscilator with my 88-keys midi-keyboard.

Oscilator works fine, I can control everything. But not with the keyboard for some reason... I am quite sure I messed up halfway through the code. There must be some error with my thinking-process...

How can I map my midi-controller correctly to this oscillator?

Any Help is appreciated!

Here is the code:

import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import themidibus.*;

MidiBus myBus;

float bufferX;
float bufferY;

float amp; //creating global variables to swap values between functions
float freq; 

Minim       minim;
AudioOutput out;
Oscil       wave;

void setup()
{
  size(400, 400);
   MidiBus.list();

   myBus = new MidiBus(this, 0, 3);
  minim = new Minim(this);

  out = minim.getLineOut();

  // create a sine wave Oscil, set to 440 Hz, at 0.5 amplitude
  wave = new Oscil( 440, 0.5f, Waves.SINE );
  // patch the Oscil to the output
  wave.patch( out );



}

void draw()
{
  background(0);

  fill(255);
 noStroke(); 

 for(int i = 0; i < out.bufferSize() - 1; i++) {

bufferX = out.left.get(i)*100;  
bufferY = out.right.get(i)*100;

 rect(width/2, height/2, bufferX, bufferY); //this draws some kind of rectangle to visualize the sound

 }
}
 void noteOn( int pitch, int velocity, int value) {
  // Receive a noteOn
  println(value);
  println("Pitch:"+pitch);
  println("Velocity:"+velocity);

  freq = value;  //writing the frequency data to the global variable
}


void controllerChange(int channel, int number, int value) {
  // Receive a controllerChange
  println();
  println("Controller Change:");
  println("--------");
  println("Channel:"+channel);
  println("Number:"+number);
  println("Value:"+value);

  if(number == 7) {  // only the volume-slider has to handle this business

 amp = value;  // writing the volume data into the global variable
  }
}


void midikeys()
{



 float freq1 = map(freq, 0, 98, 110, 880);  //mapping the notes-values to the frequency-spectrum
  wave.setFrequency( freq1 );

 float amp1 = map(amp, 0, 127, 0, 1);  //mapping the volume-slider to the volume control
  wave.setAmplitude( amp1 );
}

void keyPressed()
{ 
  switch( key )  //mapping the different osc-forms to the number-keys
  {
    case '1': 
      wave.setWaveform( Waves.SINE );
      break;

    case '2':
      wave.setWaveform( Waves.TRIANGLE );
      break;

    case '3':
      wave.setWaveform( Waves.SAW );
      break;

    case '4':
      wave.setWaveform( Waves.SQUARE );
      break;

    case '5':
      wave.setWaveform( Waves.QUARTERPULSE );
      break;

    default: break; 
  }

}

Have a good one!

Isaak

Answers

  • Thanks, changed it

  • what calls midikeys()?

  • midikeys() is called by nothing... I just tried calling midikeys() in the voi draw(), but nothing happens. In my original code the oscilator works fine, i just can't control anything with the midi keys

  •  void noteOn( int pitch, int velocity, int value) {
      // Receive a noteOn
      println(value);
      println("Pitch:"+pitch);
      println("Velocity:"+velocity);
    
      freq = value;  //writing the frequency data to the global variable
    }
    

    Pretty sure this is wrong. The javadoc reads: void noteOn(int channel, int pitch, int velocity) so you're setting the velocity (note volume) as the frequency instead of the pitch. Then maybe call midikeys() from this method, because you're not calling it from anywhere I believe as koogs pointed out. You might call it from draw() as well but if you call it from noteOn() it will only change the wave object when something is changed. Maybe that gives problems (if the libraries happen to be multithreaded for example), in that case detect if frequency of amplitude changed in draw() and only call midikeys() if they are:

    if(freq != prevfreq || amp != prevamp)
    {
       midikeys();
       prevfreq = freq;
       prevamp = amp;
    }
    
  • Thanks Mate, that did the trick! I created the two global variables prevfreq and prevamp. Here's the code, in case anyone ever needs it:

    import ddf.minim.*;
    import ddf.minim.analysis.*;
    import ddf.minim.ugens.*;
    import themidibus.*;
    
    float prevfreq = 440;
    float prevamp = 0f;
    
    MidiBus myBus;
    
    float bufferX;
    float bufferY;
    
    float amp; //creating global variables to swap values between functions
    float freq; 
    
     int value;
     int vel;
    
     boolean nOff = false;
    
    Minim       minim;
    AudioOutput out;
    Oscil       wave;
    
    void setup()
    {
      size(400, 400);
       MidiBus.list();
    
       myBus = new MidiBus(this, 1, 4);
      minim = new Minim(this);
    
      out = minim.getLineOut();
    
      // create a sine wave Oscil, set to 440 Hz, at 0.5 amplitude
      wave = new Oscil( prevfreq, prevamp, Waves.SINE );
      // patch the Oscil to the output
      wave.patch( out );
    
    
    
    }
    
    void draw()
    {
      background(0);
    
      fill(255);
     noStroke(); 
    
     for(int i = 0; i < out.bufferSize() - 1; i++) {
    
    bufferX = out.left.get(i)*100;  
    bufferY = out.right.get(i)*100;
    
     rect(width/2, height/2, bufferX, bufferY); //this draws some kind of rectangle to visualize the sound
    
     if(freq != prevfreq || amp != prevamp)
    {
       midikeys();
       prevfreq = freq;
       prevamp = amp;
    }
    
    
    
    
    
     }
    }
     void noteOn(int channel, int pitch, int velocity) {
      // Receive a noteOn
       println();
      println("Note On:");
      println("--------");
      println("Channel:"+channel);
      println("Pitch:"+pitch);
      println("Velocity:"+velocity);
    
      freq = pitch;  //writing the frequency data to the global variable
      vel = velocity;
    }
    
    void noteOff(int channel, int pitch, int velocity) {
       println();
      println("Note Off:");
      println("--------");
      println("Channel:"+channel);
      println("Pitch:"+pitch);
      println("Velocity:"+velocity);
      vel = velocity;
    
      nOff = true;
    
    }
    
    
    void controllerChange(int channel, int number, int value) {
      // Receive a controllerChange
      println("Controller Change:");
      println("Channel:"+channel);
      println("Number:"+number);
      println("Value:"+value);
    
      if(number == 7) {  // only the volume-slider has to handle this business
    
     amp = value;  // writing the volume data into the global variable
      }
    }
    
    
    void midikeys()
    {
    
    
    
     float freq1 = map(freq, 0, 98, 110, 880);  //mapping the notes-values to the frequency-spectrum
      wave.setFrequency( freq1 );
    
     float amp1 = map(amp, 0, 127, 0, 1);  //mapping the volume-slider to the volume control
      wave.setAmplitude( amp1 );
    }
    
    void keyPressed()
    { 
      switch( key )  //mapping the different osc-forms to the number-keys
      {
        case '1': 
          wave.setWaveform( Waves.SINE );
          break;
    
        case '2':
          wave.setWaveform( Waves.TRIANGLE );
          break;
    
        case '3':
          wave.setWaveform( Waves.SAW );
          break;
    
        case '4':
          wave.setWaveform( Waves.SQUARE );
          break;
    
        case '5':
          wave.setWaveform( Waves.QUARTERPULSE );
          break;
    
        default: break; 
      }
    
    }
    

    Now I am working on the noteOff function, so that only a tone comes when I press a key. As far as my understanding goes I do not have to control this over the amplitude but over the oscilator itself.

    Thanks again for the help!

Sign In or Register to comment.