From 4112945bb90ffd38dad10c53a3b19a8f4776aaea Mon Sep 17 00:00:00 2001 From: Maarten Janssen Date: Fri, 10 Apr 2020 10:08:02 +0200 Subject: [PATCH] Added two new examples * A new example 'Scale' is added to show how to play simple notes. * A new example 'PianoBoard' is added this sketch requires the Cheerful Electronic Piano Board and will combine with the OPL2 board to create a piano --- README.md | 2 +- build | 2 +- examples/PianoBoard/PianoBoard.ino | 139 +++++++++++++++++++++++++++++ examples/Scale/Scale.ino | 43 +++++++++ library.properties | 2 +- 5 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 examples/PianoBoard/PianoBoard.ino create mode 100644 examples/Scale/Scale.ino diff --git a/README.md b/README.md index 393d2dc..3d0bbc6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This repository contains the OPL2 Audio Board library for Arduino, Teensy, Raspb * Emulation with DosBox; you can use the board to output MIDI music (Teensy++ 2.0 and later) * Use the board directly as a synthesizer by using the [OPL3BankEditor](https://github.com/Wohlstand/OPL3BankEditor) software by Wohlstand -Current library version is 1.5.1 +Current library version is 1.5.2 To obtain your own OPL2 Audio Board visit the [Tindie store](https://www.tindie.com/products/DhrBaksteen/opl2-audio-board/). diff --git a/build b/build index bf8e459..9934b97 100755 --- a/build +++ b/build @@ -18,7 +18,7 @@ echo "\033[1;36m / | \\ | / /_/ | | ( /_/ ) | | ( /_/ ) __ \\| echo "\033[1;34m \\____|__ /____/\\____ | |__|\\___/ |______ /\\___(____ /__| \\____ | " echo "\033[1;34m \\/ \\/ \\/ \\/ \\/ \033[0m" echo "Installation script for Raspberry Pi and compatibles" -echo "Library version 1.5.1, 16th of Match 2020" +echo "Library version 1.5.2, 10th of April 2020" echo "Copyright (c) 2016-2020 Maarten Janssen, Cheerful" echo "" diff --git a/examples/PianoBoard/PianoBoard.ino b/examples/PianoBoard/PianoBoard.ino new file mode 100644 index 0000000..8213de6 --- /dev/null +++ b/examples/PianoBoard/PianoBoard.ino @@ -0,0 +1,139 @@ +/** + * This is a simple demo sketch for the OPL2 library. It makes use of the Piano Board and assumes then you also have the + * ArduinoPianoBoard library installed (see https://github.com/DhrBaksteen/ArduinoPianoBoard). + * + * This sketch makes a simple piano out of the OPL2 Board and the Piano Board. Use the piano keys to play a tune. User + * key 1 will lower the octave, user key 2 will increase the octave. User key 3 is free for your own experiments! + * + * OPL2 Board is connected as follows: + * Pin 8 - Reset + * Pin 9 - A0 + * Pin 10 - Latch + * Pin 11 - Data + * Pin 13 - Shift + * + * Piano Board is connected as follows: + * Pin 7 - /SS + * Pin 12 - MISO + * Pin 13 - SCK + * + * Code by Maarten Janssen (maarten@cheerful.nl) 2020-04-10 + * Most recent version of the library can be found at my GitHub: https://github.com/DhrBaksteen/ArduinoOPL2 + */ + +#include +#include +#include +#include + +OPL2 opl2; +PianoKeys piano(7); + +int octave = 4; +int chIndex = 0; +int keyChannel[9] = {-1, -1, -1, -1, -1, -1, -1, -1, -1}; + + +void setup() { + opl2.init(); + + // Load an instrument and assign it to all OPL2 channels. + Instrument piano = opl2.loadInstrument(INSTRUMENT_CRYSTAL); + for (int i = 0; i < 9; i ++) { + opl2.setInstrument(i, piano); + } +} + + +void loop() { + piano.updateKeys(); + + // Handle keys that are being pressed or held down. + for (int i = KEY_C; i <= KEY_C2; i ++) { + // Handle a key press. + if (piano.wasKeyPressed(i)) { + // Find a free OPL2 channel where we can play the note. + int opl2Channel = getFreeChannel(); + + // If a channel is available then register it as used and play the note. + if (opl2Channel > -1) { + keyChannel[opl2Channel] = i ; + if (i == KEY_C2) { + opl2.playNote(opl2Channel, octave + 1, NOTE_C); + } else { + opl2.playNote(opl2Channel, octave, i); + } + } + } + + // Handle a key release. + if (piano.wasKeyReleased(i)) { + // Find the OPL2 channel where the not is playing. + int opl2Channel = getKeyChannel(i); + + // If the channel is found then mark it unused and stop playing the note. + if (opl2Channel > -1) { + keyChannel[opl2Channel] = -1; + opl2.setKeyOn(opl2Channel, false); + } + } + } + + // Lower the octave when user key 1 is pressed. + if (piano.wasKeyPressed(KEY_USER_1) && octave > 0) { + octave --; + } + + // Raise the octave when user key 2 is pressed. + if (piano.wasKeyPressed(KEY_USER_2) && octave < 6) { + octave ++; + } + + delay(20); +} + + +/** + * Look for a free channel on the OPL2 that we can use to play a note on. There is a prefered channel that is + * incremented each time a note is played. This is to allow for the sound of a node to fade out when a key is released. + * If the prefered channel is already in use then look for an available channel across all available ones. + * + * @return {int} The index of the OPL2 channel to use or -1 if no channels are available. + */ +int getFreeChannel() { + int opl2Channel = -1; + + // If the prefered channel is available then use it. + if (keyChannel[chIndex] == -1) { + opl2Channel = chIndex; + chIndex = (chIndex + 1) % 9; + + // The preferd channel is used, so look for one that is available. + } else { + for (int i = 0; i < 9; i ++) { + if (keyChannel[i] == 0) { + opl2Channel = i; + break; + } + } + } + + return opl2Channel; +} + + +/** + * Get the OPL2 channel that is playing the given note. + * + * @param {int} key - The index of the PianoBoard key for which to find the associated channel. + * @return {int} The OPL2 channel that is playing the note of the given key or -1 if note is not playing. + */ +int getKeyChannel(int key) { + for (int i = 0; i < 9; i ++) { + if (keyChannel[i] == key) { + return i; + } + } + + return -1; +} diff --git a/examples/Scale/Scale.ino b/examples/Scale/Scale.ino new file mode 100644 index 0000000..a1a5472 --- /dev/null +++ b/examples/Scale/Scale.ino @@ -0,0 +1,43 @@ +/** + * This is a simple demo sketch for the OPL2 library. It plays a repeating musical scale on channels 0 using a piano + * instrument. + * + * OPL2 board is connected as follows: + * Pin 8 - Reset + * Pin 9 - A0 + * Pin 10 - Latch + * Pin 11 - Data + * Pin 13 - Shift + * + * Refer to the wiki at https://github.com/DhrBaksteen/ArduinoOPL2/wiki/Connecting to learn how to connect your platform + * of choice! + * + * Code by Maarten Janssen (maarten@cheerful.nl) 2020-04-10 + * Most recent version of the library can be found at my GitHub: https://github.com/DhrBaksteen/ArduinoOPL2 + */ + +#include +#include +#include + + +OPL2 opl2; + +void setup() { + opl2.init(); + + Instrument piano = opl2.loadInstrument(INSTRUMENT_PIANO1); // Load a piano instrument. + opl2.setInstrument(0, piano); // Assign the instrument to OPL2 channel 0. +} + + +void loop() { + for (int note = NOTE_C; note <= NOTE_B; note ++) { + opl2.playNote(0, 4, note); // Play the note on octave 4, channel 0. + delay(400); // Wait a bit (note is held down: sustain). + opl2.setKeyOn(0, false); // Release the key (stop playing the note). + delay(200); // Wait a bit (note will die down: release). + } + + delay(500); +} diff --git a/library.properties b/library.properties index 2da4235..66e121e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Arduino OPL2 -version=1.5.1 +version=1.5.2 author=Maarten Janssen maintainer=Maarten Janssen sentence=Use this library to control the OPL2 Audio Board