diff --git a/include/MidiTime.h b/include/MidiTime.h index fe44ab4da..0204075ee 100644 --- a/include/MidiTime.h +++ b/include/MidiTime.h @@ -27,8 +27,10 @@ #ifndef MIDI_TIME_H #define MIDI_TIME_H -#include "lmms_basics.h" +#include + #include "export.h" +#include "lmms_basics.h" // note: 1 "Tact" = 1 Measure const int DefaultTicksPerTact = 192; @@ -36,6 +38,25 @@ const int DefaultStepsPerTact = 16; const int DefaultBeatsPerTact = DefaultTicksPerTact / DefaultStepsPerTact; +class MeterModel; + +class EXPORT TimeSig +{ +public: + // in a time signature, + // the numerator represents the number of beats in a measure. + // the denominator indicates which type of note represents a beat. + // example: 6/8 means 6 beats in a measure, where each beat has duration equal to one 8th-note. + TimeSig( int num, int denom ); + TimeSig( const MeterModel &model ); + int numerator() const; + int denominator() const; +private: + int m_num; + int m_denom; +}; + + class EXPORT MidiTime { public: @@ -112,6 +133,26 @@ public: return m_ticks; } + tick_t ticksPerBeat( const TimeSig &sig ) const + { + return ticksPerTact(sig) / sig.numerator(); + } + // Remainder ticks after bar is removed + tick_t getTickWithinBar( const TimeSig &sig ) const + { + return m_ticks % ticksPerTact(sig); + } + // Returns the beat position inside the bar, 0-based + tick_t getBeatWithinBar( const TimeSig &sig ) const + { + return getTickWithinBar(sig) / ticksPerBeat(sig); + } + // Remainder ticks after bar and beat are removed + tick_t getTickWithinBeat( const TimeSig &sig ) const + { + return getTickWithinBar(sig) % ticksPerBeat(sig); + } + // calculate number of frame that are needed this time f_cnt_t frames( const float framesPerTick ) const { @@ -132,6 +173,10 @@ public: { return s_ticksPerTact; } + static tick_t ticksPerTact( const TimeSig &sig ) const + { + return DefaultTicksPerTact * sig.numerator() / sig.denominator(); + } static int stepsPerTact() { diff --git a/include/Song.h b/include/Song.h index 5280cea30..7c65641ec 100644 --- a/include/Song.h +++ b/include/Song.h @@ -111,22 +111,18 @@ public: inline int ticksPerTact() const { - return DefaultTicksPerTact * - m_timeSigModel.getNumerator() / - m_timeSigModel.getDenominator(); + return MidiTime::ticksPerTact(m_timeSigModel); } // Returns the beat position inside the bar, 0-based inline int getBeat() const { - return ( currentTick() - currentTact() * ticksPerTact() ) / - ( ticksPerTact() / m_timeSigModel.getNumerator() ); + return getPlayPos().getBeatWithinBar(m_timeSigModel); } // the remainder after bar and beat are removed inline int getBeatTicks() const { - return ( currentTick() - currentTact() * ticksPerTact() ) % - ( ticksPerTact() / m_timeSigModel.getNumerator() ); + return getPlayPos().getTickWithinBeat(m_timeSigModel); } inline int getTicks() const { @@ -186,6 +182,10 @@ public: { return m_playPos[pm]; } + inline const PlayPos & getPlayPos() const + { + return getPlayPos(m_playMode); + } void updateLength(); tact_t length() const diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e974d151f..6d6ae4d98 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -82,6 +82,7 @@ set(LMMS_SRCS core/midi/MidiController.cpp core/midi/MidiOss.cpp core/midi/MidiPort.cpp + core/midi/MidiTime.cpp core/midi/MidiWinMM.cpp PARENT_SCOPE diff --git a/src/core/midi/MidiTime.cpp b/src/core/midi/MidiTime.cpp new file mode 100644 index 000000000..f93136144 --- /dev/null +++ b/src/core/midi/MidiTime.cpp @@ -0,0 +1,49 @@ +/* + * MidiTime.cpp - Class that encapsulates the position of a note/event in terms of + * its bar, beat and tick. + * + * Copyright (c) 2004-2014 Tobias Doerffel