aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt7
-rw-r--r--README.md5
-rw-r--r--include/adlmidi.hpp56
-rw-r--r--src/adlmidi_midiplay.cpp175
-rw-r--r--src/adlmidi_private.hpp4
-rw-r--r--utils/adlmidi-2/midiplay.cc518
6 files changed, 268 insertions, 497 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3bae41a..60c9b4c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,7 +113,6 @@ endfunction()
option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON)
option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF)
-option(WITH_CPP_EXTRAS "Build with support for C++ extras (features can be found in 'adlmidi.hpp' header)" OFF)
option(WITH_MIDI_SEQUENCER "Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins." ON)
option(WITH_EMBEDDED_BANKS "Use embedded banks" ON)
option(WITH_HQ_RESAMPLER "Build with support for high quality resampling" OFF)
@@ -209,10 +208,6 @@ function(handle_options targetLib)
target_compile_definitions(${targetLib} PUBLIC ADLMIDI_DISABLE_MIDI_SEQUENCER)
endif()
- if(NOT WITH_CPP_EXTRAS)
- target_compile_definitions(${targetLib} PUBLIC ADLMIDI_DISABLE_CPP_EXTRAS)
- endif()
-
if(WITH_EMBEDDED_BANKS AND WITH_GENADLDATA AND NOT ADLMIDI_DOS)
add_dependencies(${targetLib} gen-adldata-run)
endif()
@@ -365,7 +360,6 @@ install(TARGETS ${libADLMIDI_INSTALLS}
install(FILES
include/adlmidi.h
- include/adlmidi.hpp
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
file(GLOB DOCTXT_FILES
@@ -406,7 +400,6 @@ message("libADLMIDI_STATIC = ${libADLMIDI_STATIC}")
message("libADLMIDI_SHARED = ${libADLMIDI_SHARED}")
message("WITH_UNIT_TESTS = ${WITH_UNIT_TESTS}")
-message("WITH_CPP_EXTRAS = ${WITH_CPP_EXTRAS}")
message("WITH_MIDI_SEQUENCER = ${WITH_MIDI_SEQUENCER}")
message("WITH_EMBEDDED_BANKS = ${WITH_EMBEDDED_BANKS}")
message("WITH_HQ_RESAMPLER = ${WITH_HQ_RESAMPLER}")
diff --git a/README.md b/README.md
index 21bb6ed..5d5d1b5 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,6 @@ The library is licensed under in it's parts LGPL 2.1+, GPL v2+, GPL v3+, and MIT
* **libADLMIDI_SHARED** - (ON/OFF, default OFF) Build shared library
* **WITH_UNIT_TESTS** - (ON/OFF, default OFF) Enable unit testing
-* **WITH_CPP_EXTRAS** - (ON/OFF, default OFF) Build libADLMIDI with some extra public features for C++ language (for example, instrument testing API is available for C++ only).
* **WITH_MIDI_SEQUENCER** - (ON/OFF, default ON) Build with embedded MIDI sequencer. Disable this if you want use library in real-time MIDI drivers or plugins.)
* **WITH_EMBEDDED_BANKS** - (ON/OFF, default ON) Enable or disable embedded banks (Original ADLMIDI and older versions of libADLMIDI are had embedded-only banks with no ability to load custom banks in runtime).
* **WITH_HQ_RESAMPLER** - (ON/OFF, default OFF) Build with support for high quality resampling (requires zita-resampler to be installed)
@@ -101,7 +100,7 @@ The library is licensed under in it's parts LGPL 2.1+, GPL v2+, GPL v3+, and MIT
* **WITH_MIDIPLAY** - (ON/OFF, default OFF) Build demo MIDI player (Requires SDL2 and also pthread on Windows with MinGW)
* **MIDIPLAY_WAVE_ONLY** - (ON/OFF, default OFF) Build Demo MIDI player without support of real time playing. It will output into WAV only.
-* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows. Also, the **WITH_CPP_EXTRAS** flag must be enabled)
+* **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows).
* **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC. Support for other platforms comming soon!
* **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI
* **EXAMPLE_SDL2_AUDIO** - (ON/OFF, default OFF) Build also a simple SDL2 demo MIDI player
@@ -121,7 +120,6 @@ You need to make in the any IDE a library project and put into it next files
### Public header (include)
* adlmidi.h - Library Public API header, use it to control library
-* adlmidi.hpp - Public additional C++ API header, optional
### Internal code (src)
* chips/* - Various OPL3 chip emulators and commonized interface over them
@@ -187,6 +185,7 @@ To build that example you will need to have installed SDL2 library.
* Fixed an accuracy of the DMX volume model, include the buggy AM intepretation
* Fully rewritten an embedded banks database
* Improved an accuracy of Apogee volume model, include the bug of AM instruments
+ * Removed C++ extras. C++-binded instruments tester is useless since a real-time MIDI API can completely replace it.
## 1.4.0 2018-10-01
* Implemented a full support for Portamento! (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!)
diff --git a/include/adlmidi.hpp b/include/adlmidi.hpp
deleted file mode 100644
index 0df6dd4..0000000
--- a/include/adlmidi.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libADLMIDI is a free Software MIDI synthesizer library with OPL3 emulation
- *
- * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma <bisqwit@iki.fi>
- * ADLMIDI Library API: Copyright (c) 2015-2020 Vitaly Novichkov <admin@wohlnet.ru>
- *
- * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation:
- * http://iki.fi/bisqwit/source/adlmidi.html
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ADLMIDI_HPP
-#define ADLMIDI_HPP
-
-#include "adlmidi.h"
-
-struct ADL_MIDIPlayer;
-
-class ADLMIDI_DECLSPEC AdlInstrumentTester
-{
- struct Impl;
- Impl *p;
-
-public:
- explicit AdlInstrumentTester(ADL_MIDIPlayer *device);
- virtual ~AdlInstrumentTester();
-
- void start();
-
- // Find list of adlib instruments that supposedly implement this GM
- void FindAdlList();
- void DoNote(int note);
- void DoNoteOff();
- void NextGM(int offset);
- void NextAdl(int offset);
- bool HandleInputChar(char ch);
-
-private:
- AdlInstrumentTester(const AdlInstrumentTester &);
- AdlInstrumentTester &operator=(const AdlInstrumentTester &);
-};
-
-#endif //ADLMIDI_HPP
-
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index c3ef14c..70e5854 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -1865,178 +1865,3 @@ void MIDIplay::describeChannels(char *str, char *attr, size_t size)
str[index] = 0;
attr[index] = 0;
}
-
-#ifndef ADLMIDI_DISABLE_CPP_EXTRAS
-
-struct AdlInstrumentTester::Impl
-{
- uint32_t cur_gm;
- uint32_t ins_idx;
- int cur_note;
- std::vector<uint32_t> adl_ins_list;
- Synth *opl;
- MIDIplay *play;
-};
-
-ADLMIDI_EXPORT AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device)
- : p(new Impl)
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- MIDIplay *play = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
- p->cur_gm = 0;
- p->ins_idx = 0;
- p->cur_note = -1;
- p->play = play;
- p->opl = play ? play->m_synth.get() : NULL;
-#else
- ADL_UNUSED(device);
-#endif
-}
-
-ADLMIDI_EXPORT AdlInstrumentTester::~AdlInstrumentTester()
-{
- delete p;
-}
-
-ADLMIDI_EXPORT void AdlInstrumentTester::start()
-{
- NextGM(0);
-}
-
-ADLMIDI_EXPORT void AdlInstrumentTester::FindAdlList()
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- p->play->realTime_panic();
- p->cur_note = -1;
- p->opl->silenceAll();
-#endif
-}
-
-
-ADLMIDI_EXPORT void AdlInstrumentTester::DoNote(int note)
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- DoNoteOff();
- p->play->realTime_NoteOn(0, note, 127);
- p->cur_note = note;
-#else
- ADL_UNUSED(note);
-#endif
-}
-
-void AdlInstrumentTester::DoNoteOff()
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- if(p->cur_note > 0)
- p->play->realTime_NoteOff(0, p->cur_note);
-#endif
-}
-
-ADLMIDI_EXPORT void AdlInstrumentTester::NextGM(int offset)
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- if(offset < 0 && (static_cast<long>(p->cur_gm) + offset) < 0)
- p->cur_gm += g_embeddedBanksCount;
-
- p->cur_gm += offset;
-
- if(p->cur_gm >= g_embeddedBanksCount)
- p->cur_gm = (p->cur_gm + offset) - g_embeddedBanksCount;
-
- p->play->m_setup.numFourOps = -1;
- p->opl->setEmbeddedBank(p->cur_gm);
- adlCalculateFourOpChannels(p->play, true);
- p->opl->updateChannelCategories();
-
-// std::printf("Bank %u [%s]\n", P->cur_gm, adl_getBankNames()[P->cur_gm]);
-// std::fflush(stdout);
-
- FindAdlList();
-#else
- ADL_UNUSED(offset);
-#endif
-}
-
-ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
-{
-#ifndef DISABLE_EMBEDDED_BANKS
-
-#if 0
- UI.Color(15);
- std::fflush(stderr);
- std::printf("SELECTED G%c%d\t%s\n",
- cur_gm < 128 ? 'M' : 'P', cur_gm < 128 ? cur_gm + 1 : cur_gm - 128,
- "<-> select GM, ^v select ins, qwe play note");
- std::fflush(stdout);
- UI.Color(7);
- std::fflush(stderr);
-#endif
-
- if(offset < 0 && (static_cast<long>(p->ins_idx) + offset) < 0)
- p->ins_idx += 127;
-
- p->ins_idx += offset;
-
- if(p->ins_idx >= 127)
- p->ins_idx = (p->ins_idx + offset) - 127;
-
- p->play->realTime_PatchChange(0, p->ins_idx);
- p->play->realTime_Controller(0, 7, 127);
- p->play->realTime_Controller(0, 11, 127);
- p->play->realTime_Controller(0, 10, 64);
-
-// std::printf("Instrument %u\n", p->ins_idx);
-// std::fflush(stdout);
-
-#else
- ADL_UNUSED(offset);
-#endif
-}
-
-ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
-{
-#ifndef DISABLE_EMBEDDED_BANKS
- static const char notes[] = "zsxdcvgbhnjmq2w3er5t6y7ui9o0p";
- // c'd'ef'g'a'bC'D'EF'G'A'Bc'd'e
- switch(ch)
- {
- case '/':
- case 'H':
- case 'A':
- NextAdl(-1);
- break;
- case '*':
- case 'P':
- case 'B':
- NextAdl(+1);
- break;
- case '-':
- case 'K':
- case 'D':
- NextGM(-1);
- break;
- case '+':
- case 'M':
- case 'C':
- NextGM(+1);
- break;
- case ' ':
- DoNoteOff();
- break;
- case 3:
-#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
- case 27:
-#endif
- return false;
- default:
- const char *p = std::strchr(notes, ch);
- if(p && *p)
- DoNote((int)(p - notes) + 48);
- }
-#else
- ADL_UNUSED(ch);
-#endif
- return true;
-}
-
-#endif /* ADLMIDI_DISABLE_CPP_EXTRAS */
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 2d47ade..a5a3b8c 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -151,10 +151,6 @@ typedef class OPL3 Synth;
#define ADLMIDI_BUILD
#include "adlmidi.h" //Main API
-#ifndef ADLMIDI_DISABLE_CPP_EXTRAS
-#include "adlmidi.hpp" //Extra C++ API
-#endif
-
#include "adlmidi_ptr.hpp"
class MIDIplay;
diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc
index 7867968..f48828c 100644
--- a/utils/adlmidi-2/midiplay.cc
+++ b/utils/adlmidi-2/midiplay.cc
@@ -81,7 +81,7 @@ public:
#include <signal.h>
#include "adlmidi.h"
-#include "adlmidi.hpp"
+
#ifndef __DJGPP__
@@ -186,7 +186,7 @@ static class UserInterface
#endif
public:
static constexpr unsigned NColumns = 1216 / 20;
- #ifdef SUPPORT_VIDEO_OUTPUT
+#ifdef SUPPORT_VIDEO_OUTPUT
static constexpr unsigned VidWidth = 1216, VidHeight = 2160;
static constexpr unsigned FontWidth = 20, FontHeight = 45;
static constexpr unsigned TxWidth = (VidWidth / FontWidth), TxHeight = (VidHeight / FontHeight);
@@ -194,10 +194,10 @@ public:
unsigned short CharBuffer[TxWidth * TxHeight] = {0};
bool DirtyCells[TxWidth * TxHeight] = {false};
unsigned NDirty = 0;
- #endif
- #ifdef _WIN32
+#endif
+#ifdef _WIN32
void *handle;
- #endif
+#endif
int x, y, color, txtline, maxy;
// Text:
@@ -221,22 +221,22 @@ public:
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
- #ifdef _WIN32
+#ifdef _WIN32
fflush(stderr);
- #endif
+#endif
}
#endif
UserInterface():
- #ifdef SUPPORT_PUZZLE_GAME
+#ifdef SUPPORT_PUZZLE_GAME
player(2),
computer(31),
- #endif
+#endif
x(0), y(0), color(-1), txtline(0),
maxy(0), cursor_visible(true)
{
GuessInitialWindowHeight();
- #ifdef _WIN32
+#ifdef _WIN32
handle = GetStdHandle(STD_OUTPUT_HANDLE);
GotoXY(41, 13);
CONSOLE_SCREEN_BUFFER_INFO tmp;
@@ -252,19 +252,19 @@ public:
//COORD size = { NColumns, 23*NumCards+5 };
//SetConsoleScreenBufferSize(handle,size);
}
- #endif
- #if (!defined(_WIN32) || defined(__CYGWIN__)) && defined(TIOCGWINSZ)
+#endif
+#if (!defined(_WIN32) || defined(__CYGWIN__)) && defined(TIOCGWINSZ)
std::signal(SIGWINCH, SigWinchHandler);
- #endif
- #ifdef __DJGPP__
+#endif
+#ifdef __DJGPP__
color = 7;
- #endif
+#endif
std::memset(slots, '.', sizeof(slots));
std::memset(background, '.', sizeof(background));
std::memset(backgroundcolor, 1, sizeof(backgroundcolor));
- #ifndef _WIN32
+#ifndef _WIN32
std::setvbuf(stderr, stderr_buffer, _IOFBF, sizeof(stderr_buffer));
- #endif
+#endif
RawPrn("\r"); // Ensure cursor is at the x=0 we imagine it being
Print(0, 7, true, "Hit Ctrl-C to quit");
}
@@ -272,7 +272,7 @@ public:
{
if(!cursor_visible) return;
cursor_visible = false;
- #ifdef _WIN32
+#ifdef _WIN32
if(handle)
{
const CONSOLE_CURSOR_INFO info = {100, false};
@@ -281,15 +281,15 @@ public:
CheckTetris();
return;
}
- #endif
+#endif
if(!DoingInstrumentTesting)
CheckTetris();
- #ifdef __DJGPP__
+#ifdef __DJGPP__
{
_setcursortype(_NOCURSOR);
return;
}
- #endif
+#endif
RawPrn("\33[?25l"); // hide cursor
}
void ShowCursor()
@@ -298,28 +298,28 @@ public:
cursor_visible = true;
GotoXY(0, maxy);
Color(7);
- #ifdef _WIN32
+#ifdef _WIN32
if(handle)
{
const CONSOLE_CURSOR_INFO info = {100, true};
SetConsoleCursorInfo(handle, &info);
return;
}
- #endif
- #ifdef __DJGPP__
+#endif
+#ifdef __DJGPP__
{
_setcursortype(_NORMALCURSOR);
return;
}
- #endif
+#endif
RawPrn("\33[?25h"); // show cursor
std::fflush(stderr);
}
void VidPut(char c)
{
- #ifndef SUPPORT_VIDEO_OUTPUT
+#ifndef SUPPORT_VIDEO_OUTPUT
c = c;
- #else
+#else
unsigned clr = (unsigned)color, tx = (unsigned)x, ty = (unsigned)y;
unsigned cell_index = ty * TxWidth + tx;
if(cell_index < TxWidth * TxHeight)
@@ -337,7 +337,7 @@ public:
}
#endif
}
- #ifdef SUPPORT_VIDEO_OUTPUT
+#ifdef SUPPORT_VIDEO_OUTPUT
static unsigned VidTranslateColor(unsigned c)
{
static const unsigned colors[16] =
@@ -389,19 +389,19 @@ public:
}
}
}
- #endif
+#endif
void PutC(char c)
{
- #ifdef _WIN32
+#ifdef _WIN32
if(handle) WriteConsole(handle, &c, 1, 0, 0);
else
- #endif
+#endif
{
- #ifdef __DJGPP__
+#ifdef __DJGPP__
putch(c);
- #else
+#else
std::fputc(c, stderr);
- #endif
+#endif
}
VidPut(c);
++x; // One letter drawn. Update cursor position.
@@ -410,11 +410,11 @@ public:
int Print(unsigned beginx, unsigned color, bool ln, const char *fmt, va_list ap)
{
char Line[1024];
- #ifndef __CYGWIN__
+#ifndef __CYGWIN__
int nchars = std::vsnprintf(Line, sizeof(Line), fmt, ap);
- #else
+#else
int nchars = std::vsprintf(Line, fmt, ap); /* SECURITY: POSSIBLE BUFFER OVERFLOW (Cygwin) */
- #endif
+#endif
//if(nchars == 0) return nchars;
HideCursor();
@@ -565,7 +565,7 @@ public:
y += 1;
x = 0;
}
- #ifdef _WIN32
+#ifdef _WIN32
if(handle)
{
CONSOLE_SCREEN_BUFFER_INFO tmp;
@@ -578,14 +578,14 @@ public:
}
SetConsoleCursorPosition(handle, tmp2);
}
- #endif
- #ifdef __DJGPP__
+#endif
+#ifdef __DJGPP__
{
gotoxy(x = newx, wherey() - (y - newy));
y = newy;
return;
}
- #endif
+#endif
// Go up with \33[A
if(newy < y)
{
@@ -613,15 +613,15 @@ public:
{
if(color != newcolor)
{
- #ifdef _WIN32
+#ifdef _WIN32
if(handle)
SetConsoleTextAttribute(handle, newcolor);
else
- #endif
- #ifdef __DJGPP__
+#endif
+#ifdef __DJGPP__
textattr(newcolor);
if(0)
- #endif
+#endif
{
static const char map[8 + 1] = "04261537";
RawPrn("\33[0;%s40;3%c", (newcolor & 8) ? "1;" : "", map[newcolor & 7]);
@@ -1289,197 +1289,214 @@ static void SendStereoAudio(unsigned long count, short* samples)
}
#endif /* not DJGPP */
-/*
- * THIS CLASS USES !!!ADL PRIVATE!!!
- */
-
-//class OPL3;
-//class AdlInstrumentTester
-//{
-// uint32_t cur_gm;
-// uint32_t ins_idx;
-// std::vector<uint32_t> adl_ins_list;
-// OPL3 *opl;
-// MIDIplay * play;
-
-//public:
-// AdlInstrumentTester(ADL_MIDIPlayer *device)
-// {
-// cur_gm = 0;
-// ins_idx = 0;
-// play = reinterpret_cast<MIDIplay*>(device->adl_midiPlayer);
-// if(!play)
-// return;
-// opl = &play->opl;
-// }
-
-// ~AdlInstrumentTester()
-// {}
-
-// // Find list of adlib instruments that supposedly implement this GM
-// void FindAdlList()
-// {
-// const unsigned NumBanks = (unsigned)adl_getBanksCount();
-// std::set<unsigned> adl_ins_set;
-// for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
-// adl_ins_set.insert(banks[bankno][cur_gm]);
-// adl_ins_list.assign(adl_ins_set.begin(), adl_ins_set.end());
-// ins_idx = 0;
-// NextAdl(0);
-// opl->Silence();
-// }
-
-
-// void Touch(unsigned c, unsigned volume) // Volume maxes at 127*127*127
-// {
-// if(opl->LogarithmicVolumes)// !!!ADL PRIVATE!!!
-// opl->Touch_Real(c, volume * 127 / (127 * 127 * 127) / 2);// !!!ADL PRIVATE!!!
-// else
-// {
-// // The formula below: SOLVE(V=127^3 * 2^( (A-63.49999) / 8), A)
-// opl->Touch_Real(c, volume > 8725 ? static_cast<unsigned int>(std::log(volume) * 11.541561 + (0.5 - 104.22845)) : 0);// !!!ADL PRIVATE!!!
-// // The incorrect formula below: SOLVE(V=127^3 * (2^(A/63)-1), A)
-// //Touch_Real(c, volume>11210 ? 91.61112 * std::log(4.8819E-7*volume + 1.0)+0.5 : 0);
-// }
-// }
-
-// void DoNote(int note)
-// {
-// if(adl_ins_list.empty()) FindAdlList();
-// const unsigned meta = adl_ins_list[ins_idx];
-// const adlinsdata &ains = opl->GetAdlMetaIns(meta);// !!!ADL PRIVATE!!!
-
-// int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50);
-// if(ains.tone)
-// {
-// /*if(ains.tone < 20)
-// tone += ains.tone;
-// else */
-// if(ains.tone < 128)
-// tone = ains.tone;
-// else
-// tone -= ains.tone - 128;
-// }
-// double hertz = 172.00093 * std::exp(0.057762265 * (tone + 0.0));
-// int i[2] = { ains.adlno1, ains.adlno2 };
-// int32_t adlchannel[2] = { 0, 3 };
-// if(i[0] == i[1])
-// {
-// adlchannel[1] = -1;
-// adlchannel[0] = 6; // single-op
-// std::printf("noteon at %d(%d) for %g Hz\n",
-// adlchannel[0], i[0], hertz);
-// }
-// else
-// {
-// std::printf("noteon at %d(%d) and %d(%d) for %g Hz\n",
-// adlchannel[0], i[0], adlchannel[1], i[1], hertz);
-// }
-
-// opl->NoteOff(0);
-// opl->NoteOff(3);
-// opl->NoteOff(6);
-// for(unsigned c = 0; c < 2; ++c)
-// {
-// if(adlchannel[c] < 0) continue;
-// opl->Patch((uint16_t)adlchannel[c], (uint16_t)i[c]);
-// opl->Touch_Real((uint16_t)adlchannel[c], 127 * 127 * 100);
-// opl->Pan((uint16_t)adlchannel[c], 0x30);
-// opl->NoteOn((uint16_t)adlchannel[c], hertz);
-// }
-// }
-
-// void NextGM(int offset)
-// {
-// cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF;
-// FindAdlList();
-// }
-
-// void NextAdl(int offset)
-// {
-// if(adl_ins_list.empty()) FindAdlList();
-// const unsigned NumBanks = (unsigned)adl_getBanksCount();
-// ins_idx = (uint32_t)((int32_t)ins_idx + (int32_t)adl_ins_list.size() + offset) % adl_ins_list.size();
-
-// UI.Color(15);
-// std::fflush(stderr);
-// std::printf("SELECTED G%c%d\t%s\n",
-// cur_gm < 128 ? 'M' : 'P', cur_gm < 128 ? cur_gm + 1 : cur_gm - 128,
-// "<-> select GM, ^v select ins, qwe play note");
-// std::fflush(stdout);
-// UI.Color(7);
-// std::fflush(stderr);
-// for(unsigned a = 0; a < adl_ins_list.size(); ++a)
-// {
-// const unsigned i = adl_ins_list[a];
-// const adlinsdata &ains = opl->GetAdlMetaIns(i);
-
-// char ToneIndication[8] = " ";
-// if(ains.tone)
-// {
-// /*if(ains.tone < 20)
-// std::sprintf(ToneIndication, "+%-2d", ains.tone);
-// else*/
-// if(ains.tone < 128)
-// std::sprintf(ToneIndication, "=%-2d", ains.tone);
-// else
-// std::sprintf(ToneIndication, "-%-2d", ains.tone - 128);
-// }
-// std::printf("%s%s%s%u\t",
-// ToneIndication,
-// ains.adlno1 != ains.adlno2 ? "[2]" : " ",
-// (ins_idx == a) ? "->" : "\t",
-// i
-// );
-
-// for(unsigned bankno = 0; bankno < NumBanks; ++bankno)
-// if(banks[bankno][cur_gm] == i)
-// std::printf(" %u", bankno);
-
-// std::printf("\n");
-// }
-// }
-
-// bool HandleInputChar(char ch)
-// {
-// static const char notes[] = "zsxdcvgbhnjmq2w3er5t6y7ui9o0p";
-// // c'd'ef'g'a'bC'D'EF'G'A'Bc'd'e
-// switch(ch)
-// {
-// case '/':
-// case 'H':
-// case 'A':
-// NextAdl(-1);
-// break;
-// case '*':
-// case 'P':
-// case 'B':
-// NextAdl(+1);
-// break;
-// case '-':
-// case 'K':
-// case 'D':
-// NextGM(-1);
-// break;
-// case '+':
-// case 'M':
-// case 'C':
-// NextGM(+1);
-// break;
-// case 3:
-// #if !((!defined(_WIN32) || defined(__CYGWIN__)) && !defined(__DJGPP__))
-// case 27:
-// #endif
-// return false;
-// break;
-// default:
-// const char *p = strchr(notes, ch);
-// if(p && *p)
-// DoNote((p - notes) - 12);
-// }
-// return true;
-// }
-//};
+
+class AdlInstrumentTester
+{
+ struct Impl;
+ Impl *p;
+
+public:
+ explicit AdlInstrumentTester(ADL_MIDIPlayer *device);
+ virtual ~AdlInstrumentTester();
+
+ void start();
+
+ // Find list of adlib instruments that supposedly implement this GM
+ void FindAdlList();
+ void DoNote(int note);
+ void DoNoteOff();
+ void NextGM(int offset);
+ void NextAdl(int offset);
+ bool HandleInputChar(char ch);
+
+ void printIntst();
+
+private:
+ AdlInstrumentTester(const AdlInstrumentTester &);
+ AdlInstrumentTester &operator=(const AdlInstrumentTester &);
+};
+
+
+struct AdlInstrumentTester::Impl
+{
+ bool is_drums;
+ int play_chan;
+ int cur_gm;
+ int ins_idx;
+ int cur_note;
+ ADL_MIDIPlayer *device;
+};
+
+AdlInstrumentTester::AdlInstrumentTester(ADL_MIDIPlayer *device)
+ : p(new Impl)
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ p->is_drums = false;
+ p->play_chan = 0;
+ p->cur_gm = 0;
+ p->ins_idx = 0;
+ p->cur_note = -1;
+ p->device = device;
+#else
+ ADL_UNUSED(device);
+#endif
+}
+
+AdlInstrumentTester::~AdlInstrumentTester()
+{
+ delete p;
+}
+
+void AdlInstrumentTester::start()
+{
+ NextGM(0);
+}
+
+void AdlInstrumentTester::FindAdlList()
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ adl_panic(p->device);
+ p->cur_note = -1;
+#endif
+}
+
+
+void AdlInstrumentTester::DoNote(int note)
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ DoNoteOff();
+ adl_rt_noteOn(p->device, p->play_chan, note, 127);
+ p->cur_note = note;
+#else
+ ADL_UNUSED(note);
+#endif
+}
+
+void AdlInstrumentTester::DoNoteOff()
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ if(p->cur_note > 0)
+ adl_rt_noteOff(p->device, 0, p->cur_note);
+#endif
+}
+
+void AdlInstrumentTester::NextGM(int offset)
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ int maxBanks = adl_getBanksCount();
+ if(offset < 0 && (static_cast<long>(p->cur_gm) + offset) < 0)
+ p->cur_gm += maxBanks;
+
+ p->cur_gm += offset;
+
+ if(p->cur_gm >= maxBanks)
+ p->cur_gm = (p->cur_gm + offset) - maxBanks;
+
+ adl_setBank(p->device, p->cur_gm);
+
+ FindAdlList();
+
+ printIntst();
+#else
+ ADL_UNUSED(offset);
+#endif
+}
+
+void AdlInstrumentTester::NextAdl(int offset)
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+
+#if 0
+ UI.Color(15);
+ std::fflush(stderr);
+ std::printf("SELECTED G%c%d\t%s\n",
+ cur_gm < 128 ? 'M' : 'P', cur_gm < 128 ? cur_gm + 1 : cur_gm - 128,
+ "<-> select GM, ^v select ins, qwe play note");
+ std::fflush(stdout);
+ UI.Color(7);
+ std::fflush(stderr);
+#endif
+
+ if(offset < 0 && (static_cast<long>(p->ins_idx) + offset) < 0)
+ p->ins_idx += 127;
+
+ p->ins_idx += offset;
+
+ if(p->ins_idx >= 127)
+ p->ins_idx = (p->ins_idx + offset) - 127;
+
+ adl_rt_patchChange(p->device, p->play_chan, p->ins_idx);
+ adl_rt_controllerChange(p->device, p->play_chan, 7, 127);
+ adl_rt_controllerChange(p->device, p->play_chan, 11, 127);
+ adl_rt_controllerChange(p->device, p->play_chan, 10, 64);
+
+ printIntst();
+#else
+ ADL_UNUSED(offset);
+#endif
+}
+
+bool AdlInstrumentTester::HandleInputChar(char ch)
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ static const char notes[] = "zsxdcvgbhnjmq2w3er5t6y7ui9o0p";
+ // c'd'ef'g'a'bC'D'EF'G'A'Bc'd'e
+ switch(ch)
+ {
+ case '/':
+ case 'H':
+ case 'A':
+ NextAdl(-1);
+ break;
+ case '*':
+ case 'P':
+ case 'B':
+ NextAdl(+1);
+ break;
+ case '-':
+ case 'K':
+ case 'D':
+ NextGM(-1);
+ break;
+ case '+':
+ case 'M':
+ case 'C':
+ NextGM(+1);
+ break;
+ case 'T':
+ p->is_drums = !p->is_drums;
+ p->play_chan = p->is_drums ? 9 : 0;
+ NextAdl(0);
+ case ' ':
+ DoNoteOff();
+ break;
+ case 3:
+#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__))
+ case 27:
+#endif
+ return false;
+ default:
+ const char *p = std::strchr(notes, ch);
+ if(p && *p)
+ DoNote((int)(p - notes) + 48);
+ }
+#else
+ ADL_UNUSED(ch);
+#endif
+ return true;
+}
+
+void AdlInstrumentTester::printIntst()
+{
+#ifndef DISABLE_EMBEDDED_BANKS
+ UI.GotoXY(0, 10);
+ UI.Print(0, 255, false, "Bank: %3d, Instrument %3d %10s ",
+ p->cur_gm, p->ins_idx, p->is_drums ? "drum" : "melodic");
+ UI.ShowCursor();
+#endif
+}
+
+
static void TidyupAndExit(int sig)
{
@@ -1724,11 +1741,11 @@ int main(int argc, char **argv)
#endif
ADL_MIDIPlayer *myDevice;
- #ifndef __DJGPP__
+#ifndef __DJGPP__
myDevice = adl_init(PCM_RATE);
- #else
+#else
myDevice = adl_init(48000);
- #endif
+#endif
// Set hooks
adl_setNoteHook(myDevice, adlNoteHook, (void *)&UI);
@@ -1820,9 +1837,7 @@ int main(int argc, char **argv)
#endif
adl_setLoopEnabled(myDevice, loopEnabled);
- #ifndef __DJGPP__
-
- #ifndef _WIN32
+#if !defined(__DJGPP__) && !defined(_WIN32)
static SDL_AudioSpec spec, obtained;
spec.freq = PCM_RATE;
spec.format = AUDIO_S16SYS;
@@ -1842,9 +1857,7 @@ int main(int argc, char **argv)
spec.samples, spec.freq, spec.channels,
obtained.samples, obtained.freq, obtained.channels);
}
- #endif
-
- #endif /* not DJGPP */
+#endif /* not DJGPP and not WIN32 */
if(argc >= 3)
{
@@ -1948,7 +1961,7 @@ int main(int argc, char **argv)
}
UI.Color(7);
- if(adl_openFile(myDevice, argv[1]) != 0)
+ if(!DoingInstrumentTesting && adl_openFile(myDevice, argv[1]) != 0)
{
std::fprintf(stderr, "%s\n", adl_errorInfo(myDevice));
UI.ShowCursor();
@@ -2128,7 +2141,7 @@ int main(int argc, char **argv)
//Shut up all sustaining notes
adl_panic(myDevice);
- #ifdef __DJGPP__
+#ifdef __DJGPP__
// Fix the skewed clock and reset BIOS tick rate
_farpokel(_dos_ds, 0x46C, BIOStimer_begin +
(BIOStimer - BIOStimer_begin)
@@ -2143,14 +2156,15 @@ int main(int argc, char **argv)
UI.ShowCursor();
UI.Color(7);
clrscr();
- #else
- #ifdef _WIN32
+#else
+
+#ifdef _WIN32
WindowsAudio::Close();
- #else
+#else
SDL_CloseAudio();
- #endif
+#endif
- #endif /* djgpp */
+#endif /* djgpp */
adl_close(myDevice);