diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/adlmidi.cpp | 57 | ||||
| -rw-r--r-- | src/midi_sequencer.hpp | 25 | ||||
| -rw-r--r-- | src/midi_sequencer_impl.hpp | 30 | 
3 files changed, 111 insertions, 1 deletions
| 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, |