From c4ac43749048c4c0e0ab3656d39384112a628742 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 28 Oct 2009 21:36:40 +0000 Subject: * libardour uses ARDOUR::nframes_t and ARDOUR::nframes64_t explicitly in headers * use explicit operator<< and operator>> that in turn use PBD::EnumWriter when serializing and deserializing to/from rc files * adds scrolling in mixer window (from 2.X) * BBT math stuff - untested, but basically operational * move LocaleGuard into its own file(s) in libs/pbd * Tempo now uses nframes64_t everywhere (except for sample rate values) * as in 2.X, use mkstemp and hack to avoid temp file nonsense, and remove erroneous free() from disk stats output git-svn-id: svn://localhost/ardour2/branches/3.0@5961 d708f5d6-7413-0410-9779-e7cbd77b26cf --- ardour.rc.in | 40 +-- gtk2_ardour/ardour_ui.cc | 26 +- gtk2_ardour/mixer_ui.cc | 59 ++++ gtk2_ardour/mixer_ui.h | 3 + gtk2_ardour/opts.cc | 13 +- libs/ardour/ardour/ardour.h | 20 +- libs/ardour/ardour/bbt_time.h | 2 - libs/ardour/ardour/configuration_variable.h | 11 +- libs/ardour/ardour/debug.h | 3 +- libs/ardour/ardour/mix.h | 38 +-- libs/ardour/ardour/peak.h | 4 +- libs/ardour/ardour/tempo.h | 82 ++--- libs/ardour/ardour/types.h | 50 ++- libs/ardour/ardour/utils.h | 2 +- libs/ardour/configuration.cc | 26 +- libs/ardour/enums.cc | 229 ++++++++++++++ libs/ardour/globals.cc | 50 +-- libs/ardour/midi_region.cc | 1 + libs/ardour/session.cc | 1 + libs/ardour/session_configuration.cc | 1 + libs/ardour/sse_functions_xmm.cc | 2 +- libs/ardour/tempo.cc | 411 ++++++++++++++++++++----- libs/pbd/locale_guard.cc | 22 ++ libs/pbd/pbd/enumwriter.h | 4 + libs/pbd/pbd/locale_guard.h | 33 ++ libs/pbd/wscript | 1 + libs/surfaces/mackie/mackie_control_protocol.h | 4 +- 27 files changed, 846 insertions(+), 292 deletions(-) create mode 100644 libs/pbd/locale_guard.cc create mode 100644 libs/pbd/pbd/locale_guard.h diff --git a/ardour.rc.in b/ardour.rc.in index fa9c1fbafc..52572563c9 100644 --- a/ardour.rc.in +++ b/ardour.rc.in @@ -4,41 +4,41 @@ diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index f10f287ef8..f6208fab8c 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -3009,36 +3009,38 @@ ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback) void ARDOUR_UI::write_buffer_stats () { + + std::ofstream fout; struct tm tm; char buf[64]; + char path[PATH_MAX+1]; int fd; + + strcpy (path, "ardourBufferingXXXXXX"); - char* tmplt = (char*)calloc(strlen("ardourXXXXXX"), sizeof(char)); - int fd = mkstemp (tmplt); - if (fd) { + if ((fd = mkstemp (path )) < 0) { cerr << X_("cannot find temporary name for ardour buffer stats") << endl; return; } + + fout.open (path); + close (fd); - FILE* fout = fdopen (fd, "w"); if (!fout) { - cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), tmplt) << endl; + cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl; return; } for (list::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) { - std::ostringstream ss; localtime_r (&(*i).when, &tm); strftime (buf, sizeof (buf), "%T", &tm); - fprintf(fout, "%s %u %u\n", buf, (*i).capture, (*i).playback); + fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl; } - + disk_buffer_stats.clear (); - fclose (fout); - close (fd); + fout.close (); - cerr << "Ardour buffering statistics can be found in: " << tmplt << endl; - free (tmplt); + cerr << "Ardour buffering statistics can be found in: " << path << endl; } void diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index dbc61f4308..0d3f42c1d5 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -1459,10 +1459,38 @@ Mixer_UI::pane_allocation_handler (Allocation&, Gtk::Paned* which) } } } +void +Mixer_UI::scroll_left () +{ + Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); + /* stupid GTK: can't rely on clamping across versions */ + scroller.get_hscrollbar()->set_value (max (adj->get_lower(), adj->get_value() - adj->get_step_increment())); +} + +void +Mixer_UI::scroll_right () +{ + Adjustment* adj = scroller.get_hscrollbar()->get_adjustment(); + /* stupid GTK: can't rely on clamping across versions */ + scroller.get_hscrollbar()->set_value (min (adj->get_upper(), adj->get_value() + adj->get_step_increment())); +} bool Mixer_UI::on_key_press_event (GdkEventKey* ev) { + switch (ev->keyval) { + case GDK_Left: + scroll_left (); + return true; + + case GDK_Right: + scroll_right (); + return true; + + default: + break; + } + return key_press_focus_accelerator_handler (*this, ev); } @@ -1473,6 +1501,37 @@ Mixer_UI::on_key_release_event (GdkEventKey* ev) // return key_press_focus_accelerator_handler (*this, ev); } + +bool +Mixer_UI::on_scroll_event (GdkEventScroll* ev) +{ + switch (ev->direction) { + case GDK_SCROLL_LEFT: + scroll_left (); + return true; + case GDK_SCROLL_UP: + if (ev->state & Keyboard::TertiaryModifier) { + scroll_left (); + return true; + } + return false; + + case GDK_SCROLL_RIGHT: + scroll_right (); + return true; + + case GDK_SCROLL_DOWN: + if (ev->state & Keyboard::TertiaryModifier) { + scroll_right (); + return true; + } + return false; + } + + return false; +} + + void Mixer_UI::parameter_changed (string const & p) { diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index bb96255406..2945e00858 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -114,12 +114,15 @@ class Mixer_UI : public Gtk::Window bool on_key_press_event (GdkEventKey*); bool on_key_release_event (GdkEventKey*); + bool on_scroll_event (GdkEventScroll*); void pane_allocation_handler (Gtk::Allocation&, Gtk::Paned*); std::list strips; bool strip_scroller_button_release (GdkEventButton*); + void scroll_left (); + void scroll_right (); void add_strip (ARDOUR::RouteList&); void remove_strip (MixerStrip *); diff --git a/gtk2_ardour/opts.cc b/gtk2_ardour/opts.cc index 153dbfe56a..cd45bed9ff 100644 --- a/gtk2_ardour/opts.cc +++ b/gtk2_ardour/opts.cc @@ -77,11 +77,12 @@ print_help (const char *execname) static void list_debug_options () { - cerr << _("The following debug options are available. Separate multipe options with commas. Names are case-insensitive.") << "\n\n"; + cerr << _("The following debug options are available. Separate multipe options with commas.\nNames are case-insensitive and can be abbreviated.") << "\n\n"; cerr << "\tMidiSourceIO\n"; cerr << "\tMidiPlaylistIO\n"; cerr << "\tMidiDiskstreamIO\n"; cerr << "\tSnapBBT\n"; + cerr << "\tConfiguration\n"; } static int @@ -107,14 +108,16 @@ parse_debug_options (const char* str) return 0; } - if (strcasecmp (p, "midisourceio") == 0) { + if (strncasecmp (p, "midisourceio", strlen (p)) == 0) { bits |= ARDOUR::DEBUG::MidiSourceIO; - } else if (strcasecmp (p, "midiplaylistio") == 0) { + } else if (strncasecmp (p, "midiplaylistio", strlen (p)) == 0) { bits |= ARDOUR::DEBUG::MidiPlaylistIO; - } else if (strcasecmp (p, "mididiskstreamio") == 0) { + } else if (strncasecmp (p, "mididiskstreamio", strlen (p)) == 0) { bits |= ARDOUR::DEBUG::MidiDiskstreamIO; - } else if (strcasecmp (p, "snapbbt") == 0) { + } else if (strncasecmp (p, "snapbbt", strlen (p)) == 0) { bits |= ARDOUR::DEBUG::SnapBBT; + } else if (strncasecmp (p, "configuration", strlen (p)) == 0) { + bits |= ARDOUR::DEBUG::Configuration; } p = strtok_r (0, ",", &sp); diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index d7c67998c7..a1b3d06f62 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1999 Paul Davis + Copyright (C) 1999-2009 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,10 +28,11 @@ #include "pbd/error.h" #include "pbd/failed_constructor.h" +#include "pbd/locale_guard.h" #include "ardour/types.h" -// #include need this to inline jack_get_microseconds +#include namespace MIDI { class MachineControl; @@ -56,13 +57,10 @@ namespace ARDOUR { const layer_t max_layer = UCHAR_MAX; - microseconds_t get_microseconds (); -/* { - JACK has exported this functionality for a long time now - but inlining this causes problems - return (microseconds_t) jack_get_time(); + static inline microseconds_t get_microseconds () { + return (microseconds_t) jack_get_time(); } -*/ + Change new_change (); extern Change StartChanged; @@ -71,12 +69,6 @@ namespace ARDOUR { extern Change NameChanged; extern Change BoundsChanged; - struct LocaleGuard { - LocaleGuard (const char*); - ~LocaleGuard (); - const char* old; - }; - static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */ void setup_fpu (); diff --git a/libs/ardour/ardour/bbt_time.h b/libs/ardour/ardour/bbt_time.h index 44921ae6cc..b92bd2f18f 100644 --- a/libs/ardour/ardour/bbt_time.h +++ b/libs/ardour/ardour/bbt_time.h @@ -25,8 +25,6 @@ namespace ARDOUR { -class TempoMetric; - struct BBT_Time { uint32_t bars; uint32_t beats; diff --git a/libs/ardour/ardour/configuration_variable.h b/libs/ardour/ardour/configuration_variable.h index 90859b72b1..9c9cf4463e 100644 --- a/libs/ardour/ardour/configuration_variable.h +++ b/libs/ardour/ardour/configuration_variable.h @@ -20,11 +20,11 @@ #ifndef __ardour_configuration_variable_h__ #define __ardour_configuration_variable_h__ -#include -#include #include +#include #include "pbd/xml++.h" +#include "ardour/types.h" namespace ARDOUR { @@ -41,13 +41,8 @@ class ConfigVariableBase { virtual std::string get_as_string () const = 0; virtual void set_from_string (std::string const &) = 0; - void show_stored_value (const std::string&); - - static void set_show_stored_values (bool); - protected: std::string _name; - static bool show_stores; void notify (); void miss (); @@ -66,7 +61,7 @@ class ConfigVariable : public ConfigVariableBase } std::string get_as_string () const { - std::stringstream ss; + std::ostringstream ss; ss << value; return ss.str (); } diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h index a8f826babe..d91b3c1449 100644 --- a/libs/ardour/ardour/debug.h +++ b/libs/ardour/ardour/debug.h @@ -38,7 +38,8 @@ namespace ARDOUR { MidiSourceIO = 0x1, MidiPlaylistIO = 0x2, MidiDiskstreamIO = 0x4, - SnapBBT = 0x8 + SnapBBT = 0x8, + Configuration = 0x10 }; } diff --git a/libs/ardour/ardour/mix.h b/libs/ardour/ardour/mix.h index fed0f467b2..72b414d09c 100644 --- a/libs/ardour/ardour/mix.h +++ b/libs/ardour/ardour/mix.h @@ -26,39 +26,39 @@ extern "C" { /* SSE functions */ - float x86_sse_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); - void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); - void x86_sse_mix_buffers_with_gain(ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); - void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); + float x86_sse_compute_peak (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float current); + void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::nframes_t nframes, float gain); + void x86_sse_mix_buffers_with_gain(ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes, float gain); + void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes); } -void x86_sse_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); +void x86_sse_find_peaks (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float *min, float *max); /* debug wrappers for SSE functions */ -float debug_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void debug_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void debug_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void debug_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); +float debug_compute_peak (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float current); +void debug_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::nframes_t nframes, float gain); +void debug_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes, float gain); +void debug_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes); #endif #if defined (__APPLE__) -float veclib_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void veclib_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); -void veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); +float veclib_compute_peak (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float current); +void veclib_find_peaks (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float *min, float *max); +void veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::nframes_t nframes, float gain); +void veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes, float gain); +void veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes); #endif /* non-optimized functions */ -float default_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void default_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); -void default_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void default_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); +float default_compute_peak (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float current); +void default_find_peaks (const ARDOUR::Sample * buf, ARDOUR::nframes_t nsamples, float *min, float *max); +void default_apply_gain_to_buffer (ARDOUR::Sample * buf, ARDOUR::nframes_t nframes, float gain); +void default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes, float gain); +void default_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, ARDOUR::nframes_t nframes); #endif /* __ardour_mix_h__ */ diff --git a/libs/ardour/ardour/peak.h b/libs/ardour/ardour/peak.h index 5be2c08f41..2283f50118 100644 --- a/libs/ardour/ardour/peak.h +++ b/libs/ardour/ardour/peak.h @@ -25,9 +25,9 @@ #include "ardour/utils.h" static inline float -default_compute_peak (const ARDOUR::Sample * const buf, nframes_t nsamples, float current) +default_compute_peak (const ARDOUR::Sample * const buf, ARDOUR::nframes_t nsamples, float current) { - for (nframes_t i = 0; i < nsamples; ++i) { + for (ARDOUR::nframes_t i = 0; i < nsamples; ++i) { current = f_max (current, fabsf (buf[i])); } return current; diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 99dfffa81f..28c974bff1 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -81,18 +81,18 @@ class MetricSection { public: MetricSection (const BBT_Time& start) : _start (start), _frame (0), _movable (true) {} - MetricSection (nframes_t start) + MetricSection (nframes64_t start) : _frame (start), _movable (true) {} virtual ~MetricSection() {} const BBT_Time& start() const { return _start; } - nframes_t frame() const { return _frame; } + nframes64_t frame() const { return _frame; } void set_movable (bool yn) { _movable = yn; } bool movable() const { return _movable; } - virtual void set_frame (nframes_t f) { + virtual void set_frame (nframes64_t f) { _frame = f; } @@ -108,7 +108,7 @@ class MetricSection { private: BBT_Time _start; - nframes_t _frame; + nframes64_t _frame; bool _movable; }; @@ -116,7 +116,7 @@ class MeterSection : public MetricSection, public Meter { public: MeterSection (const BBT_Time& start, double bpb, double note_type) : MetricSection (start), Meter (bpb, note_type) {} - MeterSection (nframes_t start, double bpb, double note_type) + MeterSection (nframes64_t start, double bpb, double note_type) : MetricSection (start), Meter (bpb, note_type) {} MeterSection (const XMLNode&); @@ -129,7 +129,7 @@ class TempoSection : public MetricSection, public Tempo { public: TempoSection (const BBT_Time& start, double qpm, double note_type) : MetricSection (start), Tempo (qpm, note_type) {} - TempoSection (nframes_t start, double qpm, double note_type) + TempoSection (nframes64_t start, double qpm, double note_type) : MetricSection (start), Tempo (qpm, note_type) {} TempoSection (const XMLNode&); @@ -149,25 +149,25 @@ class TempoMetric { void set_tempo (const Tempo& t) { _tempo = &t; } void set_meter (const Meter& m) { _meter = &m; } - void set_frame (nframes_t f) { _frame = f; } + void set_frame (nframes64_t f) { _frame = f; } void set_start (const BBT_Time& t) { _start = t; } const Meter& meter() const { return *_meter; } const Tempo& tempo() const { return *_tempo; } - nframes_t frame() const { return _frame; } + nframes64_t frame() const { return _frame; } const BBT_Time& start() const { return _start; } private: const Meter* _meter; const Tempo* _tempo; - nframes_t _frame; + nframes64_t _frame; BBT_Time _start; }; class TempoMap : public PBD::StatefulDestructible { public: - TempoMap (nframes_t frame_rate); + TempoMap (nframes64_t frame_rate); ~TempoMap(); /* measure-based stuff */ @@ -179,13 +179,13 @@ class TempoMap : public PBD::StatefulDestructible struct BBTPoint { BBTPointType type; - nframes_t frame; + nframes64_t frame; const Meter* meter; const Tempo* tempo; uint32_t bar; uint32_t beat; - BBTPoint (const Meter& m, const Tempo& t, nframes_t f, + BBTPoint (const Meter& m, const Tempo& t, nframes64_t f, BBTPointType ty, uint32_t b, uint32_t e) : type (ty), frame (f), meter (&m), tempo (&t), bar (b), beat (e) {} }; @@ -197,27 +197,27 @@ class TempoMap : public PBD::StatefulDestructible (obj.*method)(*metrics); } - BBTPointList *get_points (nframes_t start, nframes_t end) const; + BBTPointList *get_points (nframes64_t start, nframes64_t end) const; - void bbt_time (nframes_t when, BBT_Time&) const; - nframes_t frame_time (const BBT_Time&) const; - nframes_t bbt_duration_at (nframes_t, const BBT_Time&, int dir) const; + void bbt_time (nframes64_t when, BBT_Time&) const; + nframes64_t frame_time (const BBT_Time&) const; + nframes64_t bbt_duration_at (nframes64_t, const BBT_Time&, int dir) const; void bbt_time_add (nframes64_t origin, BBT_Time& start, const BBT_Time& shift); static const Tempo& default_tempo() { return _default_tempo; } static const Meter& default_meter() { return _default_meter; } - const Tempo& tempo_at (nframes_t) const; - const Meter& meter_at (nframes_t) const; + const Tempo& tempo_at (nframes64_t) const; + const Meter& meter_at (nframes64_t) const; - const TempoSection& tempo_section_at (nframes_t); + const TempoSection& tempo_section_at (nframes64_t); void add_tempo(const Tempo&, BBT_Time where); void add_meter(const Meter&, BBT_Time where); - void add_tempo(const Tempo&, nframes_t where); - void add_meter(const Meter&, nframes_t where); + void add_tempo(const Tempo&, nframes64_t where); + void add_meter(const Meter&, nframes64_t where); void move_tempo (TempoSection&, const BBT_Time& to); void move_meter (MeterSection&, const BBT_Time& to); @@ -228,12 +228,12 @@ class TempoMap : public PBD::StatefulDestructible void replace_tempo (TempoSection& existing, const Tempo& replacement); void replace_meter (MeterSection& existing, const Meter& replacement); - nframes_t round_to_bar (nframes_t frame, int dir); - nframes_t round_to_beat (nframes_t frame, int dir); - nframes_t round_to_beat_subdivision (nframes_t fr, int sub_num, int dir); - nframes_t round_to_tick (nframes_t frame, int dir); + nframes64_t round_to_bar (nframes64_t frame, int dir); + nframes64_t round_to_beat (nframes64_t frame, int dir); + nframes64_t round_to_beat_subdivision (nframes64_t fr, int sub_num, int dir); + nframes64_t round_to_tick (nframes64_t frame, int dir); - void set_length (nframes_t frames); + void set_length (nframes64_t frames); XMLNode& get_state (void); int set_state (const XMLNode&, int version); @@ -242,21 +242,21 @@ class TempoMap : public PBD::StatefulDestructible void clear (); TempoMetric metric_at (BBT_Time bbt) const; - TempoMetric metric_at (nframes_t) const; - void bbt_time_with_metric (nframes_t, BBT_Time&, const TempoMetric&) const; + TempoMetric metric_at (nframes64_t) const; + void bbt_time_with_metric (nframes64_t, BBT_Time&, const TempoMetric&) const; - void change_existing_tempo_at (nframes_t, double bpm, double note_type); + BBT_Time bbt_add (const BBT_Time&, const BBT_Time&, const TempoMetric&) const; + BBT_Time bbt_add (const BBT_Time& a, const BBT_Time& b) const; + BBT_Time bbt_subtract (const BBT_Time&, const BBT_Time&) const; + + void change_existing_tempo_at (nframes64_t, double bpm, double note_type); void change_initial_tempo (double bpm, double note_type); - void insert_time (nframes_t, nframes_t); + void insert_time (nframes64_t, nframes64_t); int n_tempos () const; int n_meters () const; - BBT_Time bbt_add (const BBT_Time& a, const BBT_Time& b, const TempoMetric& metric); - BBT_Time bbt_add (const BBT_Time& a, const BBT_Time& b); - BBT_Time bbt_subtract (const BBT_Time& a, const BBT_Time& b); - nframes_t frame_rate () const { return _frame_rate; } sigc::signal StateChanged; @@ -267,26 +267,26 @@ class TempoMap : public PBD::StatefulDestructible Metrics* metrics; nframes_t _frame_rate; - nframes_t last_bbt_when; + nframes64_t last_bbt_when; bool last_bbt_valid; BBT_Time last_bbt; mutable Glib::RWLock lock; void timestamp_metrics (bool use_bbt); - nframes_t round_to_type (nframes_t fr, int dir, BBTPointType); + nframes64_t round_to_type (nframes64_t fr, int dir, BBTPointType); - nframes_t frame_time_unlocked (const BBT_Time&) const; + nframes64_t frame_time_unlocked (const BBT_Time&) const; - void bbt_time_unlocked (nframes_t, BBT_Time&) const; + void bbt_time_unlocked (nframes64_t, BBT_Time&) const; - nframes_t bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const; + nframes64_t bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const; const MeterSection& first_meter() const; const TempoSection& first_tempo() const; - nframes_t count_frames_between (const BBT_Time&, const BBT_Time&) const; - nframes_t count_frames_between_metrics (const Meter&, const Tempo&, + nframes64_t count_frames_between (const BBT_Time&, const BBT_Time&) const; + nframes64_t count_frames_between_metrics (const Meter&, const Tempo&, const BBT_Time&, const BBT_Time&) const; int move_metric_section (MetricSection&, const BBT_Time& to); diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index c6fc2419b2..6ec954075c 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -39,16 +39,9 @@ #include #if __GNUC__ < 3 - typedef int intptr_t; #endif -/* eventually, we'd like everything (including JACK) to - move to this. for now, its a dedicated type. -*/ - -typedef int64_t nframes64_t; - namespace ARDOUR { class Source; @@ -61,6 +54,8 @@ namespace ARDOUR { typedef uint32_t layer_t; typedef uint64_t microseconds_t; typedef uint32_t nframes_t; + typedef int64_t nframes64_t; + /** "Session frames", frames relative to the session timeline. * Everything related to transport position etc. should be of this type. @@ -430,6 +425,11 @@ namespace ARDOUR { } // namespace ARDOUR + +/* these cover types declared above in this header. See enums.cc + for the definitions. +*/ + std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf); @@ -447,20 +447,40 @@ std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf); std::istream& operator>>(std::istream& o, ARDOUR::WaveformScale& sf); std::istream& operator>>(std::istream& o, ARDOUR::WaveformShape& sf); -using ARDOUR::nframes_t; - -static inline nframes_t -session_frame_to_track_frame (nframes_t session_frame, double speed) +std::ostream& operator<<(std::ostream& o, const ARDOUR::SampleFormat& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::HeaderFormat& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::AutoConnectOption& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::EditMode& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::MonitorModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::RemoteModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::ListenPosition& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::LayerModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::CrossfadeModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::SlaveSource& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::ShuttleBehaviour& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::ShuttleUnits& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::TimecodeFormat& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::DenormalModel& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformScale& sf); +std::ostream& operator<<(std::ostream& o, const ARDOUR::WaveformShape& sf); + +static inline ARDOUR::nframes64_t +session_frame_to_track_frame (ARDOUR::nframes64_t session_frame, double speed) { - return (nframes_t)( (double)session_frame * speed ); + return (ARDOUR::nframes64_t)( (double)session_frame * speed ); } -static inline nframes_t -track_frame_to_session_frame (nframes_t track_frame, double speed) +static inline ARDOUR::nframes64_t +track_frame_to_session_frame (ARDOUR::nframes64_t track_frame, double speed) { - return (nframes_t)( (double)track_frame / speed ); + return (ARDOUR::nframes64_t)( (double)track_frame / speed ); } +/* for now, break the rules and use "using" to make these "global" */ + +using ARDOUR::nframes_t; +using ARDOUR::nframes64_t; + #endif /* __ardour_types_h__ */ diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h index 027e95dae8..c43b7ed37e 100644 --- a/libs/ardour/ardour/utils.h +++ b/libs/ardour/ardour/utils.h @@ -60,7 +60,7 @@ Glib::ustring path_expand (Glib::ustring); Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels, bool add_channel_suffix = false, uint32_t total = 0, uint32_t this_one = 0); bool path_is_paired (Glib::ustring path, Glib::ustring& pair_base); -void compute_equal_power_fades (nframes_t nframes, float* in, float* out); +void compute_equal_power_fades (ARDOUR::nframes_t nframes, float* in, float* out); const char* slave_source_to_string (ARDOUR::SlaveSource src); ARDOUR::SlaveSource string_to_slave_source (std::string str); diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc index 68f13f8245..d5ca426a74 100644 --- a/libs/ardour/configuration.cc +++ b/libs/ardour/configuration.cc @@ -17,7 +17,12 @@ */ +#include + +#include "pbd/compose.h" + #include "ardour/configuration.h" +#include "ardour/debug.h" using namespace ARDOUR; using namespace std; @@ -31,13 +36,11 @@ Configuration::~Configuration () { } -bool ConfigVariableBase::show_stores = false; - void ConfigVariableBase::add_to_node (XMLNode& node) { - std::string const v = get_as_string (); - show_stored_value (v); + const std::string v = get_as_string (); + DEBUG_TRACE (DEBUG::Configuration, string_compose ("Config variable %1 stored as [%2]\n", _name, v)); XMLNode* child = new XMLNode ("Option"); child->add_property ("name", _name); child->add_property ("value", v); @@ -101,21 +104,6 @@ ConfigVariableBase::set_from_node (XMLNode const & node) return false; } - -void -ConfigVariableBase::set_show_stored_values (bool yn) -{ - show_stores = yn; -} - -void -ConfigVariableBase::show_stored_value (const string& str) -{ - if (show_stores) { - cerr << "Config variable " << _name << " stored as " << str << endl; - } -} - void ConfigVariableBase::notify () { diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index af0ca7e14c..8ab2a6f8cf 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -111,6 +111,9 @@ setup_enum_writer () IO::Direction _IO_Direction; MuteMaster::MutePoint _MuteMaster_MutePoint; MidiModel::DiffCommand::Property _MidiModel_DiffCommand_Property; + WaveformScale _WaveformScale; + WaveformShape _WaveformShape; + QuantizeType _QuantizeType; #define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear() @@ -531,4 +534,230 @@ setup_enum_writer () REGISTER_CLASS_ENUM (MidiModel::DiffCommand, StartTime); REGISTER_CLASS_ENUM (MidiModel::DiffCommand, Length); REGISTER (_MidiModel_DiffCommand_Property); + + REGISTER_ENUM(Linear); + REGISTER_ENUM(Logarithmic); + REGISTER(_WaveformScale); + + REGISTER_ENUM(Traditional); + REGISTER_ENUM(Rectified); + REGISTER(_WaveformShape); + + REGISTER_ENUM(Plain); + REGISTER_ENUM(Legato); + REGISTER_ENUM(Groove); + REGISTER(_QuantizeType); + +} + +/* deserializing types from ardour/types.h */ + +std::istream& operator>>(std::istream& o, HeaderFormat& var) +{ + std::string s; + o >> s; + var = (HeaderFormat) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const HeaderFormat& var) +{ + std::string s = enum_2_string (var); + return o << s; +} + +std::istream& operator>>(std::istream& o, SampleFormat& var) +{ + std::string s; + o >> s; + var = (SampleFormat) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const SampleFormat& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, AutoConnectOption& var) +{ + std::string s; + o >> s; + var = (AutoConnectOption) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const AutoConnectOption& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, MonitorModel& var) +{ + std::string s; + o >> s; + var = (MonitorModel) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const MonitorModel& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, RemoteModel& var) +{ + std::string s; + o >> s; + var = (RemoteModel) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const RemoteModel& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, EditMode& var) +{ + std::string s; + o >> s; + var = (EditMode) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const EditMode& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, ListenPosition& var) +{ + std::string s; + o >> s; + var = (ListenPosition) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const ListenPosition& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, LayerModel& var) +{ + std::string s; + o >> s; + var = (LayerModel) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const LayerModel& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, CrossfadeModel& var) +{ + std::string s; + o >> s; + var = (CrossfadeModel) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const CrossfadeModel& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, SlaveSource& var) +{ + std::string s; + o >> s; + var = (SlaveSource) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const SlaveSource& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) +{ + std::string s; + o >> s; + var = (ShuttleBehaviour) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const ShuttleBehaviour& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, ShuttleUnits& var) +{ + std::string s; + o >> s; + var = (ShuttleUnits) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const ShuttleUnits& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, TimecodeFormat& var) +{ + std::string s; + o >> s; + var = (TimecodeFormat) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const TimecodeFormat& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, DenormalModel& var) +{ + std::string s; + o >> s; + var = (DenormalModel) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const DenormalModel& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, WaveformScale& var) +{ + std::string s; + o >> s; + var = (WaveformScale) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const WaveformScale& var) +{ + std::string s = enum_2_string (var); + return o << s; +} +std::istream& operator>>(std::istream& o, WaveformShape& var) +{ + std::string s; + o >> s; + var = (WaveformShape) string_2_enum (s, var); + return o; +} + +std::ostream& operator<<(std::ostream& o, const WaveformShape& var) +{ + std::string s = enum_2_string (var); + return o << s; } diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 05894d8377..4d75c30a0d 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -28,7 +28,6 @@ #include #include #include -#include #include #ifdef VST_SUPPORT @@ -53,6 +52,7 @@ #include "pbd/strsplit.h" #include "pbd/fpu.h" #include "pbd/file_utils.h" +#include "pbd/enumwriter.h" #include "midi++/port.h" #include "midi++/manager.h" @@ -401,13 +401,6 @@ ARDOUR::cleanup () return 0; } - -microseconds_t -ARDOUR::get_microseconds () -{ - return (microseconds_t) jack_get_time (); -} - ARDOUR::Change ARDOUR::new_change () { @@ -468,20 +461,6 @@ ARDOUR::no_auto_connect() return getenv ("ARDOUR_NO_AUTOCONNECT") != 0; } -ARDOUR::LocaleGuard::LocaleGuard (const char* str) -{ - old = strdup (setlocale (LC_NUMERIC, NULL)); - if (strcmp (old, str)) { - setlocale (LC_NUMERIC, str); - } -} - -ARDOUR::LocaleGuard::~LocaleGuard () -{ - setlocale (LC_NUMERIC, old); - free ((char*)old); -} - void ARDOUR::setup_fpu () { @@ -620,30 +599,3 @@ ARDOUR::coverage (nframes_t sa, nframes_t ea, return OverlapNone; } -/* not sure where to put these */ - -template -std::istream& int_to_type (std::istream& o, T& hf) { - int val; - o >> val; - hf = (T) val; - return o; -} - -std::istream& operator>>(std::istream& o, HeaderFormat& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, SampleFormat& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, AutoConnectOption& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, MonitorModel& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, RemoteModel& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, EditMode& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, ListenPosition& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, LayerModel& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, TimecodeFormat& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, DenormalModel& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, WaveformScale& var) { return int_to_type (o, var); } -std::istream& operator>>(std::istream& o, WaveformShape& var) { return int_to_type (o, var); } - diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index c17763bf80..a722afd399 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -47,6 +47,7 @@ using namespace std; using namespace ARDOUR; +using namespace PBD; /** Basic MidiRegion constructor (one channel) */ MidiRegion::MidiRegion (boost::shared_ptr src, nframes_t start, nframes_t length) diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index c23712d1b9..564031fc75 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -74,6 +74,7 @@ #include "ardour/plugin_insert.h" #include "ardour/port_insert.h" #include "ardour/processor.h" +#include "ardour/rc_configuration.h" #include "ardour/recent_sessions.h" #include "ardour/region_factory.h" #include "ardour/return.h" diff --git a/libs/ardour/session_configuration.cc b/libs/ardour/session_configuration.cc index 0f00dae161..0cdb85bfd0 100644 --- a/libs/ardour/session_configuration.cc +++ b/libs/ardour/session_configuration.cc @@ -24,6 +24,7 @@ #include "i18n.h" using namespace ARDOUR; +using namespace PBD; SessionConfiguration::SessionConfiguration () : diff --git a/libs/ardour/sse_functions_xmm.cc b/libs/ardour/sse_functions_xmm.cc index c20dbb4e27..c1f11c4c83 100644 --- a/libs/ardour/sse_functions_xmm.cc +++ b/libs/ardour/sse_functions_xmm.cc @@ -22,7 +22,7 @@ #include "ardour/types.h" void -x86_sse_find_peaks(const ARDOUR::Sample* buf, nframes_t nframes, float *min, float *max) +x86_sse_find_peaks(const ARDOUR::Sample* buf, ARDOUR::nframes_t nframes, float *min, float *max) { __m128 current_max, current_min, work; diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index d7300f937b..da7706aaf5 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -18,6 +18,8 @@ */ #include +#include + #include #include @@ -217,7 +219,7 @@ struct MetricSectionSorter { } }; -TempoMap::TempoMap (nframes_t fr) +TempoMap::TempoMap (nframes64_t fr) { metrics = new Metrics; _frame_rate = fr; @@ -258,11 +260,11 @@ TempoMap::move_metric_section (MetricSection& section, const BBT_Time& when) /* position by audio frame, then recompute BBT timestamps from the audio ones */ - nframes_t frame = frame_time (when); + nframes64_t frame = frame_time (when); // cerr << "nominal frame time = " << frame << endl; - nframes_t prev_frame = round_to_type (frame, -1, Beat); - nframes_t next_frame = round_to_type (frame, 1, Beat); + nframes64_t prev_frame = round_to_type (frame, -1, Beat); + nframes64_t next_frame = round_to_type (frame, 1, Beat); // cerr << "previous beat at " << prev_frame << " next at " << next_frame << endl; @@ -409,7 +411,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where) } void -TempoMap::add_tempo (const Tempo& tempo, nframes_t where) +TempoMap::add_tempo (const Tempo& tempo, nframes64_t where) { { Glib::RWLock::WriterLock lm (lock); @@ -477,7 +479,7 @@ TempoMap::add_meter (const Meter& meter, BBT_Time where) } void -TempoMap::add_meter (const Meter& meter, nframes_t where) +TempoMap::add_meter (const Meter& meter, nframes64_t where) { { Glib::RWLock::WriterLock lm (lock); @@ -530,7 +532,7 @@ TempoMap::change_initial_tempo (double beats_per_minute, double note_type) } void -TempoMap::change_existing_tempo_at (nframes_t where, double beats_per_minute, double note_type) +TempoMap::change_existing_tempo_at (nframes64_t where, double beats_per_minute, double note_type) { Tempo newtempo (beats_per_minute, note_type); @@ -620,8 +622,8 @@ TempoMap::timestamp_metrics (bool use_bbt) // cerr << "\n\n\n ######################\nTIMESTAMP via BBT ##############\n" << endl; - nframes_t current = 0; - nframes_t section_frames; + nframes64_t current = 0; + nframes64_t section_frames; BBT_Time start; BBT_Time end; @@ -715,7 +717,7 @@ TempoMap::timestamp_metrics (bool use_bbt) } TempoMetric -TempoMap::metric_at (nframes_t frame) const +TempoMap::metric_at (nframes64_t frame) const { TempoMetric m (first_meter(), first_tempo()); const Meter* meter; @@ -783,7 +785,7 @@ TempoMap::metric_at (BBT_Time bbt) const } void -TempoMap::bbt_time (nframes_t frame, BBT_Time& bbt) const +TempoMap::bbt_time (nframes64_t frame, BBT_Time& bbt) const { { Glib::RWLock::ReaderLock lm (lock); @@ -792,15 +794,15 @@ TempoMap::bbt_time (nframes_t frame, BBT_Time& bbt) const } void -TempoMap::bbt_time_unlocked (nframes_t frame, BBT_Time& bbt) const +TempoMap::bbt_time_unlocked (nframes64_t frame, BBT_Time& bbt) const { bbt_time_with_metric (frame, bbt, metric_at (frame)); } void -TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const TempoMetric& metric) const +TempoMap::bbt_time_with_metric (nframes64_t frame, BBT_Time& bbt, const TempoMetric& metric) const { - nframes_t frame_diff; + nframes64_t frame_diff; // cerr << "---- BBT time for " << frame << " using metric @ " << metric.frame() << " BBT " << metric.start() << endl; @@ -831,11 +833,11 @@ TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const TempoMetri 0.1/4, but I can't be bothered to test that. */ uint32_t ticks_on_last_beat = (uint32_t)floor(Meter::ticks_per_beat * beat_fraction); - if(bbt.beats > (uint32_t)floor(beats_per_bar) && - bbt.ticks >= ticks_on_last_beat) { - bbt.ticks -= ticks_on_last_beat; - bbt.beats = 0; - bbt.bars++; + + if (bbt.beats > (uint32_t)floor(beats_per_bar) && bbt.ticks >= ticks_on_last_beat) { + bbt.ticks -= ticks_on_last_beat; + bbt.beats = 0; + bbt.bars++; } bbt.beats++; // correction for 1-based counting, see above for matching operation. @@ -843,16 +845,16 @@ TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const TempoMetri // cerr << "-----\t RETURN " << bbt << endl; } -nframes_t +nframes64_t TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) const { /* for this to work with fractional measure types, start and end have to be "legal" BBT types, that means that the beats and ticks should be inside a bar */ - nframes_t frames = 0; - nframes_t start_frame = 0; - nframes_t end_frame = 0; + nframes64_t frames = 0; + nframes64_t start_frame = 0; + nframes64_t end_frame = 0; TempoMetric m = metric_at (start); @@ -862,7 +864,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con + start.ticks/Meter::ticks_per_beat; - start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); + start_frame = m.frame() + (nframes64_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); m = metric_at(end); @@ -871,7 +873,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) + end.ticks/Meter::ticks_per_beat; - end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); + end_frame = m.frame() + (nframes64_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); frames = end_frame - start_frame; @@ -879,12 +881,12 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con } -nframes_t +nframes64_t TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, const BBT_Time& start, const BBT_Time& end) const { /* this is used in timestamping the metrics by actually counting the beats */ - nframes_t frames = 0; + nframes64_t frames = 0; uint32_t bar = start.bars; double beat = (double) start.beats; double beats_counted = 0; @@ -923,13 +925,13 @@ TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, // << " fpb was " << beat_frames // << endl; - frames = (nframes_t) floor (beats_counted * beat_frames); + frames = (nframes64_t) floor (beats_counted * beat_frames); return frames; } -nframes_t +nframes64_t TempoMap::frame_time (const BBT_Time& bbt) const { BBT_Time start ; /* 1|1|0 */ @@ -937,10 +939,10 @@ TempoMap::frame_time (const BBT_Time& bbt) const return count_frames_between ( start, bbt); } -nframes_t -TempoMap::bbt_duration_at (nframes_t pos, const BBT_Time& bbt, int dir) const +nframes64_t +TempoMap::bbt_duration_at (nframes64_t pos, const BBT_Time& bbt, int dir) const { - nframes_t frames = 0; + nframes64_t frames = 0; BBT_Time when; bbt_time(pos, when); @@ -953,11 +955,11 @@ TempoMap::bbt_duration_at (nframes_t pos, const BBT_Time& bbt, int dir) const return frames; } -nframes_t +nframes64_t TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const { - nframes_t frames = 0; + nframes64_t frames = 0; double beats_per_bar; BBT_Time result; @@ -1080,8 +1082,8 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i -nframes_t -TempoMap::round_to_bar (nframes_t fr, int dir) +nframes64_t +TempoMap::round_to_bar (nframes64_t fr, int dir) { { Glib::RWLock::ReaderLock lm (lock); @@ -1090,8 +1092,8 @@ TempoMap::round_to_bar (nframes_t fr, int dir) } -nframes_t -TempoMap::round_to_beat (nframes_t fr, int dir) +nframes64_t +TempoMap::round_to_beat (nframes64_t fr, int dir) { { Glib::RWLock::ReaderLock lm (lock); @@ -1099,8 +1101,8 @@ TempoMap::round_to_beat (nframes_t fr, int dir) } } -nframes_t -TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num, int dir) +nframes64_t +TempoMap::round_to_beat_subdivision (nframes64_t fr, int sub_num, int dir) { BBT_Time the_beat; @@ -1190,59 +1192,117 @@ TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num, int dir) return frame_time (the_beat); } -nframes_t -TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type) +nframes64_t +TempoMap::round_to_type (nframes64_t frame, int dir, BBTPointType type) { TempoMetric metric = metric_at (frame); BBT_Time bbt; BBT_Time start; - bbt_time_with_metric (frame, bbt, metric); + BBT_Time one_bar (1,0,0); + BBT_Time one_beat (0,1,0); + bbt_time_with_metric (frame, bbt, metric); switch (type) { case Bar: DEBUG_TRACE(DEBUG::SnapBBT, string_compose ("round from %1 (%3) to bars in direction %2\n", frame, (dir < 0 ? "back" : "forward"), bbt)); + if (dir < 0) { - if (bbt.bars > 1) { - bbt.bars--; + + /* find bar position preceding frame */ + + try { + bbt = bbt_subtract (bbt, one_bar); } + + catch (...) { + return frame; + } + + } else if (dir > 0) { - if (bbt.beats > 0) { - bbt.bars++; - } else if (metric.frame() < frame) { - bbt.bars++; + + /* find bar position following frame */ + + try { + bbt = bbt_add (bbt, one_bar, metric); } - } else { - if (bbt.beats > metric.meter().beats_per_bar()/2) { - bbt.bars++; + catch (...) { + return frame; } + + } else { + + /* "true" rounding */ + + /* round to nearest beat */ + if (bbt.ticks >= (Meter::ticks_per_beat/2)) { + try { + bbt = bbt_add (bbt, one_beat, metric); + } + catch (...) { + return frame; + } + } + + /* round to nearest bar */ + if (bbt.beats >= metric.meter().beats_per_bar()/2) { + try { + bbt = bbt_add (bbt, one_bar, metric); + } + catch (...) { + return frame; + } + } } + /* force beats & ticks to their values at the start of a bar */ bbt.beats = 1; bbt.ticks = 0; break; case Beat: DEBUG_TRACE(DEBUG::SnapBBT, string_compose ("round from %1 (%3) to beat in direction %2\n", frame, (dir < 0 ? "back" : "forward"), bbt)); + if (dir < 0) { - if (bbt.beats > 1) { - bbt.beats--; - } + + /* find beat position preceding frame */ + + try { + bbt = bbt_subtract (bbt, one_beat); + } + + catch (...) { + return frame; + } + } else if (dir > 0) { - if (bbt.ticks > 0) { - bbt.beats++; - } else if (metric.frame() < frame) { - bbt.beats++; + + /* find beat position following frame */ + + try { + bbt = bbt_add (bbt, one_beat, metric); + } + catch (...) { + return frame; } + } else { + + /* "true" rounding */ + + /* round to nearest beat */ if (bbt.ticks >= (Meter::ticks_per_beat/2)) { - bbt.beats++; + + try { + bbt = bbt_add (bbt, one_beat, metric); + } + catch (...) { + return frame; + } } } - if (bbt.beats > ceil(metric.meter().beats_per_bar()) ) { - bbt.beats = 1; - bbt.bars++; - } + /* force ticks to the value at the start of a beat */ bbt.ticks = 0; break; @@ -1253,7 +1313,7 @@ TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type) } TempoMap::BBTPointList * -TempoMap::get_points (nframes_t lower, nframes_t upper) const +TempoMap::get_points (nframes64_t lower, nframes64_t upper) const { Metrics::const_iterator i; @@ -1272,7 +1332,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const double delta_bars; double delta_beats; double dummy; - nframes_t limit; + nframes64_t limit; meter = &first_meter (); tempo = &first_tempo (); @@ -1349,7 +1409,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const if (beat == 1) { if (current >= lower) { // cerr << "Add Bar at " << bar << "|1" << " @ " << current << endl; - points->push_back (BBTPoint (*meter, *tempo,(nframes_t)rint(current), Bar, bar, 1)); + points->push_back (BBTPoint (*meter, *tempo,(nframes64_t)rint(current), Bar, bar, 1)); } } @@ -1361,7 +1421,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const while (beat <= ceil( beats_per_bar) && beat_frame < limit) { if (beat_frame >= lower) { // cerr << "Add Beat at " << bar << '|' << beat << " @ " << beat_frame << endl; - points->push_back (BBTPoint (*meter, *tempo, (nframes_t) rint(beat_frame), Beat, bar, beat)); + points->push_back (BBTPoint (*meter, *tempo, (nframes64_t) rint(beat_frame), Beat, bar, beat)); } beat_frame += beat_frames; current+= beat_frames; @@ -1442,7 +1502,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const } const TempoSection& -TempoMap::tempo_section_at (nframes_t frame) +TempoMap::tempo_section_at (nframes64_t frame) { Glib::RWLock::ReaderLock lm (lock); Metrics::iterator i; @@ -1469,7 +1529,7 @@ TempoMap::tempo_section_at (nframes_t frame) } const Tempo& -TempoMap::tempo_at (nframes_t frame) const +TempoMap::tempo_at (nframes64_t frame) const { TempoMetric m (metric_at (frame)); return m.tempo(); @@ -1477,7 +1537,7 @@ TempoMap::tempo_at (nframes_t frame) const const Meter& -TempoMap::meter_at (nframes_t frame) const +TempoMap::meter_at (nframes64_t frame) const { TempoMetric m (metric_at (frame)); return m.meter(); @@ -1604,7 +1664,7 @@ TempoMap::n_meters() const } void -TempoMap::insert_time (nframes_t where, nframes_t amount) +TempoMap::insert_time (nframes64_t where, nframes64_t amount) { for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) { if ((*i)->frame() >= where) { @@ -1618,22 +1678,211 @@ TempoMap::insert_time (nframes_t where, nframes_t amount) } BBT_Time -TempoMap::bbt_add (const BBT_Time& a, const BBT_Time& b, const TempoMetric& /*metric*/) +TempoMap::bbt_add (const BBT_Time& start, const BBT_Time& other) const { - // FIXME: Obviously not correct! - return BBT_Time(a.bars + b.bars, a.beats + b.beats, a.ticks + b.ticks); + TempoMetric metric = metric_at (start); + return bbt_add (start, other, metric); } BBT_Time -TempoMap::bbt_add (const BBT_Time& a, const BBT_Time& b) +TempoMap::bbt_add (const BBT_Time& start, const BBT_Time& other, const TempoMetric& metric) const { - // FIXME: Obviously not correct! - return BBT_Time(a.bars + b.bars, a.beats + b.beats, a.ticks + b.ticks); + BBT_Time result = start; + BBT_Time op = op; + uint32_t ticks = result.ticks + op.ticks; + + if (ticks >= Meter::ticks_per_beat) { + op.beats++; + result.ticks = ticks % (uint32_t) Meter::ticks_per_beat; + } + + /* now comes the complicated part. we have to add one beat a time, + checking for a new metric on every beat. + */ + + /* grab all meter sections */ + + list meter_sections; + + for (Metrics::const_iterator x = metrics->begin(); x != metrics->end(); ++x) { + const MeterSection* ms; + if ((ms = dynamic_cast(*x)) != 0) { + meter_sections.push_back (ms); + } + } + + assert (!meter_sections.empty()); + + list::const_iterator next_meter; + const Meter* meter = 0; + + /* go forwards through the meter sections till we get to the one + covering the current value of result. this positions i to point to + the next meter section too, or the end. + */ + + for (next_meter = meter_sections.begin(); next_meter != meter_sections.end(); ++next_meter) { + + if (result < (*next_meter)->start()) { + /* this metric is past the result time. stop looking, we have what we need */ + break; + } + + if (result == (*next_meter)->start()) { + /* this meter section starts at result, push i beyond it so that it points + to the NEXT section, opwise we will get stuck later, and use this meter section. + */ + meter = *next_meter; + ++next_meter; + break; + } + + meter = *next_meter; + } + + assert (meter != 0); + + /* OK, now have the meter for the bar start we are on, and i is an iterator + that points to the metric after the one we are currently dealing with + (or to metrics->end(), of course) + */ + + while (op.beats) { + + /* given the current meter, have we gone past the end of the bar ? */ + + if (result.beats >= meter->beats_per_bar()) { + /* move to next bar, first beat */ + result.bars++; + result.beats = 1; + } else { + result.beats++; + } + + /* one down ... */ + + op.beats--; + + /* check if we need to use a new meter section: has adding beats to result taken us + to or after the start of the next meter section? in which case, use it. + */ + + if (next_meter != meter_sections.end() && (((*next_meter)->start () < result) || (result == (*next_meter)->start()))) { + meter = *next_meter; + ++next_meter; + } + } + + /* finally, add bars */ + + result.bars += op.bars++; + + return result; } BBT_Time -TempoMap::bbt_subtract (const BBT_Time& a, const BBT_Time& b) +TempoMap::bbt_subtract (const BBT_Time& start, const BBT_Time& other) const { - // FIXME: Obviously not correct! - return BBT_Time(a.bars - b.bars, a.beats - b.beats, a.ticks - b.ticks); + BBT_Time result = start; + BBT_Time op = other; + + if (op.ticks > result.ticks) { + /* subtract an extra beat later; meanwhile set ticks to the right "carry" value */ + op.beats++; + result.ticks = Meter::ticks_per_beat - (op.ticks - result.ticks); + } else { + result.ticks -= op.ticks; + } + + /* now comes the complicated part. we have to subtract one beat a time, + checking for a new metric on every beat. + */ + + /* grab all meter sections */ + + list meter_sections; + + for (Metrics::const_iterator x = metrics->begin(); x != metrics->end(); ++x) { + const MeterSection* ms; + if ((ms = dynamic_cast(*x)) != 0) { + meter_sections.push_back (ms); + } + } + + assert (!meter_sections.empty()); + + /* go backwards through the meter sections till we get to the one + covering the current value of result. this positions i to point to + the next (previous) meter section too, or the end. + */ + + const MeterSection* meter = 0; + list::const_reverse_iterator next_meter; + + for (next_meter = meter_sections.rbegin(); next_meter != meter_sections.rend(); ++next_meter) { + + /* when we find the first meter section that is before or at result, use it, + and set next_meter to the previous one + */ + + if ((*next_meter)->start() < result || (*next_meter)->start() == result) { + meter = *next_meter; + ++next_meter; + break; + } + } + + assert (meter != 0); + + /* OK, now have the meter for the bar start we are on, and i is an iterator + that points to the metric after the one we are currently dealing with + (or to metrics->end(), of course) + */ + + while (op.beats) { + + /* have we reached the start of the bar? if so, move to the last beat of the previous + bar. opwise, just step back 1 beat. + */ + + if (result.beats == 1) { + + /* move to previous bar, last beat */ + + if (result.bars <= 1) { + /* i'm sorry dave, i can't do that */ + throw std::out_of_range ("illegal BBT subtraction"); + } + + result.bars--; + result.beats = meter->beats_per_bar(); + } else { + + /* back one beat */ + + result.beats--; + } + + /* one down ... */ + op.beats--; + + /* check if we need to use a new meter section: has subtracting beats to result taken us + to before the start of the current meter section? in which case, use the prior one. + */ + + if (result < meter->start() && next_meter != meter_sections.rend()) { + meter = *next_meter; + ++next_meter; + } + } + + /* finally, subtract bars */ + + if (op.bars >= result.bars) { + /* i'm sorry dave, i can't do that */ + throw std::out_of_range ("illegal BBT subtraction"); + } + + result.bars -= op.bars; + return result; } diff --git a/libs/pbd/locale_guard.cc b/libs/pbd/locale_guard.cc new file mode 100644 index 0000000000..7d6c0708b8 --- /dev/null +++ b/libs/pbd/locale_guard.cc @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "pbd/locale_guard.h" + +using namespace PBD; + +LocaleGuard::LocaleGuard (const char* str) +{ + old = strdup (setlocale (LC_NUMERIC, NULL)); + if (strcmp (old, str)) { + setlocale (LC_NUMERIC, str); + } +} + +LocaleGuard::~LocaleGuard () +{ + setlocale (LC_NUMERIC, old); + free ((char*)old); +} + diff --git a/libs/pbd/pbd/enumwriter.h b/libs/pbd/pbd/enumwriter.h index f53388f3cc..63a8ef6f6e 100644 --- a/libs/pbd/pbd/enumwriter.h +++ b/libs/pbd/pbd/enumwriter.h @@ -18,6 +18,9 @@ $Id$ */ +#ifndef __pbd_enumwriter_h__ +#define __pbd_enumwriter_h__ + #include #include #include @@ -75,3 +78,4 @@ class EnumWriter { #define enum_2_string(e) (PBD::EnumWriter::instance().write (typeid(e).name(), e)) #define string_2_enum(str,e) (PBD::EnumWriter::instance().read (typeid(e).name(), (str))) +#endif /* __pbd_enumwriter_h__ */ diff --git a/libs/pbd/pbd/locale_guard.h b/libs/pbd/pbd/locale_guard.h new file mode 100644 index 0000000000..480cc0fddb --- /dev/null +++ b/libs/pbd/pbd/locale_guard.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2009 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __pbd_locale_guard__ +#define __pbd_locale_guard__ + +namespace PBD { + +struct LocaleGuard { + LocaleGuard (const char*); + ~LocaleGuard (); + const char* old; +}; + +} + +#endif /* __pbd_locale_guard__ */ diff --git a/libs/pbd/wscript b/libs/pbd/wscript index be65a84ac1..5ecaf69643 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -64,6 +64,7 @@ def build(bld): file_utils.cc fpu.cc id.cc + locale_guard.cc malign.cc mountpoint.cc pathscanner.cc diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index b77be7d230..617d09a086 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -294,8 +294,8 @@ class MackieControlProtocol // also called from poll_automation to update timecode display void update_timecode_display(); - std::string format_bbt_timecode( nframes_t now_frame ); - std::string format_timecode_timecode( nframes_t now_frame ); + std::string format_bbt_timecode (ARDOUR::nframes_t now_frame ); + std::string format_timecode_timecode (ARDOUR::nframes_t now_frame ); /** notification that the port is about to start it's init sequence. -- cgit v1.2.3