diff options
author | JP Cimalando <jpcima@users.noreply.github.com> | 2018-07-07 02:03:01 +0200 |
---|---|---|
committer | JP Cimalando <jpcima@users.noreply.github.com> | 2018-07-07 02:40:02 +0200 |
commit | 7cb0fe9dad9f7ef24d1142d866450305102bf3a9 (patch) | |
tree | 392c55537731346ec8dc65a9f93afb35fbe4f73d | |
parent | 63f0c95a978902e0896513ca4c7e7e3907da7b9d (diff) | |
download | libADLMIDI-7cb0fe9dad9f7ef24d1142d866450305102bf3a9.tar.gz libADLMIDI-7cb0fe9dad9f7ef24d1142d866450305102bf3a9.tar.bz2 libADLMIDI-7cb0fe9dad9f7ef24d1142d866450305102bf3a9.zip |
sequencer API to turn tracks on/off/solo
-rw-r--r-- | include/adlmidi.h | 27 | ||||
-rw-r--r-- | src/adlmidi.cpp | 57 | ||||
-rw-r--r-- | src/midi_sequencer.hpp | 25 | ||||
-rw-r--r-- | src/midi_sequencer_impl.hpp | 30 |
4 files changed, 138 insertions, 1 deletions
diff --git a/include/adlmidi.h b/include/adlmidi.h index 387a30a..dc6fd8c 100644 --- a/include/adlmidi.h +++ b/include/adlmidi.h @@ -636,6 +636,33 @@ extern void adl_setTempo(struct ADL_MIDIPlayer *device, double tempo); */ extern int adl_atEnd(struct ADL_MIDIPlayer *device); +/** + * @brief Returns the number of tracks of the current sequence + * @param device Instance of the library + * @return Count of tracks in the current sequence + */ +extern size_t adl_trackCount(struct ADL_MIDIPlayer *device); + +/** + * @brief Track options + */ +enum ADLMIDI_TrackOptions +{ + /*! Enabled track */ + ADL_TrackOption_On = 1, + /*! Disabled track */ + ADL_TrackOption_Off = 2, + /*! Solo track */ + ADL_TrackOption_Solo = 3, +}; + +/** + * @brief Sets options on a track of the current sequence + * @param device Instance of the library + * @param trackNumber Identifier of the designated track. + * @return 0 on success, <0 when any error has occurred + */ +extern int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions); diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp index 4fed13b..93d1bf1 100644 --- a/src/adlmidi.cpp +++ b/src/adlmidi.cpp @@ -1356,6 +1356,63 @@ ADLMIDI_EXPORT int adl_atEnd(struct ADL_MIDIPlayer *device) #endif } +ADLMIDI_EXPORT size_t adl_trackCount(struct ADL_MIDIPlayer *device) +{ +#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER + if(!device) + return 0; + MidiPlayer *play = GET_MIDI_PLAYER(device); + if(!play) + return 0; + return play->m_sequencer.getTrackCount(); +#else + ADL_UNUSED(device); + return 0; +#endif +} + +ADLMIDI_EXPORT int adl_setTrackOptions(struct ADL_MIDIPlayer *device, size_t trackNumber, unsigned trackOptions) +{ +#ifndef ADLMIDI_DISABLE_MIDI_SEQUENCER + if(!device) + return -1; + MidiPlayer *play = GET_MIDI_PLAYER(device); + if(!play) + return -1; + MidiSequencer &seq = play->m_sequencer; + + unsigned enableFlag = trackOptions & 3; + trackOptions &= ~3u; + + // handle on/off/solo + switch(enableFlag) + { + default: + break; + case ADL_TrackOption_On: + case ADL_TrackOption_Off: + if(!seq.setTrackEnabled(trackNumber, enableFlag == ADL_TrackOption_On)) + return -1; + break; + case ADL_TrackOption_Solo: + seq.setSoloTrack(trackNumber); + break; + } + + // handle others... + if(trackOptions != 0) + return -1; + + return 0; + +#else + ADL_UNUSED(device); + ADL_UNUSED(trackNumber); + ADL_UNUSED(trackOptions); + return -1; +#endif +} + ADLMIDI_EXPORT void adl_panic(struct ADL_MIDIPlayer *device) { if(!device) diff --git a/src/midi_sequencer.hpp b/src/midi_sequencer.hpp index 6eeefa9..71e06b5 100644 --- a/src/midi_sequencer.hpp +++ b/src/midi_sequencer.hpp @@ -343,6 +343,11 @@ private: //! Are loop points invalid? bool m_invalidLoop; /*Loop points are invalid (loopStart after loopEnd or loopStart and loopEnd are on same place)*/ + //! Whether the nth track has playback disabled + std::vector<bool> m_trackDisable; + //! Index of solo track, or max for disabled + size_t m_trackSolo; + //! File parsing errors string (adding into m_errorString on aborting of the process) std::string m_parsingErrorsString; //! Common error string @@ -365,6 +370,26 @@ public: FileFormat getFormat(); /** + * @brief Returns the number of tracks + * @return Track count + */ + size_t getTrackCount() const; + + /** + * @brief Sets whether a track is playing + * @param track Track identifier + * @param enable Whether to enable track playback + * @return true on success, false if there was no such track + */ + bool setTrackEnabled(size_t track, bool enable); + + /** + * @brief Enables or disables solo on a track + * @param track Identifier of solo track, or max to disable + */ + void setSoloTrack(size_t track); + + /** * @brief Get the list of CMF instruments (CMF only) * @return Array of raw CMF instruments entries */ diff --git a/src/midi_sequencer_impl.hpp b/src/midi_sequencer_impl.hpp index ce70c3e..d8edbfb 100644 --- a/src/midi_sequencer_impl.hpp +++ b/src/midi_sequencer_impl.hpp @@ -271,7 +271,8 @@ BW_MidiSequencer::BW_MidiSequencer() : m_atEnd(false), m_loopStart(false), m_loopEnd(false), - m_invalidLoop(false) + m_invalidLoop(false), + m_trackSolo(~(size_t)0) {} BW_MidiSequencer::~BW_MidiSequencer() @@ -307,6 +308,25 @@ BW_MidiSequencer::FileFormat BW_MidiSequencer::getFormat() return m_format; } +size_t BW_MidiSequencer::getTrackCount() const +{ + return m_trackData.size(); +} + +bool BW_MidiSequencer::setTrackEnabled(size_t track, bool enable) +{ + size_t trackCount = m_trackData.size(); + if(track >= trackCount) + return false; + m_trackDisable[track] = !enable; + return true; +} + +void BW_MidiSequencer::setSoloTrack(size_t track) +{ + m_trackSolo = track; +} + const std::vector<BW_MidiSequencer::CmfInstrument> BW_MidiSequencer::getRawCmfInstruments() { return m_cmfInstruments; @@ -362,6 +382,8 @@ bool BW_MidiSequencer::buildTrackData(const std::vector<std::vector<uint8_t> > & m_fullSongTimeLength = 0.0; m_loopStartTime = -1.0; m_loopEndTime = -1.0; + m_trackDisable.clear(); + m_trackSolo = ~(size_t)0; m_musTitle.clear(); m_musCopyright.clear(); m_musTrackTitles.clear(); @@ -369,6 +391,7 @@ bool BW_MidiSequencer::buildTrackData(const std::vector<std::vector<uint8_t> > & m_trackData.clear(); const size_t trackCount = trackData.size(); m_trackData.resize(trackCount, MidiTrackQueue()); + m_trackDisable.resize(trackCount); m_invalidLoop = false; bool gotLoopStart = false, gotLoopEnd = false, gotLoopEventInThisRow = false; @@ -1122,6 +1145,11 @@ BW_MidiSequencer::MidiEvent BW_MidiSequencer::parseEvent(const uint8_t **pptr, c void BW_MidiSequencer::handleEvent(size_t track, const BW_MidiSequencer::MidiEvent &evt, int32_t &status) { + if(m_trackSolo != ~(size_t)0 && track != m_trackSolo) + return; + if(m_trackDisable[track]) + return; + if(m_interface->onEvent) { m_interface->onEvent(m_interface->onEvent_userData, |