diff --git a/README.md b/README.md
index d0f0181..ca625e0 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,11 @@
# MD_YM2413
-The YM2413, OPLL, is a cost-reduced FM synthesis sound chip manufactured
-by Yamaha Corporation and based on their YM3812 (OPL2).
+The YM2413, OPLL, is a cost-reduced FM synthesis sound chip manufactured by Yamaha Corporation and based on their YM3812 (OPL2).
-The simplifications mean that the YM2413 can only play one user-defined
-instrument at a time, with an additional 15 read-only hard-coded instrument
-profiles available. The IC can operate as 9 channels of instruments or 6
-channels with melodic instruments and 5 with percussion instruments.
+The simplifications mean that the YM2413 can only play one user-defined instrument at a time, with an additional 15 read-only hard-coded instrument profiles available. The IC can operate as 9 channels of instruments or 6 channels with melodic instruments and 5 with percussion instruments.
-Its main historical application was the generation of music and sound effects in
-microprocessor systems. It was extensively used in early game consoles, arcade games,
-home computers and low-cost synthesizer keyboards.
+Its main historical application was the generation of music and sound effects in microprocessor systems. It was extensively used in early game consoles, arcade games, home computers and low-cost synthesizer keyboards.
-This library implements functions that manage the sound and noise generation interface
-to the YM2413 IC through a clean API encapsulating the basic functionality provided
-by the hardware.
+This library implements functions that manage the sound generation interface to the YM2413 IC through a clean API encapsulating the basic functionality provided by the hardware.
[Library Documentation](https://majicdesigns.github.io/MD_YM2413/)
\ No newline at end of file
diff --git a/docs/YM2413_IC.png b/docs/YM2413_IC.png
new file mode 100644
index 0000000..bb1f43f
Binary files /dev/null and b/docs/YM2413_IC.png differ
diff --git a/docs/_m_d___y_m2413_8cpp.html b/docs/_m_d___y_m2413_8cpp.html
index de6f57c..7d87f36 100644
--- a/docs/_m_d___y_m2413_8cpp.html
+++ b/docs/_m_d___y_m2413_8cpp.html
@@ -116,7 +116,7 @@
Define the data for a custom instrument directly. The data is preformatted for the YM2413 device and will be passed through without further processing.
+
This method is used to set instrument definitions that are in OPLL format and held in the application as a compact byte sequence.
Define the playing envelope in OPL2/OPL3 format for the custom instrument. The parameters are in higher OPL format, which is readily available and very close to the YM2413 format (OPLL). Translations are made as required.
This method should be used with caution, as it bypasses all the checks and buffering built into the library. It is provided to support applications that are a collection of register setting to be written to hardware at set time intervals (eg, VGM files).
+
Parameters
+
+
addr
the 8 bit device address to write the data.
+
data
the 8 bit data value to write to the device.
+
+
+
+
The documentation for this class was generated from the following files:
The YM2413, OPLL, is a cost-reduced FM synthesis sound chip manufactured by Yamaha Corporation and based on their YM3812 (OPL2).
-
The simplifications mean that the YM2413 can only play one user-defined instrument at a time, with 15 read-only hard-coded instrument profiles available. The IC can operate as 9 channels of instruments or 6 channels with general instruments and 5 with hard-coded percussion instruments.
+
+
+
+YM2413 IC
+
The YM2413, OPLL, is a cost-reduced FM synthesis sound chip manufactured by Yamaha Corporation and based on their YM3812 (OPL2).
+
The simplifications mean that the YM2413 can only play one user-defined instrument at a time, with an additional 15 read-only hard-coded instrument profiles available. The IC can operate as 9 channels of instruments or 6 channels with melodic instruments and 5 with hard-coded percussion instruments.
Its main historical application was the generation of music and sound effects in microprocessor systems. It was extensively used in early game consoles, arcade games, home computers and low-cost synthesizer keyboards.
This library implements functions that manage the sound and noise generation interface to the YM2413 IC through a clean API encapsulating the basic functionality provided by the hardware.
Copyright (C) 2019 Marco Colli. All rights reserved.
+
Copyright (C) 2020 Marco Colli. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -102,7 +102,7 @@
-
Generated on Fri Nov 1 2019 09:41:40 for MD_YM2413 Library by
+
Generated on Thu Jan 30 2020 15:38:00 for MD_YM2413 Library by
1.8.16
The library implements methods to load custom instruments into the single available customizable slot.
+
The library is able to take two styles of instrument definitions
+
OPL2/OPL3 style definitions that can be downloaded from from various sites. The OPL2/3 definitions are translated into an OPLL compatible format. The major difference is in the way that wave types are handled - OPL2/3 definitions can have up to 7 different wave types while OPLL is limited to full or half sine wave - and the library has a mapping between the two.
+
Native OPLL (YM2413) definitions if these are known.
+
+
To play the custom instrument, use the loadInstrumentOPL2() or loadInstrument() methods to load the data for the custom instrument and then set the channel that will use this instrument to I_CUSTOM.
+
+
+
+
+
+
+
Generated on Thu Jan 30 2020 15:38:00 for MD_YM2413 Library by
+
+ 1.8.16
This is the bock diagram of the YM2413. It has an 8 bit bus interface with one address line to select one of two write-only registers. One register is used to select the byte register to access 8 of the 271 internal register bits and one for writing data to the selected register.
-
On the analog side there are two outputs, one each for the Rhythym and Melody outputs.
+
This is the block diagram of the YM2413. It has an 8 bit bus interface with one address line to select one of two write-only registers. One register is used to select the byte register to access 8 of the 271 internal register bits and one for writing data to the selected register.
+
On the analog side there are two outputs, one each for the Rhythm and Melody outputs.
The IC DIP package has 18 pins with the following pinout:
Note: If multiple ICs are interfaced, then the ICs CS line must also be used to select the right device and share the data lines.
@@ -144,7 +146,7 @@
0
0
1
Data write mode
Hardware Direct Connection to the MCU
-
The library 8 digital output data lines from the Arduino MCU and additional AO and WE digital outputs to load the data into the YM2413 IC.
+
The library uses 8 digital output data lines from the Arduino MCU and additional AO and WE digital outputs to load the data into the YM2413 IC.
The data pins used are for the application to specify as part of the object initialization parameters. The D array parameter has pin numbers arranged to correspond to the IC pins (ie, pin D[0] is connected to IC pin D0, D[1] to D1, etc). The AO and WE pins can be any arbitrary pins.
Connections between the MCU and YM2413 are mapped as shown below. The Arduino pins are arbitrary and those the pins shown are used in the library examples.
@@ -180,14 +182,14 @@
Hardware Direct Connection to the MCU
/IC [13] (MCU Reset)
Audio Output
-
The Audio output from pins 14 and 15 (MO, RO) of the IC can combined into a mono signal to directly feed an amplifer and external speaker.
+
The Audio output from pins 14 and 15 (MO, RO) of the IC can combined into a mono signal to directly feed an amplifier and external speaker.
-
Generated on Fri Nov 1 2019 09:41:40 for MD_YM2413 Library by
+
Generated on Thu Jan 30 2020 15:38:00 for MD_YM2413 Library by
1.8.16
The setup() function must include the begin() method. All the I/O pins are initialized at this time.
loop()
Automatic note off events (see below) are managed by the library. For this to happen in a timely manner, the loop() function must invoke run() every iteration through loop(). The run() method executes very quickly if the library has nothing to process, imposing minimal overheads on the user application.
-
run() may be omitted if the application manages all the noteOn() and noteOff() events withing the application.
+
run() may be omitted if the application manages all the noteOn() and noteOff() events within the application.
Playing a Note
A note starts with a note on event and ends with a note off event. The note on event is generated when the noteOn() method is invoked in the application code.
Note Off Events
The library provides flexibility on how the note off events are generated.
-
Invoking the noteOn() without a duration parameter means the user code needs to generate the note off for the channel. This method is suited to applications that directly link a physical event to playing the note (eg, switch on for note on and switch off for note off), or where the music being played includes its own note on and off events (eg, a MIDI score).
-
Invoking the the noteOn()__with a duration parameter__ causes the library to generate a note off event at the end of the specified total duration. This method suits applications where the sound duration is defined by the music being played (eg, RTTTL tunes). In this case the user code can determine if the noteOff() event has been generated by using the isIdle() method.
+
Invoking noteOn() without a duration parameter means the user code needs to generate the note off for the channel. This method is suited to applications that directly link a physical event to playing the note (eg, switch on for note on and switch off for note off), or where the music being played includes its own note on and off events (eg, a MIDI score).
+
Invoking noteOn() with a duration parameter causes the library to generate a note off event at the end of the specified total duration. This method suits applications where the sound duration is defined by the music being played (eg, RTTTL tunes). In this case the user code can determine if the noteOff() event has been generated by using the isIdle() method.
-
Generated on Fri Nov 1 2019 09:41:40 for MD_YM2413 Library by
+
Generated on Thu Jan 30 2020 15:38:00 for MD_YM2413 Library by
1.8.16
+
+
diff --git a/docs/search/functions_a.js b/docs/search/functions_a.js
new file mode 100644
index 0000000..90b56c8
--- /dev/null
+++ b/docs/search/functions_a.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+ ['_7emd_5fym2413_70',['~MD_YM2413',['../class_m_d___y_m2413.html#a0d760a4bb8fcbbbf8425e0ab5cc0c8f5',1,'MD_YM2413']]]
+];
diff --git a/docs/search/pages_0.js b/docs/search/pages_0.js
index ba0f667..37f3a14 100644
--- a/docs/search/pages_0.js
+++ b/docs/search/pages_0.js
@@ -1,5 +1,6 @@
var searchData=
[
- ['compiler_20switches_76',['Compiler Switches',['../page_compile_switch.html',1,'']]],
- ['copyright_77',['Copyright',['../page_copyright.html',1,'']]]
+ ['compiler_20switches_89',['Compiler Switches',['../page_compile_switch.html',1,'']]],
+ ['copyright_90',['Copyright',['../page_copyright.html',1,'']]],
+ ['custom_20instruments_91',['Custom Instruments',['../page_custom.html',1,'']]]
];
diff --git a/docs/search/pages_1.js b/docs/search/pages_1.js
index d2fcfc1..caa3b3c 100644
--- a/docs/search/pages_1.js
+++ b/docs/search/pages_1.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['hardware_20connections_78',['Hardware Connections',['../page_hardware.html',1,'']]]
+ ['hardware_20connections_92',['Hardware Connections',['../page_hardware.html',1,'']]]
];
diff --git a/docs/search/pages_2.js b/docs/search/pages_2.js
index df97262..5687a50 100644
--- a/docs/search/pages_2.js
+++ b/docs/search/pages_2.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['revision_20history_79',['Revision History',['../page_revision_history.html',1,'']]]
+ ['revision_20history_93',['Revision History',['../page_revision_history.html',1,'']]]
];
diff --git a/docs/search/pages_3.js b/docs/search/pages_3.js
index 6973168..df435f5 100644
--- a/docs/search/pages_3.js
+++ b/docs/search/pages_3.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['support_20the_20library_80',['Support the Library',['../page_donation.html',1,'']]]
+ ['support_20the_20library_94',['Support the Library',['../page_donation.html',1,'']]]
];
diff --git a/docs/search/pages_4.js b/docs/search/pages_4.js
index 3ce3a60..dd2efab 100644
--- a/docs/search/pages_4.js
+++ b/docs/search/pages_4.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['using_20the_20library_81',['Using the Library',['../page_library.html',1,'']]]
+ ['using_20the_20library_95',['Using the Library',['../page_library.html',1,'']]]
];
diff --git a/docs/search/pages_5.js b/docs/search/pages_5.js
index 86f626d..391a21c 100644
--- a/docs/search/pages_5.js
+++ b/docs/search/pages_5.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['ym2413_20sound_20synthesizer_20library_82',['YM2413 Sound Synthesizer Library',['../index.html',1,'']]]
+ ['ym2413_20sound_20synthesizer_20library_96',['YM2413 Sound Synthesizer Library',['../index.html',1,'']]]
];
diff --git a/docs/search/searchdata.js b/docs/search/searchdata.js
index 87b1100..d6e76db 100644
--- a/docs/search/searchdata.js
+++ b/docs/search/searchdata.js
@@ -1,10 +1,10 @@
var indexSectionsWithContent =
{
- 0: "abcdghilmnprsuvy~",
+ 0: "abcdghilmnoprsuvwy~",
1: "m",
2: "m",
- 3: "bcgimnrs~",
- 4: "cmpv",
+ 3: "bcgilmnrsw~",
+ 4: "cmopv",
5: "i",
6: "acdlv",
7: "chrsuy"
diff --git a/docs/search/variables_0.js b/docs/search/variables_0.js
index d0127e7..dd04490 100644
--- a/docs/search/variables_0.js
+++ b/docs/search/variables_0.js
@@ -1,8 +1,9 @@
var searchData=
[
- ['ch_5fbd_60',['CH_BD',['../class_m_d___y_m2413.html#afbcc9709c0797dc9f9e77291402b23a6',1,'MD_YM2413']]],
- ['ch_5fhh_61',['CH_HH',['../class_m_d___y_m2413.html#a8db1ee3b665d2f67ac7606e6c444aadd',1,'MD_YM2413']]],
- ['ch_5fsd_62',['CH_SD',['../class_m_d___y_m2413.html#a053738bc460cdb5e746a6f753aff846b',1,'MD_YM2413']]],
- ['ch_5ftcy_63',['CH_TCY',['../class_m_d___y_m2413.html#a6bb4921396d8331f7a8268ce7d06ff67',1,'MD_YM2413']]],
- ['ch_5ftom_64',['CH_TOM',['../class_m_d___y_m2413.html#ae16e4cd45a31d6c9cadce01728407f84',1,'MD_YM2413']]]
+ ['ch_5fbd_71',['CH_BD',['../class_m_d___y_m2413.html#afbcc9709c0797dc9f9e77291402b23a6',1,'MD_YM2413']]],
+ ['ch_5fhh_72',['CH_HH',['../class_m_d___y_m2413.html#a8db1ee3b665d2f67ac7606e6c444aadd',1,'MD_YM2413']]],
+ ['ch_5fsd_73',['CH_SD',['../class_m_d___y_m2413.html#a053738bc460cdb5e746a6f753aff846b',1,'MD_YM2413']]],
+ ['ch_5ftcy_74',['CH_TCY',['../class_m_d___y_m2413.html#a6bb4921396d8331f7a8268ce7d06ff67',1,'MD_YM2413']]],
+ ['ch_5ftom_75',['CH_TOM',['../class_m_d___y_m2413.html#ae16e4cd45a31d6c9cadce01728407f84',1,'MD_YM2413']]],
+ ['ch_5fundefined_76',['CH_UNDEFINED',['../class_m_d___y_m2413.html#a0396e7f1513a8b3772fb9600bb8115bb',1,'MD_YM2413']]]
];
diff --git a/docs/search/variables_1.js b/docs/search/variables_1.js
index a1ccd6b..9fce366 100644
--- a/docs/search/variables_1.js
+++ b/docs/search/variables_1.js
@@ -1,5 +1,5 @@
var searchData=
[
- ['max_5foctave_65',['MAX_OCTAVE',['../class_m_d___y_m2413.html#a0fb3500aadac8cfa56b3b283f46dee6e',1,'MD_YM2413']]],
- ['min_5foctave_66',['MIN_OCTAVE',['../class_m_d___y_m2413.html#a2e26a3194804e9783b597439f73e4b2c',1,'MD_YM2413']]]
+ ['max_5foctave_77',['MAX_OCTAVE',['../class_m_d___y_m2413.html#a0fb3500aadac8cfa56b3b283f46dee6e',1,'MD_YM2413']]],
+ ['min_5foctave_78',['MIN_OCTAVE',['../class_m_d___y_m2413.html#a2e26a3194804e9783b597439f73e4b2c',1,'MD_YM2413']]]
];
diff --git a/docs/search/variables_2.js b/docs/search/variables_2.js
index 2a9504a..ef15391 100644
--- a/docs/search/variables_2.js
+++ b/docs/search/variables_2.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['perc_5fchan_5fbase_67',['PERC_CHAN_BASE',['../class_m_d___y_m2413.html#a4f4d70b74b47e347126a1d32aa3deb1a',1,'MD_YM2413']]]
+ ['opl2_5fdata_5fsize_79',['OPL2_DATA_SIZE',['../class_m_d___y_m2413.html#a9a08b789c7deac60f9f88cfa7482bf1f',1,'MD_YM2413']]]
];
diff --git a/docs/search/variables_3.js b/docs/search/variables_3.js
index eb74c46..f0a7af5 100644
--- a/docs/search/variables_3.js
+++ b/docs/search/variables_3.js
@@ -1,5 +1,4 @@
var searchData=
[
- ['vol_5fmax_68',['VOL_MAX',['../class_m_d___y_m2413.html#a59ef0109f681e73292823edb016345ac',1,'MD_YM2413']]],
- ['vol_5foff_69',['VOL_OFF',['../class_m_d___y_m2413.html#a440959c72100f9004f074c8726f3c98e',1,'MD_YM2413']]]
+ ['perc_5fchan_5fbase_80',['PERC_CHAN_BASE',['../class_m_d___y_m2413.html#a4f4d70b74b47e347126a1d32aa3deb1a',1,'MD_YM2413']]]
];
diff --git a/docs/search/variables_4.js b/docs/search/variables_4.js
index 2a31e14..ef68001 100644
--- a/docs/search/variables_4.js
+++ b/docs/search/variables_4.js
@@ -1,6 +1,5 @@
var searchData=
[
- ['ta_78',['Ta',['../struct_m_d___s_n76489_1_1adsr_envelope__t.html#a12c0da24a32217165fcbb378713be0b7',1,'MD_SN76489::adsrEnvelope_t']]],
- ['td_79',['Td',['../struct_m_d___s_n76489_1_1adsr_envelope__t.html#aaf51f15e2b9364f7fa9daa272fb7b090',1,'MD_SN76489::adsrEnvelope_t']]],
- ['tr_80',['Tr',['../struct_m_d___s_n76489_1_1adsr_envelope__t.html#a5d5cac4a26216e3306096581809d7ac1',1,'MD_SN76489::adsrEnvelope_t']]]
+ ['vol_5fmax_81',['VOL_MAX',['../class_m_d___y_m2413.html#a59ef0109f681e73292823edb016345ac',1,'MD_YM2413']]],
+ ['vol_5foff_82',['VOL_OFF',['../class_m_d___y_m2413.html#a440959c72100f9004f074c8726f3c98e',1,'MD_YM2413']]]
];
diff --git a/examples/MD_YM2413_Custom/MD_YM2413_Custom.ino b/examples/MD_YM2413_Custom/MD_YM2413_Custom.ino
index c07ffb0..fc925de 100644
--- a/examples/MD_YM2413_Custom/MD_YM2413_Custom.ino
+++ b/examples/MD_YM2413_Custom/MD_YM2413_Custom.ino
@@ -1,7 +1,12 @@
// MD_YM2413 Library example program.
//
-// Allows interactive CLI setting of instrument parameters for exploring
-// what effect they can produce.
+// Example program for the MD_YM2413 library.
+//
+// Allows interactive CLI setting of 'canned' MIDI instrument parameters
+// for exploring what effect they can produce.
+//
+// MIDI instruments and drums are define in OPL2 format in the
+// midi_drums and midi_instruments header files, respectively.
//
// Library Dependencies
// MD_MusicTable library located at https://github.com/MajicDesigns/MD_MusicTable
@@ -97,7 +102,7 @@ void handlerT(char *param)
Serial.print(timePlay);
}
-void handlerL(char* param)
+void handlerLI(char* param)
{
uint16_t inst;
@@ -108,15 +113,29 @@ void handlerL(char* param)
S.loadInstrumentOPL2(midiInstruments[inst], true);
}
+void handlerLD(char* param)
+{
+ uint16_t drum;
+
+ param = getNum(drum, param);
+ // ensure in range
+ if (drum < DRUM_NOTE_BASE) drum = DRUM_NOTE_BASE;
+ if (drum >= DRUM_NOTE_BASE + NUM_MIDI_DRUMS) drum = DRUM_NOTE_BASE + NUM_MIDI_DRUMS - 1;
+ Serial.print("\n>Instrument ");
+ Serial.print(drum);
+ S.loadInstrumentOPL2(midiDrums[drum], true);
+}
+
const MD_cmdProcessor::cmdItem_t PROGMEM cmdTable[] =
{
- { "h", handlerHelp, "", "Show this help" },
- { "?", handlerHelp, "", "Show this help" },
- { "v", handlerV, "v", "Set channel volume to v [0..15]" },
- { "t", handlerT, "t", "Set play time duration to t ms" },
- { "l", handlerL, "n", "Load MIDI instrument n"},
- { "p", handlerP, "m", "Play MIDI Note m" },
- { "z", handlerZ, "", "Software reset" },
+ { "h", handlerHelp, "", "Show this help" },
+ { "?", handlerHelp, "", "Show this help" },
+ { "v", handlerV, "v", "Set channel volume to v [0..15]" },
+ { "t", handlerT, "t", "Set play time duration to t ms" },
+ { "li", handlerLI, "n", "Load MIDI instrument n [0..127]"},
+ { "ld", handlerLD, "n", "Load MIDI drum n [27 .. 86]"},
+ { "p", handlerP, "m", "Play MIDI Note m" },
+ { "z", handlerZ, "", "Software reset" },
};
MD_cmdProcessor CP(Serial, cmdTable, ARRAY_SIZE(cmdTable));
diff --git a/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Map.h b/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Map.h
index a1a9303..b335dbd 100644
--- a/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Map.h
+++ b/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Map.h
@@ -5,7 +5,7 @@ static const uint8_t PROGMEM MidiIMap[] =
{
// 1-8 Piano
MD_YM2413::I_PIANO, MD_YM2413::I_PIANO, MD_YM2413::I_PIANO, MD_YM2413::I_PIANO,
- MD_YM2413::I_PIANO, MD_YM2413::I_PIANO, MD_YM2413::I_HARPSICORD, MD_YM2413::I_HARPSICORD,
+ MD_YM2413::I_PIANO, MD_YM2413::I_PIANO, MD_YM2413::I_HARPSICHORD, MD_YM2413::I_HARPSICHORD,
// 9-16 Chrom Percussion
MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE,
MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE, MD_YM2413::I_VIBRAPHONE,
@@ -20,7 +20,7 @@ static const uint8_t PROGMEM MidiIMap[] =
MD_YM2413::I_SYNTH_BASS, MD_YM2413::I_SYNTH_BASS, MD_YM2413::I_SYNTH_BASS, MD_YM2413::I_SYNTH_BASS,
// 41-48 Strings
MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_ACOUSTIC_BASS,
- MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_HARPSICORD,
+ MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_HARPSICHORD,
// 49-56 Ensemble
MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN, MD_YM2413::I_VIOLIN,
MD_YM2413::I_ORGAN, MD_YM2413::I_ORGAN, MD_YM2413::I_SYNTH, MD_YM2413::I_SYNTH,
diff --git a/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Player.ino b/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Player.ino
index 42897fd..0249ec4 100644
--- a/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Player.ino
+++ b/examples/MD_YM2413_MIDI_Player/MD_YM2413_MIDI_Player.ino
@@ -1,4 +1,6 @@
// Play MIDI files from the SD card.
+//
+// Example file for the MD_YM2413 library
//
// Dependencies
// SDFat at https://github.com/greiman?tab=repositories
@@ -35,7 +37,7 @@ const uint8_t PITCHBEND_RANGE = 2; // +/- range in semitones
static const char PROGMEM PLAYLIST[][FILE_NAME_SIZE] =
{
-"MARBLEMC.MID",
+//"MARBLEMC.MID",
//"birthday.mid",
//"Mario.mid",
//"pacman.mid",
@@ -52,10 +54,10 @@ static const char PROGMEM PLAYLIST[][FILE_NAME_SIZE] =
//"FERNANDO.MID",
//"FUGUEGM.MID",
//"GANGNAM.MID",
-//"GBROWN.MID",
+"GBROWN.MID",
//"IPANEMA.mid",
//"MOZART.MID",
-//"POPCORN.MID",
+"POPCORN.MID",
//"PRDANCER.MID",
"PROWLER.MID",
//"SKYFALL.MID",
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/AIR.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/AIR.MID
new file mode 100644
index 0000000..703d143
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/AIR.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/BANDIT.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/BANDIT.MID
new file mode 100644
index 0000000..fec4a2e
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/BANDIT.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/CHATCHOO.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/CHATCHOO.MID
new file mode 100644
index 0000000..35512d2
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/CHATCHOO.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/ELISE.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/ELISE.MID
new file mode 100644
index 0000000..958a295
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/ELISE.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/FERNANDO.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/FERNANDO.MID
new file mode 100644
index 0000000..cfd5e8b
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/FERNANDO.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/FIRERAIN.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/FIRERAIN.MID
new file mode 100644
index 0000000..2a4e4f9
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/FIRERAIN.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/FUGUEGM.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/FUGUEGM.MID
new file mode 100644
index 0000000..b0b805d
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/FUGUEGM.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/GANGNAM.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/GANGNAM.MID
new file mode 100644
index 0000000..c4648ee
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/GANGNAM.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/GBROWN.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/GBROWN.MID
new file mode 100644
index 0000000..16b303a
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/GBROWN.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/IPANEMA.mid b/examples/MD_YM2413_MIDI_Player/MIDI files/IPANEMA.mid
new file mode 100644
index 0000000..d0d7800
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/IPANEMA.mid differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/JZBUMBLE.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/JZBUMBLE.MID
new file mode 100644
index 0000000..d0a4bd7
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/JZBUMBLE.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/LOOPDEMO.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/LOOPDEMO.MID
new file mode 100644
index 0000000..786287c
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/LOOPDEMO.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/MARBLEMC.mid b/examples/MD_YM2413_MIDI_Player/MIDI files/MARBLEMC.mid
new file mode 100644
index 0000000..f35f5ac
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/MARBLEMC.mid differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/MINUET.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/MINUET.MID
new file mode 100644
index 0000000..80673fc
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/MINUET.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/MOZART.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/MOZART.MID
new file mode 100644
index 0000000..dd6a282
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/MOZART.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/Mario.mid b/examples/MD_YM2413_MIDI_Player/MIDI files/Mario.mid
new file mode 100644
index 0000000..b02e5d3
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/Mario.mid differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/POPCORN.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/POPCORN.MID
new file mode 100644
index 0000000..275f7af
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/POPCORN.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/PRDANCER.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/PRDANCER.MID
new file mode 100644
index 0000000..828cbcc
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/PRDANCER.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/PROWLER.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/PROWLER.MID
new file mode 100644
index 0000000..d75065f
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/PROWLER.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/SKYFALL.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/SKYFALL.MID
new file mode 100644
index 0000000..26032bd
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/SKYFALL.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/SONATAC.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/SONATAC.MID
new file mode 100644
index 0000000..8456740
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/SONATAC.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/STRIPPER.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/STRIPPER.MID
new file mode 100644
index 0000000..5a10e77
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/STRIPPER.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/SYMPH9.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/SYMPH9.MID
new file mode 100644
index 0000000..764467f
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/SYMPH9.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/TWINKLE.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/TWINKLE.MID
new file mode 100644
index 0000000..736a34e
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/TWINKLE.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/XMAS.MID b/examples/MD_YM2413_MIDI_Player/MIDI files/XMAS.MID
new file mode 100644
index 0000000..2144473
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/XMAS.MID differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/birthday.mid b/examples/MD_YM2413_MIDI_Player/MIDI files/birthday.mid
new file mode 100644
index 0000000..b6d062c
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/birthday.mid differ
diff --git a/examples/MD_YM2413_MIDI_Player/MIDI files/pacman.mid b/examples/MD_YM2413_MIDI_Player/MIDI files/pacman.mid
new file mode 100644
index 0000000..eecc2f5
Binary files /dev/null and b/examples/MD_YM2413_MIDI_Player/MIDI files/pacman.mid differ
diff --git a/examples/MD_YM2413_Note/MD_YM2413_Note.ino b/examples/MD_YM2413_Note/MD_YM2413_Note.ino
index 856a5eb..e64b84b 100644
--- a/examples/MD_YM2413_Note/MD_YM2413_Note.ino
+++ b/examples/MD_YM2413_Note/MD_YM2413_Note.ino
@@ -76,7 +76,7 @@ void loop(void)
Serial.print(f);
Serial.print(F("Hz"));
for (uint8_t i = 0; i < CHAN_COUNT; i++)
- S.noteOn(i, f, PLAY_TIME);
+ S.noteOn(i, f, MD_YM2413::VOL_MAX, PLAY_TIME);
}
else // play by note/octave
{
@@ -93,7 +93,7 @@ void loop(void)
Serial.print(F(" N"));
Serial.print(n);
for (uint8_t i = 0; i < CHAN_COUNT; i++)
- S.noteOn(i, o, n, PLAY_TIME);
+ S.noteOn(i, o, n, MD_YM2413::VOL_MAX, PLAY_TIME);
}
playToggle = !playToggle;
diff --git a/examples/MD_YM2413_Percussion/MD_YM2413_Percussion.ino b/examples/MD_YM2413_Percussion/MD_YM2413_Percussion.ino
index 6af3907..579ff6c 100644
--- a/examples/MD_YM2413_Percussion/MD_YM2413_Percussion.ino
+++ b/examples/MD_YM2413_Percussion/MD_YM2413_Percussion.ino
@@ -1,12 +1,6 @@
// MD_YM2413 Library example program.
//
-// Plays MIDI notes START_NOTE to END_NOTE in sequence over and over again.
-// Tests tone/note playing functions of the library using timed notes
-// and supplying frequency or octave/note number for comparison of the way
-// each note is generated.
-//
-// Library Dependencies
-// MusicTable library located at https://github.com/MajicDesigns/MD_MusicTable
+// Plays each percussion instrument in turn.
//
#include
@@ -25,7 +19,7 @@ MD_YM2413 S(D_PIN, WE_PIN, A0_PIN);
void setup(void)
{
Serial.begin(57600);
- Serial.println(F("\n[MD_YM2413 Note Tester]"));
+ Serial.println(F("\n[MD_YM2413 Percussion Tester]"));
S.begin();
S.setPercussion(true);
@@ -33,7 +27,7 @@ void setup(void)
void loop(void)
{
- // testing range for octaves 0 through 7
+ // testing range for percussion channels
const uint8_t START_CHANNEL = MD_YM2413::CH_HH; // first percussion channel
const uint8_t END_CHANNEL = MD_YM2413::CH_BD; // last percussion channel
diff --git a/examples/MD_YM2413_RTTTL_Player/MD_YM2413_RTTTL_Player.ino b/examples/MD_YM2413_RTTTL_Player/MD_YM2413_RTTTL_Player.ino
index b369531..467117b 100644
--- a/examples/MD_YM2413_RTTTL_Player/MD_YM2413_RTTTL_Player.ino
+++ b/examples/MD_YM2413_RTTTL_Player/MD_YM2413_RTTTL_Player.ino
@@ -41,9 +41,13 @@ const uint8_t A0_PIN = 4; // Arduino pin connected to the A0 pin
const uint8_t PLAY_VOL = MD_YM2413::VOL_MAX;
// Number of playing channels and the instruments for each
-const uint8_t NUM_CHAN = 3;
-const MD_YM2413::instrument_t instr[NUM_CHAN] =
-{ MD_YM2413::I_PIANO, MD_YM2413::I_SYNTH_BASS, MD_YM2413::I_ACOUSTIC_BASS };
+const MD_YM2413::instrument_t instr[] =
+{
+ MD_YM2413::I_PIANO,
+ MD_YM2413::I_SYNTH_BASS,
+ MD_YM2413::I_ACOUSTIC_BASS
+};
+const uint8_t NUM_CHAN = ARRAY_SIZE(instr);
// Global Data ------------------------
MD_YM2413 S(D_PIN, WE_PIN, A0_PIN);
diff --git a/examples/MD_YM2413_VGM_Player_CLI/MD_YM2413_VGM_Player_CLI.ino b/examples/MD_YM2413_VGM_Player_CLI/MD_YM2413_VGM_Player_CLI.ino
index 36f39a1..079a239 100644
--- a/examples/MD_YM2413_VGM_Player_CLI/MD_YM2413_VGM_Player_CLI.ino
+++ b/examples/MD_YM2413_VGM_Player_CLI/MD_YM2413_VGM_Player_CLI.ino
@@ -1,6 +1,7 @@
// Command Line Interface (Serial) to play VGM files from the SD card.
//
-// Enter commands on the serial monitor to control the application
+// Example program for the MD_YM2413 library.
+// Enter commands on the serial monitor to control the application.
//
// Dependencies
// SDFat at https://github.com/greiman?tab=repositories
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/01DISC.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/01DISC.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/01DISC.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/01DISC.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/01SAMPLE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/01SAMPLE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/01SAMPLE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/01SAMPLE.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/02DISC.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/02DISC.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/02DISC.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/02DISC.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/02SAMPLE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/02SAMPLE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/02SAMPLE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/02SAMPLE.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/03SAMPLE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/03SAMPLE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/03SAMPLE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/03SAMPLE.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/04SAMPLE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/04SAMPLE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/04SAMPLE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/04SAMPLE.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/05SAMPLE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/05SAMPLE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/05SAMPLE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/05SAMPLE.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/INORGANIC.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/INORGANIC.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/INORGANIC.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/INORGANIC.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/OUTOFRAP.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/OUTOFRAP.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/OUTOFRAP.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/OUTOFRAP.VGM
diff --git a/examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/PRACTICE.VGM b/examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/PRACTICE.VGM
similarity index 100%
rename from examples/MD_YM2413_VGM_Player_CLI/YM_TUNES/PRACTICE.VGM
rename to examples/MD_YM2413_VGM_Player_CLI/VGM_TUNES/PRACTICE.VGM
diff --git a/keywords.txt b/keywords.txt
index bb19006..c2f40f7 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -23,8 +23,11 @@ setSustain KEYWORD2
setPercussion KEYWORD2
isPercussion KEYWORD2
countChannels KEYWORD2
+loadInstrument KEYWORD2
+loadInstrumentOPL2 KEYWORD2
isIdle KEYWORD2
run KEYWORD2
+write KEYWORD2
######################################
# Constants (LITERAL1)
@@ -34,8 +37,10 @@ VOL_OFF LITERAL1
VOL_MAX LITERAL1
MIN_OCTAVE LITERAL1
MAX_OCTAVE LITERAL1
+CH_UNDEFINED LITERAL1
+OPL2_DATA_SIZE LITERAL1
PERC_CHANNEL_BASE LITERAL1
-I_ORIGINAL LITERAL1
+I_CUSTOM LITERAL1
I_VIOLIN LITERAL1
I_GUITAR LITERAL1
I_PIANO LITERAL1
@@ -45,12 +50,12 @@ I_OBOE LITERAL1
I_TRUMPET LITERAL1
I_ORGAN LITERAL1
I_HORN LITERAL1
-I_SYNTHESIZER LITERAL1
+I_SYNTH LITERAL1
I_HARPSICORD LITERAL1
I_VIBRAPHONE LITERAL1
-I_SYNTHESIZER_BASS LITERAL1
+I_SYNTH_BASS LITERAL1
I_ACOUSTIC_BASS LITERAL1
-I_ELECTRIC_GUITAR LITERAL1
+I_EGUITAR LITERAL1
P_HI_HAT LITERAL1
P_TOP_CYMBAL LITERAL1
P_TOM_TOM LITERAL1
diff --git a/library.properties b/library.properties
index 698b175..9b6dc4a 100644
--- a/library.properties
+++ b/library.properties
@@ -2,8 +2,8 @@ name=MD_YM2413
version=1.0.0
author=majicDesigns
maintainer=marco_c <8136821@gmail.com>
-sentence=Library for Yahama YM2413 sound synthesizer.
-paragraph=Library to implement basic functionality for the Yahama YM2413 sound synthesizer chip
+sentence=Library for Yamaha YM2413 sound synthesizer.
+paragraph=Library to implement basic functionality for managing for Yamaha YM2413 sound synthesizer chip
category=Signal Input/Output
url=https://github.com/MajicDesigns/MD_YM2413
architectures=*
diff --git a/media/photo/YM2413_PCB_Bare.JPG b/media/photo/YM2413_PCB_Bare.JPG
new file mode 100644
index 0000000..89e8fa9
Binary files /dev/null and b/media/photo/YM2413_PCB_Bare.JPG differ
diff --git a/media/photo/YM2413_PCB_Design.png b/media/photo/YM2413_PCB_Design.png
new file mode 100644
index 0000000..e24cd42
Binary files /dev/null and b/media/photo/YM2413_PCB_Design.png differ
diff --git a/media/photo/YM2413_PCB_Populated.png b/media/photo/YM2413_PCB_Populated.png
new file mode 100644
index 0000000..b886743
Binary files /dev/null and b/media/photo/YM2413_PCB_Populated.png differ
diff --git a/media/photo/YM2413_Register_Map.png b/media/photo/YM2413_Register_Map.png
new file mode 100644
index 0000000..09bf951
Binary files /dev/null and b/media/photo/YM2413_Register_Map.png differ
diff --git a/media/photo/YM2413_Schematic.png b/media/photo/YM2413_Schematic.png
new file mode 100644
index 0000000..dc3bab4
Binary files /dev/null and b/media/photo/YM2413_Schematic.png differ
diff --git a/src/MD_YM2413.cpp b/src/MD_YM2413.cpp
index 620ae15..7f31990 100644
--- a/src/MD_YM2413.cpp
+++ b/src/MD_YM2413.cpp
@@ -18,7 +18,7 @@ _D(D), _we(we), _a0(a0)
void MD_YM2413::begin(void)
{
- // Set all pins to outputs and initialise
+ // Set all pins to outputs and initialize
for (int8_t i = 0; i < DATA_BITS; i++)
pinMode(_D[i], OUTPUT);
pinMode(_we, OUTPUT);
@@ -26,7 +26,7 @@ void MD_YM2413::begin(void)
digitalWrite(_we, HIGH);
- // initialise the hardware defaults
+ // initialize the hardware defaults
send(R_TEST_CTL_REG, 0); // never test mode
setPercussion(false); // all instruments to default (below)
}
@@ -95,7 +95,7 @@ void MD_YM2413::setPercussion(bool enable)
}
bool MD_YM2413::setInstrument(uint8_t chan, instrument_t instr, uint8_t vol)
-// 'attach' the specified instruiment to the channel
+// 'attach' the specified instrument to the channel
{
if (chan >= countChannels() || // not a valid channel
(!isPercussion() && instr >= P_HI_HAT)) // not a valid instrument for this mode
@@ -169,7 +169,7 @@ void MD_YM2413::setVolume(uint8_t chan, uint8_t v)
{
// Percussion mode is on and this is a percussion channel.
// These need to be sent in pairs as the registers
- // are organised in nybbles for different percussion instruments
+ // are organized in nibbles for different percussion instruments
switch (_C[chan].instrument)
{
case P_BASS_DRUM:
@@ -248,7 +248,7 @@ void MD_YM2413::noteOn(uint8_t chan, uint16_t freq, uint8_t vol, uint16_t durati
}
void MD_YM2413::noteOn(uint8_t chan, uint8_t octave, uint8_t note, uint8_t vol, uint16_t duration)
-// turn on a note by speficying the octave and note number
+// turn on a note by specifying the octave and note number
{
uint8_t data;
diff --git a/src/MD_YM2413.h b/src/MD_YM2413.h
index 44c0d27..d0ffc11 100644
--- a/src/MD_YM2413.h
+++ b/src/MD_YM2413.h
@@ -12,7 +12,7 @@
The YM2413 Synthesizer IC
-------------------------
-![YM2413 IC] (YM2413_IC.jpg "YM2413 IC")
+![YM2413 IC] (YM2413_IC.png "YM2413 IC")
The YM2413, OPLL, is a cost-reduced FM synthesis sound chip manufactured
by Yamaha Corporation and based on their YM3812 (OPL2).
@@ -42,11 +42,11 @@ Topics
References
----------
-- On-line IC datasheet at http://members.casema.nl/hhaydn/howel/parts/76489.htm
+- On-line IC data sheet at http://map.grauw.nl/resources/sound/yamaha_ym2413_frs.pdf
- Additional technical information from http://www.smspower.org/Development/YM2413
\page pageRevisionHistory Revision History
-xxx 2019 version 1.0.0
+Feb 2020 version 1.0.0
- Initial implementation.
\page pageHardware Hardware Connections
@@ -55,12 +55,12 @@ YM2413 IC Description
![YM2413 Block Diagram] (YM2413_BlockDiagram.png "YM2413 Block Diagram")
-This is the bock diagram of the YM2413. It has an 8 bit bus interface with one
+This is the block diagram of the YM2413. It has an 8 bit bus interface with one
address line to select one of two write-only registers. One register is used
to select the byte register to access 8 of the 271 internal register bits and
one for writing data to the selected register.
-On the analog side there are two outputs, one each for the Rhythym and Melody
+On the analog side there are two outputs, one each for the Rhythm and Melody
outputs.
The IC DIP package has 18 pins with the following pinout:
@@ -83,8 +83,9 @@ The IC DIP package has 18 pins with the following pinout:
|/CS | Active low Chip Select (connect to GND or MCU output if more than one IC shares D0-D7)
|/IC | Chip reset (pull up to Vcc or connect MCU reset)
|AO | Address/Data discriminator
-|MO, RO | Melody and Rhythm outputs
-|CLK | 4MHz clock signal (see below)
+|MO | Melody Output
+|RO | Rhythm Output
+|CLK | 4MHz clock signal
|VCC | 5V
|GND | Ground
@@ -166,32 +167,32 @@ Note Off Events
---------------
The library provides flexibility on how the note off events are generated.
-Invoking the noteOn() __without a duration parameter__ means the user code
+Invoking noteOn() __without a duration parameter__ means the user code
needs to generate the note off for the channel. This method is suited
to applications that directly link a physical event to playing the note (eg,
switch on for note on and switch off for note off), or where the music being
played includes its own note on and off events (eg, a MIDI score).
-Invoking the the noteOn() __with a duration parameter__ causes the library to
+Invoking noteOn() __with a duration parameter__ causes the library to
generate a note off event at the end of the specified total duration. This
method suits applications where the sound duration is defined by the music
being played (eg, RTTTL tunes). In this case the user code can determine
if the noteOff() event has been generated by using the isIdle() method.
-\pageCustom Custom Instruments
+\page pageCustom Custom Instruments
Defining and using Custom Instruments
--------------------------------------
-The library implements methods to load custome instruments into the single
-available customisable slot.
+The library implements methods to load custom instruments into the single
+available customizable slot.
-The library is able to take two styles of instrument defintions
-- OPL2/OPL3 syle defintions that can be downloaded from from variuous sites. The
+The library is able to take two styles of instrument definitions
+- OPL2/OPL3 style definitions that can be downloaded from from various sites. The
OPL2/3 definitions are translated into an OPLL compatible format. The major
-difference is in the way that wave types are handled - OPL2/3 defintions can have
-up to 7 different wave types while OPLL is limited to full or half svne wave - and
+difference is in the way that wave types are handled - OPL2/3 definitions can have
+up to 7 different wave types while OPLL is limited to full or half sine wave - and
the library has a mapping between the two.
-- Native OPLL (YM2413) defintions if these are known.
+- Native OPLL (YM2413) definitions if these are known.
To play the custom instrument, use the loadInstrumentOPL2() or loadInstrument() methods
to load the data for the custom instrument and then set the channel that will use this
@@ -209,7 +210,7 @@ If you like and use this library please consider making a small donation
using [PayPal](https://paypal.me/MajicDesigns/4USD)
\page pageCopyright Copyright
-Copyright (C) 2019 Marco Colli. All rights reserved.
+Copyright (C) 2020 Marco Colli. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -258,7 +259,7 @@ class MD_YM2413
*/
typedef enum
{
- // These instrument defintions match those for the
+ // These instrument definitions match those for the
// hardware register.
I_CUSTOM = 0,
I_VIOLIN = 1,
@@ -271,7 +272,7 @@ class MD_YM2413
I_ORGAN = 8,
I_HORN = 9,
I_SYNTH = 10,
- I_HARPSICORD = 11,
+ I_HARPSICHORD = 11,
I_VIBRAPHONE = 12,
I_SYNTH_BASS = 13,
I_ACOUSTIC_BASS = 14,
@@ -288,22 +289,22 @@ class MD_YM2413
I_UNDEFINED = 0xff,
} instrument_t;
- /**
- * Class Constructor.
- *
- * Instantiate a new instance of this derived class. The parameters passed are used to
- * connect the software to the hardware. Multiple instances may co-exist.
- *
- * The D array is arranged to correspond to the IC pins (ie, pin D[0] is connected
- * to IC pin D0, D[1] to D1, etc). D0 is the MSB in the data byte, D7 the LSB.
- *
- * The we and a0 pins are used for handshaking the data over the data bus.
- *
- * \sa \ref pageHardware
- *
- * \param D pointer to array of 8 pins used as the data bus interface
- * \param we pin number used as write enable
- * \param a0 pin number used as address/data selector
+ /**
+ * Class Constructor.
+ *
+ * Instantiate a new instance of this derived class. The parameters passed are used to
+ * connect the software to the hardware. Multiple instances may co-exist.
+ *
+ * The D array is arranged to correspond to the IC pins (ie, pin D[0] is connected
+ * to IC pin D0, D[1] to D1, etc). D0 is the MSB in the data byte, D7 the LSB.
+ *
+ * The we and a0 pins are used for handshaking the data over the data bus.
+ *
+ * \sa \ref pageHardware
+ *
+ * \param D pointer to array of 8 pins used as the data bus interface
+ * \param we pin number used as write enable
+ * \param a0 pin number used as address/data selector
*/
MD_YM2413(const uint8_t* D, uint8_t we, uint8_t a0);
@@ -320,7 +321,7 @@ class MD_YM2413
* Initialize the object data. This needs to be called during setup() to initialize
* new data for the class that cannot be done during the object creation.
*
- * All the I/O is initailise, percussion mode is disabled and all instruments are set
+ * All the I/O is initialize, percussion mode is disabled and all instruments are set
* as I_PIANO at VOL_MAX volume by default.
*
* \sa setVolume(), setInstrument(), setPercussion()
@@ -331,212 +332,213 @@ class MD_YM2413
/** \name Hardware and Library Management.
* @{
*/
- /**
- * Return the nummber of channels.
- *
- * Return the number of channels depending on whether the percussion instruments
- * are set.
- *
- * \sa setPercussion()
- *
- * \return the number of channels in the current configuration.
- */
+ /**
+ * Return the number of channels.
+ *
+ * Return the number of channels depending on whether the percussion instruments
+ * are set.
+ *
+ * \sa setPercussion()
+ *
+ * \return the number of channels in the current configuration.
+ */
uint8_t countChannels(void);
- /**
- * Return the current library mode
- *
- * Returns the current library/hartdware operating mode set by setPercussion().
- *
- * \sa setPercussion()
- *
- * \return true if percussion channels are enabled, false otherwise.
- */
+ /**
+ * Return the current library mode
+ *
+ * Returns the current library/hardware operating mode set by setPercussion().
+ *
+ * \sa setPercussion()
+ *
+ * \return true if percussion channels are enabled, false otherwise.
+ */
bool isPercussion(void) { return(_enablePercussion); }
- /**
- * Check if the channel is for percussion
- *
- * Returns whether the specified channel is allocated to a percussion
- * instrument. Percussion instruments are allocated to specific channels as
- * explained in setPercussion().
- *
- * \sa setPercussion()
- *
- * \param chan channel to check [0..countChannels()-1].
- * \return true if specified is for percussion, false otherwise.
- */
+ /**
+ * Check if the channel is for percussion
+ *
+ * Returns whether the specified channel is allocated to a percussion
+ * instrument. Percussion instruments are allocated to specific channels as
+ * explained in setPercussion().
+ *
+ * \sa setPercussion()
+ *
+ * \param chan channel to check [0..countChannels()-1].
+ * \return true if specified is for percussion, false otherwise.
+ */
bool isPercussion(uint8_t chan);
- /**
- * Set the current library/hardware operating mode.
- *
- * The library can operate with or without percussion instruments configured.
- * Without percussion instruments, there are 9 channels(0..8] available for
- * general instruments. With percussion enabled, there are 6 channels[0..5]
- * available for general instruments and 5 channels[6..10], for a total of 11,
- * allocated to percussion instruments.
- *
- * The method countChannels() will always return the total number of channels for
- * the current configuration.
- *
- * \sa isPercussion(), countChannels()
- *
- * \param bEnable true to enable percussion mode, false otherwise.
- */
+ /**
+ * Set the current library/hardware operating mode.
+ *
+ * The library can operate with or without percussion instruments configured.
+ * Without percussion instruments, there are 9 channels(0..8] available for
+ * general instruments. With percussion enabled, there are 6 channels[0..5]
+ * available for general instruments and 5 channels[6..10], for a total of 11,
+ * allocated to percussion instruments.
+ *
+ * The method countChannels() will always return the total number of channels for
+ * the current configuration.
+ *
+ * \sa isPercussion(), countChannels()
+ *
+ * \param bEnable true to enable percussion mode, false otherwise.
+ */
void setPercussion(bool bEnable);
- /**
- * Define the parameters for a custom instrument.
- *
- * Define the playing envelope in OPL2/OPL3 format for the custom instrument.
- * The parameters are in higher OPL format, which is readily available and very
- * close to the YM2413 format (OPLL). Translations are made as required.
- *
- * \sa \ref pageCustom
- *
- * \param ins an array of OPL2_DATA_SIZE uint8_t bytes in OPL2 format data.
- * \param fromPROGMEM true if the data is loaded from PROGMEM false otherwise.
- */
+ /**
+ * Define the parameters for a custom instrument.
+ *
+ * Define the playing envelope in OPL2/OPL3 format for the custom instrument.
+ * The parameters are in higher OPL format, which is readily available and very
+ * close to the YM2413 format (OPLL). Translations are made as required.
+ *
+ * \sa \ref pageCustom
+ *
+ * \param ins an array of OPL2_DATA_SIZE uint8_t bytes in OPL2 format data.
+ * \param fromPROGMEM true if the data is loaded from PROGMEM false otherwise.
+ */
void loadInstrumentOPL2(const uint8_t* ins, bool fromPROGMEM = true);
- /**
- * Define direct parameters for a custom instrument.
- *
- * Define the data for a custom instrument directly. The data is preformatted
- * for the YM2413 device and will be passed through without further processing.
- *
- * This method is used to set instrument definitions that are in OPLL format
- * and held in the application as a compact byte sequence.
- *
- * \sa \ref pageCustom
- *
- * \param data an array of 8 bytes in RAM that will be written to registers 0x00 through 0x07.
- */
+ /**
+ * Define direct parameters for a custom instrument.
+ *
+ * Define the data for a custom instrument directly. The data is preformatted
+ * for the YM2413 device and will be passed through without further processing.
+ *
+ * This method is used to set instrument definitions that are in OPLL format
+ * and held in the application as a compact byte sequence.
+ *
+ * \sa \ref pageCustom
+ *
+ * \param data an array of 8 bytes in RAM that will be written to registers 0x00 through 0x07.
+ */
void loadInstrument(const uint8_t* data) { for (uint8_t i = 0; i < 8; i++) send(i, data[i]); }
- /**
- * Standardise the instrument release phase
- *
- * For the specific channel, set the release vlue to a standarrised mid-point
- * for this instance of the instrument.
- *
- * \sa setInstrument()
- *
- * \param chan channel number on which sustain is set [0..countChannels()-1].
- * \param sustain set true to standardise the release phase to a mid level value.
- */
+ /**
+ * Standardize the instrument release phase
+ *
+ * For the specific channel, set the release value to a standarized mid-point
+ * for this instance of the instrument.
+ *
+ * \sa setInstrument()
+ *
+ * \param chan channel number on which sustain is set [0..countChannels()-1].
+ * \param sustain set true to standardize the release phase to a mid level value.
+ */
void setSustain(uint8_t chan, bool sustain) { if (chan < countChannels()) _C[chan].sustain = sustain; }
- /**
- * Return the idle state of a channel.
- *
- * Used to check if a channel is currently idle (ie, not playing a note).
- *
- * \param chan channel to check [0..countChannels()-1].
- * \return true if the channel is idle, false otherwise.
- */
+ /**
+ * Return the idle state of a channel.
+ *
+ * Used to check if a channel is currently idle (ie, not playing a note).
+ *
+ * \param chan channel to check [0..countChannels()-1].
+ * \return true if the channel is idle, false otherwise.
+ */
bool isIdle(uint8_t chan);
- /**
- * Run the music machine.
- *
- * Runs the automatic note off timing for all channels. This should be called
- * from the main loop() as frequently as possible to allow the library to execute
- * the note required timing for each channel.
- *
- * This method is not required if the application does not use durations when
- * invoking noteOn().
- */
+ /**
+ * Run the music machine.
+ *
+ * Runs the automatic note off timing for all channels. This should be called
+ * from the main loop() as frequently as possible to allow the library to execute
+ * the note required timing for each channel.
+ *
+ * This method is not required if the application does not use durations when
+ * invoking noteOn().
+ */
void run(void);
- /**
- * Write a byte directly to the device
- *
- * This method should be used with caution, as it bypasses all the checks
- * and buffering built into the library. It is provided to support applications
- * that are a collection of register setting to be written to hardware at set
- * time intervals (eg, VGM files).
- *
- * \param addr the 8 bit device address to write the data.
- * \param data the 8 bit data value to write to the device.
- */
+ /**
+ * Write a byte directly to the device
+ *
+ * This method should be used with caution, as it bypasses all the checks
+ * and buffering built into the library. It is provided to support applications
+ * that are a collection of register setting to be written to hardware at set
+ * time intervals (eg, VGM files).
+ *
+ * \param addr the 8 bit device address to write the data.
+ * \param data the 8 bit data value to write to the device.
+ */
inline void write(uint8_t addr, uint8_t data) { send(addr, data); }
- /** @} */
-
- //--------------------------------------------------------------
- /** \name Sound Management.
- * @{
- */
- /**
- * Set the playing instrument for a channel.
- *
- * Set the instrument for the channel to be one the value specified.
- * Valid instruments are given by the enumerated type instrument_t.
- *
- * If percussion is not enabled, the valid range of instruments is
- * one of the I_* values on channels [0..9]. The percussion instruments
- * P_* are automatically set up on the channels CH_* [6..11] when
- * percussion mode is enabled, and instruments I_* can be set up on
- * channels [0..5].
- *
- * Custom instruments must be defined before they can be used.
- *
- * \sa setPercussion(), instrument_t, setSustain(), defineInstrument()
- *
- * \param chan channel number on which volume is set [0..countChannels()-1].
- * \param instr one of the instruments I_* from instrument_t.
- * \param vol volume to set for the specificed channel in range [VOL_MIN..VOL_MAX].
- * \return true if the instrument was set correctly.
- */
+ /** @} */
+
+ //--------------------------------------------------------------
+ /** \name Sound Management.
+ * @{
+ */
+ /**
+ * Set the playing instrument for a channel.
+ *
+ * Set the instrument for the channel to be one the value specified.
+ * Valid instruments are given by the enumerated type instrument_t.
+ *
+ * If percussion is not enabled, the valid range of instruments is
+ * one of the I_* values on channels [0..9]. The percussion instruments
+ * P_* are automatically set up on the channels CH_* [6..11] when
+ * percussion mode is enabled, and instruments I_* can be set up on
+ * channels [0..5].
+ *
+ * Custom instruments must be defined before they can be used.
+ *
+ * \sa setPercussion(), instrument_t, setSustain(), defineInstrument()
+ *
+ * \param chan channel number on which volume is set [0..countChannels()-1].
+ * \param instr one of the instruments I_* from instrument_t.
+ * \param vol volume to set for the specified channel in range [VOL_MIN..VOL_MAX].
+ * \return true if the instrument was set correctly.
+ */
bool setInstrument(uint8_t chan, instrument_t instr, uint8_t vol = VOL_MAX);
- /**
- * Get the current instrument setting
- *
- * Get the instrument set for the specified channel. This will be one of
- * the instrument_t values.
- *
- * \sa setInstrument(), instrument_t
- *
- * \param chan channel number on which volume is set [0..countChannels()-1].
- * \return the value of the instrument set for the channel.
- */
+ /**
+ * Get the current instrument setting
+ *
+ * Get the instrument set for the specified channel. This will be one of
+ * the instrument_t values.
+ *
+ * \sa setInstrument(), instrument_t
+ *
+ * \param chan channel number on which volume is set [0..countChannels()-1].
+ * \return the value of the instrument set for the channel.
+ */
instrument_t getInstrument(uint8_t chan)
{ if (chan < countChannels()) return(_C[chan].instrument); else return(I_UNDEFINED); }
- /**
+ /**
* Get the volume for a channel.
*
* Get the current volume for a channel.
*
* \param chan channel number on which volume is set [0..countChannels()-1].
+ * \return the current volume in the range [VOL_MIN..VOL_MAX].
*/
uint8_t getVolume(uint8_t chan) { return(chan < countChannels() ? _C[chan].vol : 0); }
- /**
+ /**
* Set the volume for a channel.
*
* Set the volume for a channel to be the value specified.
* Valid values are all the values in the range [VOL_MIN..VOL_MAX].
*
* \param chan channel number on which volume is set [0..countChannels()-1].
- * \param v volume to set for the specificed channel in range [VOL_MIN..VOL_MAX].
+ * \param v volume to set for the specified channel in range [VOL_MIN..VOL_MAX].
*/
void setVolume(uint8_t chan, uint8_t v);
- /**
- * Set the volume for all channels.
- *
- * Set the volume for all channels to be the speified value. Valid values are all
- * the values in the range [VOL_MIN..VOL_MAX].
- *
- * \param v volume to set for all channels in range [VOL_MIN..VOL_MAX].
- */
+ /**
+ * Set the volume for all channels.
+ *
+ * Set the volume for all channels to be the specified value. Valid values are all
+ * the values in the range [VOL_MIN..VOL_MAX].
+ *
+ * \param v volume to set for all channels in range [VOL_MIN..VOL_MAX].
+ */
void setVolume(uint8_t v);
- /**
+ /**
* Play a note (frequency)
*
* Output a note with frequency freq on the specified channel using the
@@ -550,51 +552,51 @@ class MD_YM2413
*
* \param chan channel number on which to play this note [0..countChannels()-1].
* \param freq frequency to play.
- * \param vol volume to set this note in range [VOL_MIN..VOL_MAX].
+ * \param vol volume to set this note in range [VOL_MIN..VOL_MAX].
* \param duration length of time in ms for the whole note to last.
*/
void noteOn(uint8_t chan, uint16_t freq, uint8_t vol, uint16_t duration = 0);
- /**
- * Play a note (octave and note#)
- *
- * Output a note defined by octave and note number on the specified
- * channel using the instrument currently defined for the channel.
- *
- * Middle C is the first note in octave 4 (C4). Notes
- * [C, C#, D, D#, E, F, F#, G, G#, A, A#, B] are numbered sequentially
- * 0 to 11 within the octave.
- *
- * If specified, the duration will cause an automatic note off
- * event when the total time has expired. If duration is 0 the
- * note will be sustained until it is turned off by the application.
- *
- * \sa noteOff(), run()
- *
- * \param chan channel number on which to play this note [0..countChannels()-1].
- * \param octave the octave block for this note [MIN_OCTAVE..MAX_OCTAVE].
- * \param note the note number to play [0..11] as defined above.
- * \param vol volume to set this note in range [VOL_MIN..VOL_MAX].
- * \param duration length of time in ms for the whole note to last.
- */
+ /**
+ * Play a note (octave and note#)
+ *
+ * Output a note defined by octave and note number on the specified
+ * channel using the instrument currently defined for the channel.
+ *
+ * Middle C is the first note in octave 4 (C4). Notes
+ * [C, C#, D, D#, E, F, F#, G, G#, A, A#, B] are numbered sequentially
+ * 0 to 11 within the octave.
+ *
+ * If specified, the duration will cause an automatic note off
+ * event when the total time has expired. If duration is 0 the
+ * note will be sustained until it is turned off by the application.
+ *
+ * \sa noteOff(), run()
+ *
+ * \param chan channel number on which to play this note [0..countChannels()-1].
+ * \param octave the octave block for this note [MIN_OCTAVE..MAX_OCTAVE].
+ * \param note the note number to play [0..11] as defined above.
+ * \param vol volume to set this note in range [VOL_MIN..VOL_MAX].
+ * \param duration length of time in ms for the whole note to last.
+ */
void noteOn(uint8_t chan, uint8_t octave, uint8_t note, uint8_t vol, uint16_t duration = 0);
- /**
- * Stop playing a note
- *
- * Stop the note currently playing on the specified channel
- *
- * Causes a key-off event to be processed by the channel.
- *
- * \sa noteOn(), run()
- *
- * \param chan channel number on which to stop this note [0..countChannels()-1].
- */
+ /**
+ * Stop playing a note
+ *
+ * Stop the note currently playing on the specified channel
+ *
+ * Causes a key-off event to be processed by the channel.
+ *
+ * \sa noteOn(), run()
+ *
+ * \param chan channel number on which to stop this note [0..countChannels()-1].
+ */
void noteOff(uint8_t chan);
/** @} */
private:
- // channels sizeing definitons
+ // channels sizing definitions
static const uint8_t ALL_INSTR_CHANNELS = 9; ///< Number of instrument channels when all instruments
static const uint8_t PART_INSTR_CHANNELS = 6; ///< Number of instrument channels when shared with percussion
static const uint8_t PERC_CHANNELS = 5; ///< Number of percussion channels if they are defined
@@ -638,7 +640,7 @@ class MD_YM2413
{
instrument_t instrument; ///< the instrument assigned to this channel
bool sustain; ///< true if the instrument needs to be sustained after playing
- uint8_t vol; ///< volume setpoint for this channel, 0-15 (map to attenuator 15-0)
+ uint8_t vol; ///< volume set point for this channel, 0-15 (map to attenuator 15-0)
uint16_t frequency; ///< the frequency being played, 0 if not specified this way
uint8_t octave; ///< the octave for this note
uint16_t fNum; ///< the note frequency offset
diff --git a/src/MD_YM2413_hw.cpp b/src/MD_YM2413_hw.cpp
index 5905c23..55e0da9 100644
--- a/src/MD_YM2413_hw.cpp
+++ b/src/MD_YM2413_hw.cpp
@@ -13,7 +13,7 @@ See header file for copyright and licensing comments.
// Global data tables
// FNum lookup table for note play within a block (octave)
-// The data is organised by note number [0..11] corresponding to
+// The data is organized by note number [0..11] corresponding to
// notes C, C# .. A, A#, B
const uint16_t PROGMEM MD_YM2413::_fNumTable[] =
{