aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/adlmidi.h4
-rw-r--r--src/adlmidi.cpp52
-rw-r--r--src/adlmidi_private.hpp10
-rw-r--r--utils/adlmidi-2/adlmidi-2.pro5
-rw-r--r--utils/adlmidi-2/midiplay.cc49
5 files changed, 88 insertions, 32 deletions
diff --git a/include/adlmidi.h b/include/adlmidi.h
index 6ecb22b..24fa4c9 100644
--- a/include/adlmidi.h
+++ b/include/adlmidi.h
@@ -175,9 +175,11 @@ extern const struct Adl_MarkerEntry adl_metaMarker(struct ADL_MIDIPlayer *device
-/*Take a sample buffer*/
+/*Take a sample buffer and iterate MIDI timers */
extern int adl_play(struct ADL_MIDIPlayer *device, int sampleCount, short out[]);
+/*Generate audio output from chip emulators without iteration of MIDI timers. 512 samples per channel is a maximum*/
+extern int adl_generate(ADL_MIDIPlayer *device, int sampleCount, short *out);
/**Hooks**/
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index 9a0aaa4..59d7a7e 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -477,17 +477,15 @@ inline static void SendStereoAudio(MIDIplay::Setup &device,
ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
{
+ sampleCount -= sampleCount % 2; //Avoid even sample requests
+ if(sampleCount < 0)
+ return 0;
if(!device)
return 0;
MIDIplay *player = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
MIDIplay::Setup &setup = player->m_setup;
- sampleCount -= sampleCount % 2; //Avoid even sample requests
-
- if(sampleCount < 0)
- return 0;
-
ssize_t gotten_len = 0;
ssize_t n_periodCountStereo = 512;
//ssize_t n_periodCountPhys = n_periodCountStereo * 2;
@@ -576,3 +574,47 @@ ADLMIDI_EXPORT int adl_play(ADL_MIDIPlayer *device, int sampleCount, short *out)
return static_cast<int>(gotten_len);
}
+
+
+ADLMIDI_EXPORT int adl_generate(ADL_MIDIPlayer *device, int sampleCount, short *out)
+{
+ sampleCount -= sampleCount % 2; //Avoid even sample requests
+ if(sampleCount < 0)
+ return 0;
+ if(!device)
+ return 0;
+
+ MIDIplay *player = reinterpret_cast<MIDIplay *>(device->adl_midiPlayer);
+ sampleCount = (sampleCount > 1024) ? 1024 : sampleCount;
+
+ //! Count of stereo samples
+ ssize_t in_generatedStereo = sampleCount / 2;
+ //! Unsigned total sample count
+ //fill buffer with zeros
+ std::memset(out, 0, static_cast<size_t>(sampleCount) * sizeof(int16_t));
+
+ if(player->m_setup.NumCards == 1)
+ {
+ #ifdef ADLMIDI_USE_DOSBOX_OPL
+ player->opl.cards[0].GenerateArr(out, &in_generatedStereo);
+ in_generatedPhys = in_generatedStereo * 2;
+ #else
+ OPL3_GenerateStream(&player->opl.cards[0], out, static_cast<Bit32u>(in_generatedStereo));
+ #endif
+ }
+ else
+ {
+ /* Generate data from every chip and mix result */
+ for(unsigned card = 0; card < player->m_setup.NumCards; ++card)
+ {
+ #ifdef ADLMIDI_USE_DOSBOX_OPL
+ player->opl.cards[card].GenerateArrMix(out, &in_generatedStereo);
+ in_generatedPhys = in_generatedStereo * 2;
+ #else
+ OPL3_GenerateStreamMix(&player->opl.cards[card], out, static_cast<Bit32u>(in_generatedStereo));
+ #endif
+ }
+ }
+
+ return sampleCount;
+}
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 0997556..650291a 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -236,6 +236,7 @@ struct MIDIEventHooks
void *onDebugMessage_userData;
};
+
class MIDIplay
{
public:
@@ -424,7 +425,6 @@ public:
// Index to physical adlib data structure, adlins[]
char ____padding2[3];
uint32_t insmeta;
- char ____padding3[4];
struct Phys
{
//! ins, inde to adl[]
@@ -442,7 +442,8 @@ public:
}
};
typedef std::map<uint16_t, Phys> PhysMap;
- // List of adlib channels it is currently occupying.
+ char ____padding3[4];
+ // List of OPL3 channels it is currently occupying.
std::map<uint16_t /*adlchn*/, Phys> phys;
};
typedef std::map<uint8_t, NoteInfo> activenotemap_t;
@@ -462,7 +463,7 @@ public:
activenotes() { }
};
- // Additional information about AdLib channels
+ // Additional information about OPL3 channels
struct AdlChannel
{
// For collisions
@@ -483,9 +484,8 @@ public:
struct LocationData
{
bool sustained;
- char ____padding[1];
+ char ____padding[7];
MIDIchannel::NoteInfo::Phys ins; // a copy of that in phys[]
- char ____padding2[4];
int64_t kon_time_until_neglible;
int64_t vibdelay;
};
diff --git a/utils/adlmidi-2/adlmidi-2.pro b/utils/adlmidi-2/adlmidi-2.pro
index 9c5df16..2b797ff 100644
--- a/utils/adlmidi-2/adlmidi-2.pro
+++ b/utils/adlmidi-2/adlmidi-2.pro
@@ -13,6 +13,11 @@ INCLUDEPATH += $$PWD/../../src $$PWD/../../include
#LIBS += -Wl,-Bstatic -lSDL2 -Wl,-Bdynamic -lpthread -ldl
LIBS += -lSDL2 -lpthread -ldl
+linux-*: {
+ QMAKE_CXXFLAGS += -fopenmp
+ QMAKE_LFLAGS += -fopenmp
+}
+
#DEFINES += DEBUG_TIME_CALCULATION
#DEFINES += DEBUG_SEEKING_TEST
#DEFINES += DISABLE_EMBEDDED_BANKS
diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc
index 8f22b76..bd7c9d6 100644
--- a/utils/adlmidi-2/midiplay.cc
+++ b/utils/adlmidi-2/midiplay.cc
@@ -21,7 +21,7 @@
#include <assert.h>
#define SUPPORT_VIDEO_OUTPUT
-#define SUPPORT_PUZZLE_GAME
+//#define SUPPORT_PUZZLE_GAME
#ifdef __WIN32__
# include <cctype>
@@ -1270,22 +1270,23 @@ static void SendStereoAudio(unsigned long count, short *samples)
/*
* THIS CLASS USES !!!ADL PRIVATE!!!
*/
-class Tester
+class AdlInstrumentTester
{
- unsigned cur_gm;
- unsigned ins_idx;
- std::vector<unsigned> adl_ins_list;
- OPL3 &opl;// !!!ADL PRIVATE!!!
+ uint32_t cur_gm;
+ uint32_t ins_idx;
+ std::vector<uint32_t> adl_ins_list;
+ OPL3 &opl;
+
public:
- Tester(OPL3 &o) // !!!ADL PRIVATE!!!
+ AdlInstrumentTester(OPL3 &o)
: opl(o)
{
cur_gm = 0;
ins_idx = 0;
}
- ~Tester()
- {
- }
+
+ ~AdlInstrumentTester()
+ {}
// Find list of adlib instruments that supposedly implement this GM
void FindAdlList()
@@ -1323,16 +1324,17 @@ public:
int tone = (cur_gm & 128) ? (cur_gm & 127) : (note + 50);
if(ains.tone)
{
- if(ains.tone < 20)
+ /*if(ains.tone < 20)
tone += ains.tone;
- else if(ains.tone < 128)
+ 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 };
- int adlchannel[2] = { 0, 3 };
+ int32_t adlchannel[2] = { 0, 3 };
if(i[0] == i[1])
{
adlchannel[1] = -1;
@@ -1352,16 +1354,16 @@ public:
for(unsigned c = 0; c < 2; ++c)
{
if(adlchannel[c] < 0) continue;
- opl.Patch(adlchannel[c], i[c]);
- opl.Touch_Real(adlchannel[c], 127 * 127 * 100);
- opl.Pan(adlchannel[c], 0x30);
- opl.NoteOn(adlchannel[c], hertz);
+ 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 + offset) & 0xFF;
+ cur_gm = (cur_gm + 256 + (uint32_t)offset) & 0xFF;
FindAdlList();
}
@@ -1369,7 +1371,7 @@ public:
{
if(adl_ins_list.empty()) FindAdlList();
const unsigned NumBanks = (unsigned)adl_getBanksCount();
- ins_idx = (ins_idx + adl_ins_list.size() + offset) % adl_ins_list.size();
+ 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);
@@ -1860,7 +1862,7 @@ int main(int argc, char **argv)
#endif /* djgpp */
// !!!ADL PRIVATE!!!
- Tester InstrumentTester(((MIDIplay *)myDevice->adl_midiPlayer)->opl);
+ AdlInstrumentTester InstrumentTester(((MIDIplay *)myDevice->adl_midiPlayer)->opl);
//static std::vector<int> sample_buf;
double delay = 0.0;
@@ -1873,7 +1875,12 @@ int main(int argc, char **argv)
#ifndef __DJGPP__
const double eat_delay = delay < maxdelay ? delay : maxdelay;
delay -= eat_delay;
- size_t got = (size_t)adl_play(myDevice, 1024, buff);
+ size_t got = 0;
+
+ if(!DoingInstrumentTesting)
+ got = (size_t)adl_play(myDevice, 1024, buff);
+ else
+ got = (size_t)adl_generate(myDevice, 1024, buff);
if(got <= 0)
break;
/* Process it */