mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
superclock_ticks_per_second: use an (inline) accessor, change value
We do not want a value as large as the previous one, which limits the time range that can be represented in 62 bits unnecessarily. The new value is 9 times smaller than the previous value, and loses only 384000 as a significant factor. This commit also switches to using an (inline) accessor for superclock_ticks_per_second, making it possible in debug/testing phases to spot early/illegal uses of the value.
This commit is contained in:
parent
641589c56a
commit
a803dd0df8
7 changed files with 40 additions and 30 deletions
|
|
@ -31,6 +31,7 @@
|
|||
#include "pbd/ringbuffer.h"
|
||||
|
||||
#include "temporal/bbt_time.h"
|
||||
#include "temporal/superclock.h
|
||||
|
||||
#include "ardour/midi_state_tracker.h"
|
||||
#include "ardour/processor.h"
|
||||
|
|
@ -43,10 +44,6 @@ class StepSequencer;
|
|||
|
||||
typedef uint64_t superclock_t;
|
||||
|
||||
static const superclock_t superclock_ticks_per_second = 508032000; // 2^10 * 3^4 * 5^3 * 7^2
|
||||
inline superclock_t superclock_to_samples (superclock_t s, int sr) { return (s * sr) / superclock_ticks_per_second; }
|
||||
inline superclock_t samples_to_superclock (int samples, int sr) { return (samples * superclock_ticks_per_second) / sr; }
|
||||
|
||||
class BeatBox : public ARDOUR::Processor {
|
||||
public:
|
||||
BeatBox (ARDOUR::Session& s);
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ LuaBindings::common (lua_State* L)
|
|||
|
||||
.beginNamespace ("Temporal")
|
||||
|
||||
.addConst ("superclock_ticks_per_second", Temporal::superclock_ticks_per_second)
|
||||
.addFunction ("superclock_ticks_per_second", Temporal::superclock_ticks_per_second)
|
||||
.addConst ("ticks_per_beat", Temporal::ticks_per_beat)
|
||||
|
||||
.beginClass <Temporal::ratio_t> ("ratio")
|
||||
|
|
|
|||
|
|
@ -341,15 +341,6 @@ Session::Session (AudioEngine &eng,
|
|||
g_atomic_int_set (&_seek_counter, 0);
|
||||
g_atomic_int_set (&_butler_seek_counter, 0);
|
||||
|
||||
/* create a new "default" tempo map. This maybe reset/overwritten by
|
||||
* the session if it already exists during ::set_state()
|
||||
*/
|
||||
|
||||
TempoMap::SharedPtr tmcopy (TempoMap::write_copy());
|
||||
/* this discards the copy that was made, and installs the new default tempo map */
|
||||
tmcopy.reset (new TempoMap (Tempo (120, 4), Meter (4, 4)));
|
||||
TempoMap::update (tmcopy);
|
||||
|
||||
created_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
|
||||
|
||||
pthread_mutex_init (&_rt_emit_mutex, 0);
|
||||
|
|
|
|||
|
|
@ -19,13 +19,22 @@
|
|||
#include "temporal/superclock.h"
|
||||
|
||||
#ifndef COMPILER_MSVC
|
||||
Temporal::superclock_t Temporal::superclock_ticks_per_second = 508032000; // 2^10 * 3^4 * 5^3 * 7^2
|
||||
Temporal::superclock_t Temporal::_superclock_ticks_per_second = 56448000; /* 2^10 * 3^2 * 5^3 * 7^2 */
|
||||
#endif
|
||||
|
||||
int Temporal::most_recent_engine_sample_rate = 48000; /* have to pick something as a default */
|
||||
|
||||
bool Temporal::scts_set = false;
|
||||
|
||||
void
|
||||
Temporal::set_sample_rate (int sr)
|
||||
{
|
||||
most_recent_engine_sample_rate = sr;
|
||||
}
|
||||
|
||||
void
|
||||
Temporal::set_superclock_ticks_per_second (Temporal::superclock_t sc)
|
||||
{
|
||||
_superclock_ticks_per_second = sc;
|
||||
scts_set = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -534,10 +534,10 @@ TempoPoint::quarters_at_superclock (superclock_t sc) const
|
|||
superclock_t sc_delta = sc - _sclock;
|
||||
|
||||
/* convert sc into superbeats, given that sc represents some number of seconds */
|
||||
const superclock_t whole_seconds = sc_delta / superclock_ticks_per_second;
|
||||
const superclock_t remainder = sc_delta - (whole_seconds * superclock_ticks_per_second);
|
||||
const superclock_t whole_seconds = sc_delta / superclock_ticks_per_second();
|
||||
const superclock_t remainder = sc_delta - (whole_seconds * superclock_ticks_per_second());
|
||||
|
||||
const int64_t supernotes = ((_super_note_type_per_second) * whole_seconds) + int_div_round (superclock_t ((_super_note_type_per_second) * remainder), superclock_ticks_per_second);
|
||||
const int64_t supernotes = ((_super_note_type_per_second) * whole_seconds) + int_div_round (superclock_t ((_super_note_type_per_second) * remainder), superclock_ticks_per_second());
|
||||
/* multiply after divide to reduce overflow risk */
|
||||
const int64_t superbeats = int_div_round (supernotes, (superclock_t) _note_type) * 4;
|
||||
|
||||
|
|
@ -2186,7 +2186,7 @@ std::operator<<(std::ostream& str, TempoMetric const & tm)
|
|||
std::ostream&
|
||||
std::operator<<(std::ostream& str, TempoMapPoint const & tmp)
|
||||
{
|
||||
str << '@' << std::setw (12) << tmp.sclock() << ' ' << tmp.sclock() / (double) superclock_ticks_per_second
|
||||
str << '@' << std::setw (12) << tmp.sclock() << ' ' << tmp.sclock() / (double) superclock_ticks_per_second()
|
||||
<< " secs " << tmp.sample (TEMPORAL_SAMPLE_RATE) << " samples"
|
||||
<< (tmp.is_explicit_tempo() ? " EXP-T" : " imp-t")
|
||||
<< (tmp.is_explicit_meter() ? " EXP-M" : " imp-m")
|
||||
|
|
@ -2362,7 +2362,7 @@ TempoMap::get_state ()
|
|||
XMLNode* node = new XMLNode (X_("TempoMap"));
|
||||
|
||||
node->set_property (X_("time-domain"), _time_domain);
|
||||
node->set_property (X_("superclocks-per-second"), superclock_ticks_per_second);
|
||||
node->set_property (X_("superclocks-per-second"), superclock_ticks_per_second());
|
||||
|
||||
XMLNode* children;
|
||||
|
||||
|
|
@ -2397,7 +2397,9 @@ TempoMap::set_state (XMLNode const & node, int version)
|
|||
/* global map properties */
|
||||
|
||||
/* XXX this should probably be at the global level in the session file because it affects a lot more than just the tempo map, potentially */
|
||||
node.get_property (X_("superclocks-per-second"), superclock_ticks_per_second);
|
||||
superclock_t sc;
|
||||
node.get_property (X_("superclocks-per-second"), sc);
|
||||
set_superclock_ticks_per_second (sc);
|
||||
|
||||
node.get_property (X_("time-domain"), _time_domain);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
#ifndef __ardour_superclock_h__
|
||||
#define __ardour_superclock_h__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
#include <csignal>
|
||||
|
||||
#include "pbd/integer_division.h"
|
||||
|
||||
|
|
@ -30,17 +32,26 @@ namespace Temporal {
|
|||
typedef int64_t superclock_t;
|
||||
|
||||
#ifndef COMPILER_MSVC
|
||||
extern superclock_t superclock_ticks_per_second;
|
||||
extern superclock_t _superclock_ticks_per_second;
|
||||
#else
|
||||
static superclock_t superclock_ticks_per_second = 508032000; // 2^10 * 3^4 * 5^3 * 7^2
|
||||
static superclock_t _superclock_ticks_per_second = 56448000; /* 2^10 * 3^2 * 5^3 * 7^2 */
|
||||
#endif
|
||||
|
||||
static inline superclock_t superclock_to_samples (superclock_t s, int sr) { return int_div_round (s * sr, superclock_ticks_per_second); }
|
||||
static inline superclock_t samples_to_superclock (int64_t samples, int sr) { return int_div_round (samples * superclock_ticks_per_second, superclock_t (sr)); }
|
||||
extern bool scts_set;
|
||||
|
||||
#ifdef DEBUG_EARLY_SCTS_USE
|
||||
static inline superclock_t superclock_ticks_per_second() { if (!scts_set) { raise (SIGUSR2); } return _superclock_ticks_per_second; }
|
||||
#else
|
||||
static inline superclock_t superclock_ticks_per_second() { return _superclock_ticks_per_second; }
|
||||
#endif
|
||||
|
||||
static inline superclock_t superclock_to_samples (superclock_t s, int sr) { return int_div_round (s * sr, superclock_ticks_per_second()); }
|
||||
static inline superclock_t samples_to_superclock (int64_t samples, int sr) { return int_div_round (samples * superclock_ticks_per_second(), superclock_t (sr)); }
|
||||
|
||||
extern int most_recent_engine_sample_rate;
|
||||
|
||||
LIBTEMPORAL_API void set_sample_rate (int sr);
|
||||
LIBTEMPORAL_API void set_superclock_ticks_per_second (superclock_t sc);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,9 +210,9 @@ class LIBTEMPORAL_API Tempo : public Rampable {
|
|||
/* these five methods should only be used to show and collect information to the user (for whom
|
||||
* bpm as a floating point number is the obvious representation)
|
||||
*/
|
||||
double note_types_per_minute () const { return (superclock_ticks_per_second * 60.0) / _superclocks_per_note_type; }
|
||||
double end_note_types_per_minute () const { return (superclock_ticks_per_second * 60.0) / _end_superclocks_per_note_type; }
|
||||
double quarter_notes_per_minute() const { return (superclock_ticks_per_second * 60.0 * 4.0) / (_note_type * _superclocks_per_note_type); }
|
||||
double note_types_per_minute () const { return (superclock_ticks_per_second() * 60.0) / _superclocks_per_note_type; }
|
||||
double end_note_types_per_minute () const { return (superclock_ticks_per_second() * 60.0) / _end_superclocks_per_note_type; }
|
||||
double quarter_notes_per_minute() const { return (superclock_ticks_per_second() * 60.0 * 4.0) / (_note_type * _superclocks_per_note_type); }
|
||||
double samples_per_note_type(samplecnt_t sr) const { return superclock_to_samples (superclocks_per_note_type (), sr); }
|
||||
double samples_per_quarter_note(samplecnt_t sr) const { return superclock_to_samples (superclocks_per_quarter_note(), sr); }
|
||||
void set_note_types_per_minute (double npm) { _superclocks_per_note_type = double_npm_to_scpn (npm); }
|
||||
|
|
@ -301,7 +301,7 @@ class LIBTEMPORAL_API Tempo : public Rampable {
|
|||
Type _type;
|
||||
|
||||
static inline uint64_t double_npm_to_snps (double npm) { return (uint64_t) llround (npm * big_numerator / 60); }
|
||||
static inline superclock_t double_npm_to_scpn (double npm) { return (superclock_t) llround ((60./npm) * superclock_ticks_per_second); }
|
||||
static inline superclock_t double_npm_to_scpn (double npm) { return (superclock_t) llround ((60./npm) * superclock_ticks_per_second()); }
|
||||
|
||||
private:
|
||||
void set_ramped (bool yn);
|
||||
|
|
@ -416,7 +416,7 @@ class /*LIBTEMPORAL_API*/ TempoPoint : public Tempo, public tempo_hook, public v
|
|||
*/
|
||||
|
||||
LIBTEMPORAL_API double note_types_per_minute_at_DOUBLE (timepos_t const & pos) const {
|
||||
return (superclock_ticks_per_second * 60.0) / superclocks_per_note_type_at (pos);
|
||||
return (superclock_ticks_per_second() * 60.0) / superclocks_per_note_type_at (pos);
|
||||
}
|
||||
|
||||
LIBTEMPORAL_API double omega() const { return _omega; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue