From 566b5208a52c3c6771651d98d9d67f371423980d Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Tue, 25 Sep 2018 15:33:50 +0200 Subject: dosbox: fix a potential cache access problem, and some warnings --- src/chips/dosbox/dbopl.cpp | 48 +++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/chips/dosbox/dbopl.cpp b/src/chips/dosbox/dbopl.cpp index 2d31708..1931203 100644 --- a/src/chips/dosbox/dbopl.cpp +++ b/src/chips/dosbox/dbopl.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include "dbopl.h" #if defined(__GNUC__) && __GNUC__ > 3 @@ -80,7 +81,8 @@ private: #if !defined(_WIN32) #include struct Mutex : NoCopy { - Mutex() : m(PTHREAD_MUTEX_INITIALIZER) {} + Mutex() { pthread_mutex_init(&m, NULL);} + ~Mutex() { pthread_mutex_destroy(&m); } void lock() { pthread_mutex_lock(&m); } void unlock() { pthread_mutex_unlock(&m); } pthread_mutex_t m; @@ -1331,14 +1333,26 @@ struct CacheEntry { Bit32u linearRates[76]; Bit32u attackRates[76]; }; -static std::vector cache; -static Mutex cacheMutex; +struct Cache : NoCopy { + ~Cache(); + Mutex mutex; + std::vector entries; +}; + +static Cache cache; + +Cache::~Cache() +{ + for ( size_t i = 0, n = entries.size(); i < n; ++i ) + delete entries[i]; +} static const CacheEntry *CacheLookupRateDependent( Bit32u rate ) { - for ( size_t i = 0, n = cache.size(); i < n; ++i ) { - if (cache[i].rate == rate) - return &cache[i]; + for ( size_t i = 0, n = cache.entries.size(); i < n; ++i ) { + const CacheEntry *entry = cache.entries[i]; + if (entry->rate == rate) + return entry; } return NULL; } @@ -1346,7 +1360,7 @@ static const CacheEntry *CacheLookupRateDependent( Bit32u rate ) static const CacheEntry &ComputeRateDependent( Bit32u rate ) { { - MutexHolder lock( cacheMutex ); + MutexHolder lock( cache.mutex ); if (const CacheEntry *entry = CacheLookupRateDependent( rate )) return *entry; } @@ -1354,11 +1368,15 @@ static const CacheEntry &ComputeRateDependent( Bit32u rate ) double original = OPLRATE; double scale = original / (double)rate; - CacheEntry entry; - entry.rate = rate; - Bit32u *freqMul = entry.freqMul; - Bit32u *linearRates = entry.linearRates; - Bit32u *attackRates = entry.attackRates; +#if __cplusplus >= 201103L + std::unique_ptr entry(new CacheEntry); +#else + std::auto_ptr entry(new CacheEntry); +#endif + entry->rate = rate; + Bit32u *freqMul = entry->freqMul; + Bit32u *linearRates = entry->linearRates; + Bit32u *attackRates = entry->attackRates; //With higher octave this gets shifted up //-1 since the freqCreateTable = *2 @@ -1434,12 +1452,12 @@ static const CacheEntry &ComputeRateDependent( Bit32u rate ) attackRates[i] = 8 << RATE_SH; } - MutexHolder lock( cacheMutex ); + MutexHolder lock( cache.mutex ); if (const CacheEntry *entry = CacheLookupRateDependent( rate )) return *entry; - cache.push_back(entry); - return cache.back(); + cache.entries.push_back(entry.get()); + return *entry.release(); } void Chip::Setup( Bit32u rate ) { -- cgit v1.2.3 From 60171b220a3d0d195fee73b284c4cae7fddf0f58 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 26 Sep 2018 02:24:37 +0300 Subject: Fixed the too fast killing of releasing notes #181 --- src/adlmidi_midiplay.cpp | 10 +++++++--- src/adlmidi_sequencer.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 42b5b01..9276d0e 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -104,7 +104,11 @@ void MIDIplay::AdlChannel::addAge(int64_t us) { const int64_t neg = 1000 * static_cast(-0x1FFFFFFFll); if(users_empty()) + { koff_time_until_neglible_us = std::max(koff_time_until_neglible_us - us, neg); + if(koff_time_until_neglible_us < 0) + koff_time_until_neglible_us = 0; + } else { koff_time_until_neglible_us = 0; @@ -1161,7 +1165,7 @@ void MIDIplay::noteUpdate(size_t midCh, } else { - m_chipChannels[c].koff_time_until_neglible_us = 1000 * ains.ms_sound_koff; + m_chipChannels[c].koff_time_until_neglible_us = 1000 * int64_t(ains.ms_sound_koff); } } } @@ -1338,7 +1342,7 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note //if(c == MidCh) s += 4; for(AdlChannel::LocationData *j = m_chipChannels[c].users_first; j; j = j->next) { - s -= 4000; + s -= 4000000; int64_t kon_ms = j->kon_time_until_neglible_us / 1000; s -= (j->sustained == AdlChannel::LocationData::Sustain_None) ? @@ -1356,7 +1360,7 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note // Arpeggio candidate = even better if(j->vibdelay_us < 70000 || j->kon_time_until_neglible_us > 20000000) - s += 0; + s += 10; } // Percussion is inferior to melody diff --git a/src/adlmidi_sequencer.cpp b/src/adlmidi_sequencer.cpp index 3c18cad..66b9b9a 100644 --- a/src/adlmidi_sequencer.cpp +++ b/src/adlmidi_sequencer.cpp @@ -137,7 +137,7 @@ double MIDIplay::Tick(double s, double granularity) s *= m_sequencer.getTempoMultiplier(); for(uint16_t c = 0; c < m_synth.m_numChannels; ++c) - m_chipChannels[c].addAge(static_cast(s * 1000.0)); + m_chipChannels[c].addAge(static_cast(s * 1e6)); updateVibrato(s); updateArpeggio(s); -- cgit v1.2.3 From 63dfa67e16887c550b29ee5a1e97c895a9878441 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 26 Sep 2018 02:58:19 +0300 Subject: Pay attention to releasing notes #181 --- src/adlmidi_load.cpp | 2 +- src/adlmidi_midiplay.cpp | 19 +++++++++++++++---- src/adlmidi_private.hpp | 4 ++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index 915b587..e86f23e 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -203,7 +203,7 @@ bool MIDIplay::LoadMIDI_post() adlins.adl[0] = adl; adlins.adl[1] = adl; adlins.ms_sound_kon = 1000; - adlins.ms_sound_koff = 0; + adlins.ms_sound_koff = 500; adlins.tone = 0; adlins.flags = 0; adlins.voice2_fine_tune = 0.0; diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 9276d0e..105d54a 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -588,6 +588,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) int32_t c = adlchannel[ccount]; if(c < 0) continue; + m_chipChannels[c].recent_ins = voices[ccount]; m_chipChannels[c].addAge(0); } @@ -1335,12 +1336,22 @@ void MIDIplay::setErrorString(const std::string &err) int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::NoteInfo::Phys &ins) const { - int64_t koff_ms = m_chipChannels[c].koff_time_until_neglible_us / 1000; - int64_t s = (m_synth.m_musicMode != OPL3::MODE_CMF) ? -koff_ms : 0; + const AdlChannel &chan = m_chipChannels[c]; + int64_t koff_ms = chan.koff_time_until_neglible_us / 1000; + int64_t s = -koff_ms; + + // Rate channel with a releasing note + if(s < 0 && chan.users_empty()) + { + s = -10000; + // If it's same instrument, better chance to get it when no free channels + if(chan.recent_ins == ins) + s = (m_synth.m_musicMode == OPL3::MODE_CMF) ? 0 : -5000; + return s; + } // Same midi-instrument = some stability - //if(c == MidCh) s += 4; - for(AdlChannel::LocationData *j = m_chipChannels[c].users_first; j; j = j->next) + for(AdlChannel::LocationData *j = chan.users_first; j; j = j->next) { s -= 4000000; diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index c5b70ee..43986c5 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -880,6 +880,9 @@ public: //! Time left until sounding will be muted after key off int64_t koff_time_until_neglible_us; + //! Recently passed instrument, improves a goodness of released but busy channel when matching + MIDIchannel::NoteInfo::Phys recent_ins; + enum { users_max = 128 }; LocationData *users_first, *users_free_cells; LocationData users_cells[users_max]; @@ -898,6 +901,7 @@ public: AdlChannel(): koff_time_until_neglible_us(0) { users_clear(); + std::memset(&recent_ins, 0, sizeof(MIDIchannel::NoteInfo::Phys)); } AdlChannel(const AdlChannel &oth): koff_time_until_neglible_us(oth.koff_time_until_neglible_us) -- cgit v1.2.3 From 98caeed048a59ae639fe02858e98f35984585aca Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 26 Sep 2018 03:15:28 +0300 Subject: Add the competition between channels with releasing notes #181 --- src/adlmidi_midiplay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 105d54a..276a33d 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1343,10 +1343,10 @@ int64_t MIDIplay::calculateChipChannelGoodness(size_t c, const MIDIchannel::Note // Rate channel with a releasing note if(s < 0 && chan.users_empty()) { - s = -10000; + s -= 40000; // If it's same instrument, better chance to get it when no free channels if(chan.recent_ins == ins) - s = (m_synth.m_musicMode == OPL3::MODE_CMF) ? 0 : -5000; + s = (m_synth.m_musicMode == OPL3::MODE_CMF) ? 0 : -koff_ms; return s; } -- cgit v1.2.3 From 6bffa4ccd1c0d65b78e3f1ce59bf97fd30a9c40d Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Fri, 28 Sep 2018 02:00:39 +0300 Subject: Fixed wrong position report on hot file re-load When opening another file with using of same instance, the position is getting be incorrect. --- src/midi_sequencer_impl.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index 6d6b2d8..defd5c7 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -414,6 +414,9 @@ void BW_MidiSequencer::buildSmfSetupReset(size_t trackCount) m_loop.reset(); m_loop.invalidLoop = false; + m_currentPosition.began = false; + m_currentPosition.absTimePosition = 0.0; + m_currentPosition.wait = 0.0; m_currentPosition.track.clear(); m_currentPosition.track.resize(trackCount); } -- cgit v1.2.3 From 4cf3a53ed36e56985753a9d0ec5ba564d6043460 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 29 Sep 2018 00:28:14 +0300 Subject: CMake: Add a proper install of VLC plugin --- CMakeLists.txt | 17 ++++++++++------- cmake/FindLIBVLC.cmake | 27 ++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aeec85e..ce6d8c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -507,27 +507,30 @@ if(WITH_VLC_PLUGIN) list(APPEND adlmidi_vlc_src ${libADLMIDI_SOURCE_DIR}/utils/vlc_codec/libadlmidi.c) - add_library(adlmidi_plugin MODULE ${adlmidi_vlc_src}) - target_compile_options(adlmidi_plugin PUBLIC + add_library(adlmidi_vlc_plugin MODULE ${adlmidi_vlc_src}) + set_target_properties(adlmidi_vlc_plugin PROPERTIES OUTPUT_NAME adlmidi_plugin) + target_compile_options(adlmidi_vlc_plugin PUBLIC "-DVLC_MODULE_COPYRIGHT=\"Copyright \(c\) Vitaly Novichkov\"" "-DVLC_MODULE_LICENSE=\"GPLv3\"" "-DMODULE_STRING=\"adlmidi\"" ${VLCPLUGIN_DEFINITIONS}) - target_include_directories(adlmidi_plugin PRIVATE + target_include_directories(adlmidi_vlc_plugin PRIVATE ${LIBVLC_INCLUDE_DIR}/vlc/plugins ${LIBVLC_INCLUDE_DIR}/vlc) - target_link_libraries(adlmidi_plugin ADLMIDI_IF vlccore m stdc++) - # target_link_libraries(adlmidi_plugin INTERFACE "-export-symbol-regex ^vlc_entry") + target_link_libraries(adlmidi_vlc_plugin ADLMIDI_IF vlccore m stdc++) + # target_link_libraries(adlmidi_vlc_plugin INTERFACE "-export-symbol-regex ^vlc_entry") + + install(TARGETS adlmidi_vlc_plugin DESTINATION "${VLCPLUGIN_CODEC_INSTALL_PATH}") if(libADLMIDI_SHARED) - add_dependencies(adlmidi_plugin ADLMIDI_shared) + add_dependencies(adlmidi_vlc_plugin ADLMIDI_shared) # ========= WIP ========= # set_target_properties(adlmidiplay PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'") else() if(NOT libADLMIDI_STATIC) message(FATAL_ERROR "libADLMIDI is required to be built!") endif() - add_dependencies(adlmidi_plugin ADLMIDI_static) + add_dependencies(adlmidi_vlc_plugin ADLMIDI_static) endif() endif() diff --git a/cmake/FindLIBVLC.cmake b/cmake/FindLIBVLC.cmake index 93b3e35..ea26329 100644 --- a/cmake/FindLIBVLC.cmake +++ b/cmake/FindLIBVLC.cmake @@ -20,13 +20,34 @@ endif(NOT LIBVLC_MIN_VERSION) # locations. When an earlier FIND_* succeeds, subsequent FIND_*s # searching for the same item do nothing. -if (NOT WIN32) +if(NOT WIN32) find_package(PkgConfig) pkg_check_modules(PC_LIBVLC libvlc) set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) + set(LIBVLC_INCLUDE_DIRS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) + pkg_check_modules(PC_VLCPLUGIN vlc-plugin) set(VLCPLUGIN_DEFINITIONS ${PC_VLCPLUGIN_CFLAGS_OTHER}) -endif (NOT WIN32) + set(VLCPLUGIN_INCLUDE_DIRS ${PC_VLCPLUGIN_INCLUDEDIR} ${PC_VLCPLUGIN_INCLUDE_DIRS}) + + pkg_get_variable(PC_VLCPLUGIN_PLUGINS_PATH vlc-plugin pluginsdir) + set(VLCPLUGIN_CODEC_INSTALL_PATH ${PC_VLCPLUGIN_PLUGINS_PATH}/codec) + + message("-- VLC Lib include path is \"${LIBVLC_INCLUDE_DIRS}\" ==") + message("-- VLC Plugins include path is \"${VLCPLUGIN_INCLUDE_DIRS}\" ==") + message("-- VLC Plugins path is \"${VLCPLUGIN_CODEC_INSTALL_PATH}\" ==") +else() + set(LIBVLC_DEFINITIONS) + # FIXME: Is "_FILE_OFFSET_BITS=64" correct for Windows? + set(VLCPLUGIN_DEFINITIONS + -D__PLUGIN__ + -D_FILE_OFFSET_BITS=64 + -D_REENTRANT + -D_THREAD_SAFE + ) + # FIXME: Put the proper install path here + set(VLCPLUGIN_CODEC_INSTALL_PATH "C:/Program Files/vlc/plugins/codec") +endif() #Put here path to custom location #example: /home/user/vlc/include etc.. @@ -42,7 +63,7 @@ PATHS #mingw c:/msys/local/include ) -find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h +find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) #Put here path to custom location -- cgit v1.2.3 From c971992278519b29768be349dd3962bbd93dbb22 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 04:57:56 +0300 Subject: Lock settings for CMF and IMF playing to don't destroy them For now, all settings are in safe, except of custom bank that getting be dropped away by CMF file that does passing of own custom instruments. --- include/adlmidi.h | 16 ++++- src/adlmidi.cpp | 131 +++++++++++++++++++++++++++++------------ src/adlmidi_load.cpp | 18 +++++- src/adlmidi_midiplay.cpp | 8 ++- src/adlmidi_opl3.cpp | 8 +++ src/adlmidi_private.cpp | 8 +-- src/adlmidi_private.hpp | 14 ++++- utils/midiplay/adlmidiplay.cpp | 4 +- 8 files changed, 157 insertions(+), 50 deletions(-) diff --git a/include/adlmidi.h b/include/adlmidi.h index eb3edf4..2732959 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -184,6 +184,13 @@ extern ADLMIDI_DECLSPEC int adl_setNumChips(struct ADL_MIDIPlayer *device, int n */ extern ADLMIDI_DECLSPEC int adl_getNumChips(struct ADL_MIDIPlayer *device); +/** + * @brief Get obtained number of emulated chips + * @param device Instance of the library + * @return Count of working chip emulators + */ +extern ADLMIDI_DECLSPEC int adl_getNumChipsObtained(struct ADL_MIDIPlayer *device); + /** * @brief Sets a number of the patches bank from 0 to N banks. * @@ -340,10 +347,17 @@ extern ADLMIDI_DECLSPEC int adl_setNumFourOpsChn(struct ADL_MIDIPlayer *device, /** * @brief Get current total count of 4-operator channels between all chips * @param device Instance of the library - * @return 0 on success, <0 when any error has occurred + * @return 0 on success, <-1 when any error has occurred, but, -1 - "auto" */ extern ADLMIDI_DECLSPEC int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device); +/** + * @brief Get obtained total count of 4-operator channels between all chips + * @param device Instance of the library + * @return 0 on success, <0 when any error has occurred + */ +extern ADLMIDI_DECLSPEC int adl_getNumFourOpsChnObtained(struct ADL_MIDIPlayer *device); + /** * @brief Override Enable(1) or Disable(0) AdLib percussion mode. -1 - use bank default AdLib percussion mode * diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index bde8757..097fce8 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -68,7 +68,7 @@ ADLMIDI_EXPORT struct ADL_MIDIPlayer *adl_init(long sample_rate) return NULL; } midi_device->adl_midiPlayer = player; - adlRefreshNumCards(midi_device); + adlCalculateFourOpChannels(player); return midi_device; } @@ -113,10 +113,25 @@ ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numChips) return -1; } - play->m_synth.m_numChips = play->m_setup.numChips; - play->partialReset(); + int maxFourOps = static_cast(play->m_setup.numChips * 6); + + if(play->m_setup.numFourOps > maxFourOps) + play->m_setup.numFourOps = maxFourOps; + else if(play->m_setup.numFourOps < -1) + play->m_setup.numFourOps = -1; - return adlRefreshNumCards(device); + if(!play->m_synth.setupLocked()) + { + play->m_synth.m_numChips = play->m_setup.numChips; + if(play->m_setup.numFourOps < 0) + adlCalculateFourOpChannels(play, true); + else + play->m_synth.m_numFourOps = static_cast(play->m_setup.numFourOps); + play->partialReset(); + return 0; + } + + return 0; } ADLMIDI_EXPORT int adl_getNumChips(struct ADL_MIDIPlayer *device) @@ -128,6 +143,15 @@ ADLMIDI_EXPORT int adl_getNumChips(struct ADL_MIDIPlayer *device) return (int)play->m_setup.numChips; } +ADLMIDI_EXPORT int adl_getNumChipsObtained(struct ADL_MIDIPlayer *device) +{ + if(device == NULL) + return -2; + MidiPlayer *play = GET_MIDI_PLAYER(device); + assert(play); + return (int)play->m_synth.m_numChips; +} + ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank) { #ifdef DISABLE_EMBEDDED_BANKS @@ -159,7 +183,7 @@ ADLMIDI_EXPORT int adl_setBank(ADL_MIDIPlayer *device, int bank) play->m_synth.setEmbeddedBank(play->m_setup.bankId); play->applySetup(); - return adlRefreshNumCards(device); + return 0; #endif } @@ -357,9 +381,6 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) if(!device) return -1; - if(ops4 == -1) - return adlRefreshNumCards(device); - MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); if((unsigned int)ops4 > 6 * play->m_setup.numChips) @@ -371,8 +392,14 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) } play->m_setup.numFourOps = static_cast(ops4); - play->m_synth.m_numFourOps = play->m_setup.numFourOps; - play->m_synth.updateChannelCategories(); + if(!play->m_synth.setupLocked()) + { + if(play->m_setup.numFourOps >= 0) + play->m_synth.m_numFourOps = play->m_setup.numFourOps; + else + adlCalculateFourOpChannels(play); + play->m_synth.updateChannelCategories(); + } return 0; } @@ -380,22 +407,35 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) ADLMIDI_EXPORT int adl_getNumFourOpsChn(struct ADL_MIDIPlayer *device) { if(!device) - return -1; + return -2; MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); - return (int)play->m_setup.numFourOps; + return play->m_setup.numFourOps; } +ADLMIDI_EXPORT int adl_getNumFourOpsChnObtained(struct ADL_MIDIPlayer *device) +{ + if(!device) + return -2; + MidiPlayer *play = GET_MIDI_PLAYER(device); + assert(play); + return (int)play->m_synth.m_numFourOps; +} + + ADLMIDI_EXPORT void adl_setPercMode(ADL_MIDIPlayer *device, int percmod) { if(!device) return; MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.rhythmMode = percmod; - play->m_synth.m_rhythmMode = play->m_setup.rhythmMode < 0 ? - (play->m_synth.m_insBankSetup.adLibPercussions) : - (play->m_setup.rhythmMode != 0); - play->m_synth.updateChannelCategories(); + if(!play->m_synth.setupLocked()) + { + play->m_synth.m_rhythmMode = play->m_setup.rhythmMode < 0 ? + (play->m_synth.m_insBankSetup.adLibPercussions) : + (play->m_setup.rhythmMode != 0); + play->m_synth.updateChannelCategories(); + } } ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro) @@ -404,10 +444,13 @@ ADLMIDI_EXPORT void adl_setHVibrato(ADL_MIDIPlayer *device, int hvibro) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.deepVibratoMode = hvibro; - play->m_synth.m_deepVibratoMode = play->m_setup.deepVibratoMode < 0 ? - play->m_synth.m_insBankSetup.deepVibrato : - (play->m_setup.deepVibratoMode != 0); - play->m_synth.commitDeepFlags(); + if(!play->m_synth.setupLocked()) + { + play->m_synth.m_deepVibratoMode = play->m_setup.deepVibratoMode < 0 ? + play->m_synth.m_insBankSetup.deepVibrato : + (play->m_setup.deepVibratoMode != 0); + play->m_synth.commitDeepFlags(); + } } ADLMIDI_EXPORT int adl_getHVibrato(struct ADL_MIDIPlayer *device) @@ -424,10 +467,13 @@ ADLMIDI_EXPORT void adl_setHTremolo(ADL_MIDIPlayer *device, int htremo) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.deepTremoloMode = htremo; - play->m_synth.m_deepTremoloMode = play->m_setup.deepTremoloMode < 0 ? - play->m_synth.m_insBankSetup.deepTremolo : - (play->m_setup.deepTremoloMode != 0); - play->m_synth.commitDeepFlags(); + if(!play->m_synth.setupLocked()) + { + play->m_synth.m_deepTremoloMode = play->m_setup.deepTremoloMode < 0 ? + play->m_synth.m_insBankSetup.deepTremolo : + (play->m_setup.deepTremoloMode != 0); + play->m_synth.commitDeepFlags(); + } } ADLMIDI_EXPORT int adl_getHTremolo(struct ADL_MIDIPlayer *device) @@ -445,9 +491,12 @@ ADLMIDI_EXPORT void adl_setScaleModulators(ADL_MIDIPlayer *device, int smod) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.scaleModulators = smod; - play->m_synth.m_scaleModulators = play->m_setup.scaleModulators < 0 ? - play->m_synth.m_insBankSetup.scaleModulators : - (play->m_setup.scaleModulators != 0); + if(!play->m_synth.setupLocked()) + { + play->m_synth.m_scaleModulators = play->m_setup.scaleModulators < 0 ? + play->m_synth.m_insBankSetup.scaleModulators : + (play->m_setup.scaleModulators != 0); + } } ADLMIDI_EXPORT void adl_setFullRangeBrightness(struct ADL_MIDIPlayer *device, int fr_brightness) @@ -489,10 +538,13 @@ ADLMIDI_EXPORT void adl_setLogarithmicVolumes(struct ADL_MIDIPlayer *device, int MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.logarithmicVolumes = (logvol != 0); - if(play->m_setup.logarithmicVolumes) - play->m_synth.setVolumeScaleModel(ADLMIDI_VolumeModel_NativeOPL3); - else - play->m_synth.setVolumeScaleModel(static_cast(play->m_synth.m_volumeScale)); + if(!play->m_synth.setupLocked()) + { + if(play->m_setup.logarithmicVolumes) + play->m_synth.setVolumeScaleModel(ADLMIDI_VolumeModel_NativeOPL3); + else + play->m_synth.setVolumeScaleModel(static_cast(play->m_synth.m_volumeScale)); + } } ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int volumeModel) @@ -502,10 +554,13 @@ ADLMIDI_EXPORT void adl_setVolumeRangeModel(struct ADL_MIDIPlayer *device, int v MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.volumeScaleModel = volumeModel; - if(play->m_setup.volumeScaleModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model - play->m_synth.m_volumeScale = (OPL3::VolumesScale)play->m_synth.m_insBankSetup.volumeModel; - else - play->m_synth.setVolumeScaleModel(static_cast(volumeModel)); + if(!play->m_synth.setupLocked()) + { + if(play->m_setup.volumeScaleModel == ADLMIDI_VolumeModel_AUTO)//Use bank default volume model + play->m_synth.m_volumeScale = (OPL3::VolumesScale)play->m_synth.m_insBankSetup.volumeModel; + else + play->m_synth.setVolumeScaleModel(static_cast(volumeModel)); + } } ADLMIDI_EXPORT int adl_getVolumeRangeModel(struct ADL_MIDIPlayer *device) @@ -531,7 +586,8 @@ ADLMIDI_EXPORT int adl_openBankFile(struct ADL_MIDIPlayer *device, const char *f play->setErrorString("ADL MIDI: Can't load file"); return -1; } - else return adlRefreshNumCards(device); + else + return adlCalculateFourOpChannels(play, true); } ADLMIDI_ErrorString = "Can't load file: ADLMIDI is not initialized"; @@ -552,7 +608,8 @@ ADLMIDI_EXPORT int adl_openBankData(struct ADL_MIDIPlayer *device, const void *m play->setErrorString("ADL MIDI: Can't load data from memory"); return -1; } - else return adlRefreshNumCards(device); + else + return adlCalculateFourOpChannels(play, true); } ADLMIDI_ErrorString = "Can't load file: ADL MIDI is not initialized"; diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp index e86f23e..07ad875 100644 --- a/src/adlmidi_load.cpp +++ b/src/adlmidi_load.cpp @@ -1,4 +1,4 @@ -/* +/* * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation * * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma @@ -214,20 +214,36 @@ bool MIDIplay::LoadMIDI_post() m_synth.m_rhythmMode = true; m_synth.m_musicMode = OPL3::MODE_CMF; m_synth.m_volumeScale = OPL3::VOLUME_NATIVE; + + m_synth.m_numChips = 1; + m_synth.m_numFourOps = 0; } else if(format == MidiSequencer::Format_RSXX) { //opl.CartoonersVolumes = true; m_synth.m_musicMode = OPL3::MODE_RSXX; m_synth.m_volumeScale = OPL3::VOLUME_NATIVE; + + m_synth.m_numChips = 1; + m_synth.m_numFourOps = 0; } else if(format == MidiSequencer::Format_IMF) { //std::fprintf(stderr, "Done reading IMF file\n"); m_synth.m_numFourOps = 0; //Don't use 4-operator channels for IMF playing! m_synth.m_musicMode = OPL3::MODE_IMF; + + m_synth.m_numChips = 1; + m_synth.m_numFourOps = 0; + } + else + { + m_synth.m_numChips = m_setup.numChips; + if(m_setup.numFourOps < 0) + adlCalculateFourOpChannels(this, true); } + m_setup.tick_skip_samples_delay = 0; m_synth.reset(m_setup.emulator, m_setup.PCM_RATE, this); // Reset OPL3 chip //opl.Reset(); // ...twice (just in case someone misprogrammed OPL3 previously) m_chipChannels.clear(); diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 276a33d..585e855 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -141,7 +141,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate): m_setup.maxdelay = 512.0 / (double)m_setup.PCM_RATE; m_setup.bankId = 0; - m_setup.numFourOps = 7; + m_setup.numFourOps = -1; m_setup.numChips = 2; m_setup.deepTremoloMode = -1; m_setup.deepVibratoMode = -1; @@ -198,9 +198,13 @@ void MIDIplay::applySetup() m_synth.m_volumeScale = (OPL3::VolumesScale)m_synth.m_insBankSetup.volumeModel; m_synth.m_numChips = m_setup.numChips; - m_synth.m_numFourOps = m_setup.numFourOps; m_cmfPercussionMode = false; + if(m_setup.numFourOps >= 0) + m_synth.m_numFourOps = m_setup.numFourOps; + else + adlCalculateFourOpChannels(this, true); + m_synth.reset(m_setup.emulator, m_setup.PCM_RATE, this); m_chipChannels.clear(); m_chipChannels.resize(m_synth.m_numChannels); diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp index e486dd6..f3672d3 100644 --- a/src/adlmidi_opl3.cpp +++ b/src/adlmidi_opl3.cpp @@ -181,6 +181,13 @@ OPL3::OPL3() : #endif } +bool OPL3::setupLocked() +{ + return (m_musicMode == MODE_CMF || + m_musicMode == MODE_IMF || + m_musicMode == MODE_RSXX); +} + void OPL3::setEmbeddedBank(uint32_t bank) { #ifndef DISABLE_EMBEDDED_BANKS @@ -487,6 +494,7 @@ void OPL3::setPan(size_t c, uint8_t value) int panning = 0; if(value < 64 + 32) panning |= OPL_PANNING_LEFT; if(value >= 64 - 32) panning |= OPL_PANNING_RIGHT; + writePan(chip, g_channelsMap[cc], 64); writeRegI(chip, 0xC0 + g_channelsMap[cc], m_insCache[c].feedconn | panning); #ifndef ADLMIDI_HW_OPL } diff --git a/src/adlmidi_private.cpp b/src/adlmidi_private.cpp index 43fe8de..4e8e488 100644 --- a/src/adlmidi_private.cpp +++ b/src/adlmidi_private.cpp @@ -34,10 +34,9 @@ void adl_audioTickHandler(void *instance, uint32_t chipId, uint32_t rate) } #endif -int adlRefreshNumCards(ADL_MIDIPlayer *device) +int adlCalculateFourOpChannels(MIDIplay *play, bool silent) { size_t n_fourop[2] = {0, 0}, n_total[2] = {0, 0}; - MIDIplay *play = reinterpret_cast(device->adl_midiPlayer); //Automatically calculate how much 4-operator channels is necessary #ifndef DISABLE_EMBEDDED_BANKS @@ -100,9 +99,10 @@ int adlRefreshNumCards(ADL_MIDIPlayer *device) : (play->m_setup.NumCards == 1 ? 1 : play->m_setup.NumCards * 4); */ - play->m_synth.m_numFourOps = play->m_setup.numFourOps = static_cast(numFourOps * play->m_setup.numChips); + play->m_synth.m_numFourOps = static_cast(numFourOps * play->m_synth.m_numChips); // Update channel categories and set up four-operator channels - play->m_synth.updateChannelCategories(); + if(!silent) + play->m_synth.updateChannelCategories(); return 0; } diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 43986c5..c3d65c0 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -211,6 +211,7 @@ inline int32_t adl_cvtU32(int32_t x) } struct ADL_MIDIPlayer; +class MIDIplay; /** * @brief OPL3 Chip management class */ @@ -218,7 +219,7 @@ class OPL3 { friend class MIDIplay; friend class AdlInstrumentTester; - friend int adlRefreshNumCards(ADL_MIDIPlayer *device); + friend int adlCalculateFourOpChannels(MIDIplay *play, bool silent); public: enum { @@ -362,6 +363,12 @@ public: */ OPL3(); + /** + * @brief Checks are setup locked to be changed on the fly or not + * @return true when setup on the fly is locked + */ + bool setupLocked(); + /** * @brief Choose one of embedded banks * @param bank ID of the bank @@ -951,7 +958,7 @@ public: int emulator; bool runAtPcmRate; unsigned int bankId; - unsigned int numFourOps; + int numFourOps; unsigned int numChips; int deepTremoloMode; int deepVibratoMode; @@ -1485,9 +1492,10 @@ extern void adl_audioTickHandler(void *instance, uint32_t chipId, uint32_t rate) /** * @brief Automatically calculate and enable necessary count of 4-op channels on emulated chips * @param device Library context + * @param silent Don't re-count channel categories * @return Always 0 */ -extern int adlRefreshNumCards(ADL_MIDIPlayer *device); +extern int adlCalculateFourOpChannels(MIDIplay *play, bool silent = false); /** * @brief Check emulator availability diff --git a/utils/midiplay/adlmidiplay.cpp b/utils/midiplay/adlmidiplay.cpp index 5880243..39d80ff 100644 --- a/utils/midiplay/adlmidiplay.cpp +++ b/utils/midiplay/adlmidiplay.cpp @@ -606,7 +606,6 @@ int main(int argc, char **argv) printError(adl_errorInfo(myDevice)); return 1; } - std::fprintf(stdout, " - Number of chips %d\n", adl_getNumChips(myDevice)); #else int numOfChips = 1; adl_setNumChips(myDevice, numOfChips); @@ -621,7 +620,6 @@ int main(int argc, char **argv) return 1; } } - std::fprintf(stdout, " - Number of four-ops %d\n", adl_getNumFourOpsChn(myDevice)); std::string musPath = argv[1]; //Open MIDI file to play @@ -631,6 +629,8 @@ int main(int argc, char **argv) return 2; } + std::fprintf(stdout, " - Number of chips %d\n", adl_getNumChipsObtained(myDevice)); + std::fprintf(stdout, " - Number of four-ops %d\n", adl_getNumFourOpsChnObtained(myDevice)); std::fprintf(stdout, " - Track count: %lu\n", (unsigned long)adl_trackCount(myDevice)); if(soloTrack != ~(size_t)0) -- cgit v1.2.3 From fdaab26f0d0a9c188c0bb9f27220b21c4e26d745 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 05:14:41 +0300 Subject: Sequencer: fix attempt to load CMF again in same instance --- src/midi_sequencer_impl.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index defd5c7..c2654b2 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -1999,6 +1999,8 @@ bool BW_MidiSequencer::loadMIDI(FileAndMemReader &fr) m_format = Format_MIDI; m_smfFormat = 0; + m_cmfInstruments.clear(); + const size_t headerSize = 4 + 4 + 2 + 2 + 2; // 14 char headerBuf[headerSize] = ""; -- cgit v1.2.3 From 6a3ae79625abdf8d85335b44fc6a3d37c2ae840e Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 05:26:14 +0300 Subject: Another CMF/IMF/RSXX playback fix --- src/adlmidi.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 097fce8..d76ed8c 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -717,7 +717,8 @@ ADLMIDI_EXPORT int adl_setRunAtPcmRate(ADL_MIDIPlayer *device, int enabled) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); play->m_setup.runAtPcmRate = (enabled != 0); - play->partialReset(); + if(!play->m_synth.setupLocked()) + play->partialReset(); return 0; } return -1; -- cgit v1.2.3 From fb0304b01968fd2a3279a87a5825bdedfa2d5289 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 05:49:18 +0300 Subject: Fix the 4-op channels count setup --- src/adlmidi.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index d76ed8c..e104465 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -383,7 +383,7 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); - if((unsigned int)ops4 > 6 * play->m_setup.numChips) + if((ops4 >= 0) && (unsigned int)ops4 > 6 * play->m_setup.numChips) { char errBuff[250]; snprintf(errBuff, 250, "number of four-op channels may only be 0..%u when %u OPL3 cards are used.\n", (6 * (play->m_setup.numChips)), play->m_setup.numChips); @@ -391,13 +391,13 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) return -1; } - play->m_setup.numFourOps = static_cast(ops4); + play->m_setup.numFourOps = ops4; if(!play->m_synth.setupLocked()) { - if(play->m_setup.numFourOps >= 0) - play->m_synth.m_numFourOps = play->m_setup.numFourOps; + if(play->m_setup.numFourOps < 0) + adlCalculateFourOpChannels(play, true); else - adlCalculateFourOpChannels(play); + play->m_synth.m_numFourOps = static_cast(play->m_setup.numFourOps); play->m_synth.updateChannelCategories(); } -- cgit v1.2.3 From 64892d58b91e6abd9acc5204760811cbe06abc21 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 06:02:51 +0300 Subject: TRUE Fix the 4-op channels count setup --- src/adlmidi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index e104465..d0aa85f 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -383,7 +383,7 @@ ADLMIDI_EXPORT int adl_setNumFourOpsChn(ADL_MIDIPlayer *device, int ops4) MidiPlayer *play = GET_MIDI_PLAYER(device); assert(play); - if((ops4 >= 0) && (unsigned int)ops4 > 6 * play->m_setup.numChips) + if(ops4 > 6 * static_cast(play->m_setup.numChips)) { char errBuff[250]; snprintf(errBuff, 250, "number of four-op channels may only be 0..%u when %u OPL3 cards are used.\n", (6 * (play->m_setup.numChips)), play->m_setup.numChips); -- cgit v1.2.3 From 10c6c335697cd7e570d06089c61c1fae8acb29e1 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 18:53:32 +0300 Subject: Remove useless condition --- src/adlmidi_midiplay.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 585e855..673ec30 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1474,8 +1474,6 @@ void MIDIplay::killOrEvacuate(size_t from_channel, { uint16_t cs = static_cast(c); - if(c > std::numeric_limits::max()) - break; if(c == from_channel) continue; if(m_synth.m_channelCategory[c] != m_synth.m_channelCategory[from_channel]) -- cgit v1.2.3 From 77e8b86be524edf42a7070e2b7a1f6f67d7cfaa8 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 18:58:13 +0300 Subject: Move "MaxChips" constant macro into adlmidi_private.hpp --- src/adlmidi.cpp | 12 ++---------- src/adlmidi_midiplay.cpp | 4 ++++ src/adlmidi_private.hpp | 8 ++++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index d0aa85f..12d0e68 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -23,14 +23,6 @@ #include "adlmidi_private.hpp" -#ifdef ADLMIDI_HW_OPL -#define MaxChips 1 -#define MaxChips_STR "1" //Why not just "#MaxCards" ? Watcom fails to pass this with "syntax error" :-P -#else -#define MaxChips 100 -#define MaxChips_STR "100" -#endif - /* Unify MIDI player casting and interface between ADLMIDI and OPNMIDI */ #define GET_MIDI_PLAYER(device) reinterpret_cast((device)->adl_midiPlayer) typedef MIDIplay MidiPlayer; @@ -107,9 +99,9 @@ ADLMIDI_EXPORT int adl_setNumChips(ADL_MIDIPlayer *device, int numChips) #else play->m_setup.numChips = static_cast(numChips); #endif - if(play->m_setup.numChips < 1 || play->m_setup.numChips > MaxChips) + if(play->m_setup.numChips < 1 || play->m_setup.numChips > ADL_MAX_CHIPS) { - play->setErrorString("number of chips may only be 1.." MaxChips_STR ".\n"); + play->setErrorString("number of chips may only be 1.." ADL_MAX_CHIPS_STR ".\n"); return -1; } diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 673ec30..1e1da07 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1465,6 +1465,8 @@ void MIDIplay::killOrEvacuate(size_t from_channel, AdlChannel::LocationData *j, MIDIplay::MIDIchannel::activenoteiterator i) { + uint32_t maxChannels = ADL_MAX_CHIPS * 18; + // Before killing the note, check if it can be // evacuated to another channel as an arpeggio // instrument. This helps if e.g. all channels @@ -1474,6 +1476,8 @@ void MIDIplay::killOrEvacuate(size_t from_channel, { uint16_t cs = static_cast(c); + if(c >= maxChannels) + break; if(c == from_channel) continue; if(m_synth.m_channelCategory[c] != m_synth.m_channelCategory[from_channel]) diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index c3d65c0..59ba555 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -161,6 +161,14 @@ typedef BW_MidiSequencer MidiSequencer; #define OPL_PANNING_RIGHT 0x20 #define OPL_PANNING_BOTH 0x30 +#ifdef ADLMIDI_HW_OPL +#define ADL_MAX_CHIPS 1 +#define ADL_MAX_CHIPS_STR "1" //Why not just "#MaxCards" ? Watcom fails to pass this with "syntax error" :-P +#else +#define ADL_MAX_CHIPS 100 +#define ADL_MAX_CHIPS_STR "100" +#endif + extern std::string ADLMIDI_ErrorString; /* -- cgit v1.2.3 From eefbc9eb33324e0d0a9f371f0b88ffcce85adb23 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sun, 30 Sep 2018 21:54:41 +0300 Subject: Minor fix of the public header --- include/adlmidi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/adlmidi.h b/include/adlmidi.h index 2732959..4b21e25 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -66,7 +66,7 @@ typedef short ADL_SInt16; #ifdef __clang__ # if __has_extension(attribute_deprecated_with_message) -# define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +# define ADLMIDI_DEPRECATED(message) __attribute__((deprecated(message))) # endif #elif defined __GNUC__ /* not clang (gcc comes later since clang emulates gcc) */ # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -- cgit v1.2.3 From f78312bef17d096636f7888d44c103b777ce443e Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 1 Oct 2018 03:53:02 +0300 Subject: Remove useless dllexport from the typedef --- include/adlmidi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/adlmidi.h b/include/adlmidi.h index 4b21e25..3524587 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -743,7 +743,7 @@ extern ADLMIDI_DECLSPEC int adl_setTrackOptions(struct ADL_MIDIPlayer *device, s * @param trigger Value of the event which triggered this callback. * @param track Identifier of the track which triggered this callback. */ -typedef ADLMIDI_DECLSPEC void (*ADL_TriggerHandler)(void *userData, unsigned trigger, size_t track); +typedef void (*ADL_TriggerHandler)(void *userData, unsigned trigger, size_t track); /** * @brief Defines a handler for callback trigger events -- cgit v1.2.3 From 314cde9fccb603bbd2b36b58dc9b3020c160ac4b Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 1 Oct 2018 04:02:42 +0300 Subject: Readme update --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37773aa..e4a694c 100644 --- a/README.md +++ b/README.md @@ -119,8 +119,14 @@ You need to make in the any IDE a library project and put into it next files ### Internal code (src) * chips/* - Various OPL3 chip emulators and commonized interface over them +* wopl/* - WOPL bank format library * adldata.hh - bank structures definition * adlmidi_private.hpp - header of internal private APIs +* adlmidi_bankmap.h - MIDI bank hash table +* adlmidi_bankmap.tcc - MIDI bank hash table (Implementation) +* adlmidi_cvt.hpp - Instrument conversion template +* adlmidi_ptr.hpp - Custom implementations of smart pointers for C++98 +* file_reader.hpp - Generic file and memory reader * adldata.cpp - Automatically generated database of FM banks from "fm_banks" directory via "gen_adldata" tool. **Don't build it if you have defined `DISABLE_EMBEDDED_BANKS` macro!** * adlmidi.cpp - code of library @@ -160,10 +166,10 @@ To build that example you will need to have installed SDL2 library. # Todo * Check out for XG/GS standards to provide a support to use any channels as percussion and also check some of SysEx commands. -* Add support of MIDI Format 2 files (FL Studio made MIDI-files are wired and opening of those files making lossy of tempo and some meta-information events) +* Add support of MIDI Format 2 files # Changelog -## 1.4.0 +## 1.4.0 2018-10-01 * Implemented a full support for Portamento! (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added support for SysEx event handling! (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added support for GS way of custom drum channels (through SysEx events) -- cgit v1.2.3