use rational number for step durations

This commit is contained in:
Paul Davis 2018-11-07 16:25:25 -05:00
parent c37d81e0c1
commit 25f67e3f16
2 changed files with 28 additions and 15 deletions

View file

@ -22,6 +22,8 @@
#include <vector>
#include <unistd.h>
#include <boost/rational.hpp>
#include <glibmm/threads.h>
#include "pbd/stateful.h"
@ -50,6 +52,8 @@ class Step : public PBD::Stateful {
RelativePitch
};
typedef boost::rational<int> DurationRatio;
Step (StepSequence&, Temporal::Beats const & beat);
~Step ();
@ -59,7 +63,7 @@ class Step : public PBD::Stateful {
void adjust_velocity (int amt);
void adjust_pitch (int amt);
void adjust_duration (double amt);
void adjust_duration (DurationRatio const & amt);
void adjust_octave (int amt);
Mode mode() const { return _mode; }
@ -68,8 +72,8 @@ class Step : public PBD::Stateful {
double note (size_t n = 0) const { return _notes[n].number; }
double velocity (size_t n = 0) const { return _notes[n].velocity; }
double duration () const { return _duration; }
void set_duration (double duration);
DurationRatio duration () const { return _duration; }
void set_duration (DurationRatio const &);
void set_offset (Temporal::Beats const &, size_t n = 0);
Temporal::Beats offset (size_t n = 0) const { return _notes[n].offset; }
@ -109,8 +113,8 @@ class Step : public PBD::Stateful {
bool _skipped;
Mode _mode;
int _octave_shift;
double _duration;
DurationRatio _duration;
struct ParameterValue {
int parameter;
double value;

View file

@ -39,7 +39,7 @@ Step::Step (StepSequence &s, Temporal::Beats const & b)
, _skipped (false)
, _mode (AbsolutePitch)
, _octave_shift (0)
, _duration (1.0)
, _duration (1)
{
std::cerr << "step @ " << b << std::endl;
@ -105,16 +105,20 @@ Step::set_enabled (bool yn)
}
void
Step::adjust_duration (double amt)
Step::adjust_duration (DurationRatio const & amt)
{
const double new_dur = _duration + amt;
set_duration (_duration + amt);
}
if (new_dur > 1.0) {
_duration = 1.0;
} else if (new_dur < 1.0/64.0) {
_duration = 0.0;
void
Step::set_duration (DurationRatio const & dur)
{
if (dur > 1.0) {
_duration = DurationRatio (1);
} else if (dur < DurationRatio()) {
_duration = DurationRatio ();
} else {
_duration = new_dur;
_duration = dur;
}
PropertyChange pc;
@ -236,6 +240,11 @@ Step::check_note (size_t n, MidiBuffer& buf, bool running, samplepos_t start_sam
}
if (_duration == DurationRatio ()) {
/* no duration, so no new notes on */
return;
}
if (note.number < 0) {
/* note not set .. ignore */
return;
@ -304,10 +313,10 @@ Step::check_note (size_t n, MidiBuffer& buf, bool running, samplepos_t start_sam
note.off_at = note_on_time;
if (_duration == 1.0) {
if (_duration == DurationRatio (1)) {
note.off_at += Temporal::Beats (0, _sequence.step_size().to_ticks() - 1);
} else {
note.off_at += Temporal::Beats (0, _sequence.step_size().to_ticks() * _duration);
note.off_at += Temporal::Beats (0, (_sequence.step_size().to_ticks() * _duration.numerator()) / _duration.denominator());
}
}
}