 
   // Get an available OPL2 channel and setup instrument parameters.
   byte i = getFreeChannel(channel);
-  channelMap[i].midiChannel = channel;
-  channelMap[i].midiNote    = note;
   opl2.setInstrument(i, instruments[programMap[channel]]);
+  channelMap[i].midiChannel  = channel;
+  channelMap[i].midiNote     = note;
+  channelMap[i].midiVelocity = round(velocity / 127.0);
+  channelMap[i].op1Level     = round((63 - opl2.getVolume(i, OPERATOR1)) / 63.0);
+  channelMap[i].op2Level     = round((63 - opl2.getVolume(i, OPERATOR2)) / 63.0);
 
   // Set operator output levels based on note velocity.
-  float volume = velocity / 127.0;
-  byte opl2VolumeOP1 = 63 - opl2.getVolume(i, OPERATOR1);
-  byte opl2VolumeOP2 = 63 - opl2.getVolume(i, OPERATOR2);
-  opl2.setVolume(i, OPERATOR1, 63 - (opl2VolumeOP1 * volume));  
-  opl2.setVolume(i, OPERATOR2, 63 - (opl2VolumeOP2 * volume));
+  setOpl2ChannelVolume(i, channel);
 
   // Calculate octave and note number and play note!
   note = max(24, min(note, 119));

}


void onNoteOn(byte channel, byte note, byte velocity) {
  // Treat notes with a velocity of 0 as note off.
  if (velocity == 0) {

#include <SPI.h>
#include <OPL2.h>
#include <midi_instruments.h>

#define CONTROL_VOLUME          7
#define CONTROL_ALL_SOUND_OFF 120
#define CONTROL_RESET_ALL     121
#define CONTROL_ALL_NOTES_OFF 123

#define MIDI_CHANNELS 16
#define OPL2_CHANNELS 9
