Skip to content

Commit

Permalink
Merge branch 'serial_midi' of github.com:virtuaCode/ArduinoOPL2 into …
Browse files Browse the repository at this point in the history
…serial_midi
  • Loading branch information
virtuaCode committed Sep 23, 2019
2 parents 4f440c1 + b651e25 commit 499428a
Showing 1 changed file with 84 additions and 84 deletions.
168 changes: 84 additions & 84 deletions examples/SerialMidi/SerialMidi.ino
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void setup() {
* Read and handle MIDI events.
*/
void loop() {
MIDI.read();
MIDI.read();
}


Expand All @@ -112,7 +112,7 @@ byte getFreeChannel(byte midiChannel, bool* r) {
byte opl2Channel = 255;
bool replaced = false;

// Look for the oldest free OPL2 channel.
// Look for the oldest free OPL2 channel.
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
if (!opl2.getKeyOn(oldestChannel[i])) {
opl2Channel = oldestChannel[i];
Expand Down Expand Up @@ -140,32 +140,32 @@ byte getFreeChannel(byte midiChannel, bool* r) {
}

void setChannelReleased(byte opl2Channel) {
// Update the list of last released channels by moving the current released channel to the bottom so the oldest released
// channel will move to the front of the list.
byte i;
for (i = 0; i < OPL2_NUM_CHANNELS && oldestChannel[i] != opl2Channel; i ++) {}

while (i < OPL2_NUM_CHANNELS - 1) {
byte temp = oldestChannel[i + 1];
oldestChannel[i + 1] = oldestChannel[i];
oldestChannel[i] = temp;
i ++;
}
// Update the list of last released channels by moving the current released channel to the bottom so the oldest released
// channel will move to the front of the list.
byte i;
for (i = 0; i < OPL2_NUM_CHANNELS && oldestChannel[i] != opl2Channel; i ++) {}

while (i < OPL2_NUM_CHANNELS - 1) {
byte temp = oldestChannel[i + 1];
oldestChannel[i + 1] = oldestChannel[i];
oldestChannel[i] = temp;
i ++;
}

// Mark channel as not playing.
channelMap[opl2Channel].midiVelocity = 0;
// Mark channel as not playing.
channelMap[opl2Channel].midiVelocity = 0;
}


/**
* Set the volume of operators 1 and 2 of the given OPL2 channel according to the settings of the given MIDI channel.
*/
void setOpl2ChannelVolume(byte opl2Channel, byte midiChannel) {
float volume = channelMap[opl2Channel].midiVelocity * channelVolumes[midiChannel];
byte volumeOp1 = round(channelMap[opl2Channel].op1Level * volume * 63.0);
byte volumeOp2 = round(channelMap[opl2Channel].op2Level * volume * 63.0);
opl2.setVolume(opl2Channel, OPERATOR1, 63 - volumeOp1);
opl2.setVolume(opl2Channel, OPERATOR2, 63 - volumeOp2);
float volume = channelMap[opl2Channel].midiVelocity * channelVolumes[midiChannel];
byte volumeOp1 = round(channelMap[opl2Channel].op1Level * volume * 63.0);
byte volumeOp2 = round(channelMap[opl2Channel].op2Level * volume * 63.0);
opl2.setVolume(opl2Channel, OPERATOR1, 63 - volumeOp1);
opl2.setVolume(opl2Channel, OPERATOR2, 63 - volumeOp2);
}


Expand Down Expand Up @@ -236,15 +236,15 @@ void onNoteOn(byte channel, byte note, byte velocity) {
* Handle a note off MIDI event to stop playing a note.
*/
void onNoteOff(byte channel, byte note, byte velocity) {
channel = channel % 16;
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
const ChannelMapping mapping = channelMap[i];
if (mapping.midiChannel == channel && mapping.midiNote == note && mapping.midiVelocity > 0) {
opl2.setKeyOn(i, false);
setChannelReleased(i);
break;
}
}
channel = channel % 16;
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
const ChannelMapping mapping = channelMap[i];
if (mapping.midiChannel == channel && mapping.midiNote == note && mapping.midiVelocity > 0) {
opl2.setKeyOn(i, false);
setChannelReleased(i);
break;
}
}
}

/**
Expand Down Expand Up @@ -291,77 +291,77 @@ void resetPitchBend(byte channel) {
* Handle instrument change on the given MIDI channel.
*/
void onProgramChange(byte channel, byte program) {
programMap[channel % 16] = min(program, 127);
programMap[channel % 16] = min(program, 127);
}


/**
* Handle MIDI control changes on the given channel.
*/
void onControlChange(byte channel, byte control, byte value) {
channel = channel % 16;

switch (control) {

// Change volume of a MIDI channel. (Limited to 0.8 to prevent clipping)
case CONTROL_VOLUME: {
channelVolumes[channel] = min(value / 127.0, 0.8);
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
if (channelMap[i].midiChannel == channel && opl2.getKeyOn(i)) {
setOpl2ChannelVolume(i, channel);
}
}
break;
}

// Reset all controller values.
case CONTROL_RESET_ALL:
for (byte i = 0; i < MIDI_NUM_CHANNELS; i ++) {
channelVolumes[channel] = 0.8;
}
break;

// Immediately silence all channels.
// Intentionally cascade into CONTROL_ALL_NOTES_OFF!
case CONTROL_ALL_SOUND_OFF:
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
opl2.setRelease(i, OPERATOR1, 0);
opl2.setRelease(i, OPERATOR2, 0);
}
channel = channel % 16;

switch (control) {

// Change volume of a MIDI channel. (Limited to 0.8 to prevent clipping)
case CONTROL_VOLUME: {
channelVolumes[channel] = min(value / 127.0, 0.8);
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
if (channelMap[i].midiChannel == channel && opl2.getKeyOn(i)) {
setOpl2ChannelVolume(i, channel);
}
}
break;
}

// Silence all MIDI channels.
case CONTROL_ALL_NOTES_OFF: {
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
if (channelMap[i].midiChannel == channel) {
onNoteOff(channelMap[i].midiChannel, channelMap[i].midiNote, 0);
}
}
break;
}
// Reset all controller values.
case CONTROL_RESET_ALL:
for (byte i = 0; i < MIDI_NUM_CHANNELS; i ++) {
channelVolumes[channel] = 0.8;
}
break;

// Immediately silence all channels.
// Intentionally cascade into CONTROL_ALL_NOTES_OFF!
case CONTROL_ALL_SOUND_OFF:
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
opl2.setRelease(i, OPERATOR1, 0);
opl2.setRelease(i, OPERATOR2, 0);
}

// Silence all MIDI channels.
case CONTROL_ALL_NOTES_OFF: {
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
if (channelMap[i].midiChannel == channel) {
onNoteOff(channelMap[i].midiChannel, channelMap[i].midiNote, 0);
}
}
break;
}

// Ignore any other MIDI controls.
default:
break;
}
// Ignore any other MIDI controls.
default:
break;
}
}


/**
* Handle full system reset.
*/
void onSystemReset() {
opl2.init();
opl2.init();

// Silence all channels and set default instrument.
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
opl2.setKeyOn(i, false);
opl2.setInstrument(i, midiInstruments[0]);
oldestChannel[i] = i;
}
// Silence all channels and set default instrument.
for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
opl2.setKeyOn(i, false);
opl2.setInstrument(i, midiInstruments[0]);
oldestChannel[i] = i;
}

// Reset default MIDI player parameters.
for (byte i = 0; i < MIDI_NUM_CHANNELS; i ++) {
programMap[i] = 0;
channelVolumes[i] = 0.8;
}
// Reset default MIDI player parameters.
for (byte i = 0; i < MIDI_NUM_CHANNELS; i ++) {
programMap[i] = 0;
channelVolumes[i] = 0.8;
}
}

0 comments on commit 499428a

Please sign in to comment.