diff options
-rw-r--r-- | include/adlmidi.h | 4 | ||||
-rw-r--r-- | src/adlmidi.cpp | 52 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 10 | ||||
-rw-r--r-- | utils/adlmidi-2/adlmidi-2.pro | 5 | ||||
-rw-r--r-- | utils/adlmidi-2/midiplay.cc | 49 |
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 */ |