summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/SConscript7
-rw-r--r--libs/ardour/ardour/beats_frames_converter.h52
-rw-r--r--libs/ardour/ardour/midi_source.h21
-rw-r--r--libs/ardour/ardour/session.h6
-rw-r--r--libs/ardour/audio_region_importer.cc2
-rw-r--r--libs/ardour/beats_frames_converter.cc54
-rw-r--r--libs/ardour/import.cc24
-rw-r--r--libs/ardour/midi_source.cc22
-rw-r--r--libs/ardour/quantize.cc13
-rw-r--r--libs/ardour/smf_source.cc29
-rw-r--r--libs/evoral/evoral/TimeConverter.hpp43
11 files changed, 203 insertions, 70 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 11a5b36566..83b7d659b5 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -38,6 +38,7 @@ audio_library.cc
audio_playlist.cc
audio_playlist_importer.cc
audio_port.cc
+audio_region_importer.cc
audio_track.cc
audio_track_importer.cc
audioanalyser.cc
@@ -45,13 +46,13 @@ audioengine.cc
audiofile_tagger.cc
audiofilesource.cc
audioregion.cc
-audio_region_importer.cc
audiosource.cc
auditioner.cc
automatable.cc
automation.cc
automation_control.cc
automation_list.cc
+beats_frames_converter.cc
broadcast_info.cc
buffer.cc
buffer_set.cc
@@ -65,8 +66,8 @@ cycle_timer.cc
default_click.cc
directory_names.cc
diskstream.cc
-element_importer.cc
element_import_handler.cc
+element_importer.cc
enums.cc
event_type_map.cc
export_channel.cc
@@ -162,8 +163,8 @@ svn_revision.cc
tape_file_matcher.cc
template_utils.cc
tempo.cc
-ticker.cc
tempo_map_importer.cc
+ticker.cc
track.cc
transient_detector.cc
user_bundle.cc
diff --git a/libs/ardour/ardour/beats_frames_converter.h b/libs/ardour/ardour/beats_frames_converter.h
new file mode 100644
index 0000000000..79972cb4c5
--- /dev/null
+++ b/libs/ardour/ardour/beats_frames_converter.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2009 Paul Davis
+ Author: Dave Robillard
+
+ 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.
+
+ $Id: midiregion.h 733 2006-08-01 17:19:38Z drobilla $
+*/
+
+#include <evoral/TimeConverter.hpp>
+#include <ardour/types.h>
+
+#ifndef __ardour_beats_frames_converter_h__
+#define __ardour_beats_frames_converter_h__
+
+namespace ARDOUR {
+
+class Session;
+
+class BeatsFramesConverter : public Evoral::TimeConverter<double,nframes_t> {
+public:
+ BeatsFramesConverter(Session& session, nframes_t origin)
+ : _session(session)
+ , _origin(origin)
+ {}
+
+ nframes_t to(double beats) const;
+ double from(nframes_t frames) const;
+
+ nframes_t origin() const { return _origin; }
+ void set_origin(nframes_t origin) { _origin = origin; }
+
+private:
+ Session& _session;
+ nframes_t _origin;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_beats_frames_converter_h__ */
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
index 3f8ed82310..3a28cde8c6 100644
--- a/libs/ardour/ardour/midi_source.h
+++ b/libs/ardour/ardour/midi_source.h
@@ -30,8 +30,7 @@
#include <ardour/ardour.h>
#include <ardour/buffer.h>
#include <ardour/source.h>
-
-using std::string;
+#include <ardour/beats_frames_converter.h>
namespace ARDOUR {
@@ -44,7 +43,7 @@ class MidiSource : public Source
public:
typedef double TimeType;
- MidiSource (Session& session, string name);
+ MidiSource (Session& session, std::string name);
MidiSource (Session& session, const XMLNode&);
virtual ~MidiSource ();
@@ -66,13 +65,13 @@ class MidiSource : public Source
virtual void mark_streaming_write_started ();
virtual void mark_streaming_write_completed ();
- uint64_t timeline_position () { return _timeline_position; }
- void set_timeline_position (nframes_t when) { _timeline_position = when; }
+ uint64_t timeline_position () { return _timeline_position; }
+ void set_timeline_position (nframes_t when);
virtual void session_saved();
- string captured_for() const { return _captured_for; }
- void set_captured_for (string str) { _captured_for = str; }
+ std::string captured_for() const { return _captured_for; }
+ void set_captured_for (std::string str) { _captured_for = str; }
uint32_t read_data_count() const { return _read_data_count; }
uint32_t write_data_count() const { return _write_data_count; }
@@ -96,6 +95,8 @@ class MidiSource : public Source
void set_model(boost::shared_ptr<MidiModel> m) { _model = m; }
void drop_model() { _model.reset(); }
+ BeatsFramesConverter& converter() { return _converter; }
+
protected:
virtual void flush_midi() = 0;
@@ -104,10 +105,12 @@ class MidiSource : public Source
virtual nframes_t write_unlocked (MidiRingBuffer<nframes_t>& dst, nframes_t cnt) = 0;
mutable Glib::Mutex _lock;
- string _captured_for;
+ std::string _captured_for;
uint64_t _timeline_position;
mutable uint32_t _read_data_count; ///< modified in read()
mutable uint32_t _write_data_count; ///< modified in write()
+
+ BeatsFramesConverter _converter;
boost::shared_ptr<MidiModel> _model;
bool _writing;
@@ -116,7 +119,7 @@ class MidiSource : public Source
mutable nframes_t _last_read_end;
private:
- bool file_changed (string path);
+ bool file_changed (std::string path);
};
}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 8de0e1c523..ef25ebaea3 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -610,7 +610,7 @@ class Session : public PBD::StatefulDestructible
/* source management */
- struct import_status : public InterThreadInfo {
+ struct ImportStatus : public InterThreadInfo {
string doing_what;
/* control info */
@@ -624,8 +624,8 @@ class Session : public PBD::StatefulDestructible
SourceList sources;
};
- void import_audiofiles (import_status&);
- bool sample_rate_convert (import_status&, string infile, string& outfile);
+ void import_audiofiles (ImportStatus&);
+ bool sample_rate_convert (ImportStatus&, string infile, string& outfile);
string build_tmp_convert_name (string file);
boost::shared_ptr<ExportHandler> get_export_handler ();
diff --git a/libs/ardour/audio_region_importer.cc b/libs/ardour/audio_region_importer.cc
index 714446bfe2..23f3bfd6c6 100644
--- a/libs/ardour/audio_region_importer.cc
+++ b/libs/ardour/audio_region_importer.cc
@@ -336,7 +336,7 @@ AudioRegionImporter::prepare_sources ()
return;
}
- Session::import_status status;
+ Session::ImportStatus status;
// Get sources that still need to be imported
for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
diff --git a/libs/ardour/beats_frames_converter.cc b/libs/ardour/beats_frames_converter.cc
new file mode 100644
index 0000000000..736068e690
--- /dev/null
+++ b/libs/ardour/beats_frames_converter.cc
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2009 Paul Davis
+ Author: Dave Robillard
+
+ 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.
+
+ $Id: midiregion.h 733 2006-08-01 17:19:38Z drobilla $
+*/
+
+#include <ardour/audioengine.h>
+#include <ardour/beats_frames_converter.h>
+#include <ardour/session.h>
+#include <ardour/tempo.h>
+
+namespace ARDOUR {
+
+nframes_t
+BeatsFramesConverter::to(double beats) const
+{
+ // FIXME: assumes tempo never changes after origin
+ const Tempo& tempo = _session.tempo_map().tempo_at(_origin);
+ const double frames_per_beat = tempo.frames_per_beat(
+ _session.engine().frame_rate(),
+ _session.tempo_map().meter_at(_origin));
+
+ return lrint(beats * frames_per_beat);
+}
+
+double
+BeatsFramesConverter::from(nframes_t frames) const
+{
+ // FIXME: assumes tempo never changes after origin
+ const Tempo& tempo = _session.tempo_map().tempo_at(_origin);
+ const double frames_per_beat = tempo.frames_per_beat(
+ _session.engine().frame_rate(),
+ _session.tempo_map().meter_at(_origin));
+
+ return frames / frames_per_beat;
+}
+
+} /* namespace ARDOUR */
+
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 824cdb43f7..0e2cfb9988 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -257,7 +257,7 @@ compose_status_message (const string& path,
}
static void
-write_audio_data_to_new_files (ImportableSource* source, Session::import_status& status,
+write_audio_data_to_new_files (ImportableSource* source, Session::ImportStatus& status,
vector<boost::shared_ptr<Source> >& newfiles)
{
const nframes_t nframes = ResampledImportableSource::blocksize;
@@ -309,8 +309,8 @@ write_audio_data_to_new_files (ImportableSource* source, Session::import_status&
}
static void
-write_midi_data_to_new_files (Evoral::SMF* source, Session::import_status& status,
- vector<boost::shared_ptr<Source> >& newfiles)
+write_midi_data_to_new_files (Evoral::SMF* source, Session::ImportStatus& status,
+ vector<boost::shared_ptr<Source> >& newfiles)
{
uint32_t buf_size = 4;
uint8_t* buf = (uint8_t*)malloc(buf_size);
@@ -354,20 +354,14 @@ write_midi_data_to_new_files (Evoral::SMF* source, Session::import_status& statu
if (status.progress < 0.99)
status.progress += 0.01;
}
-
- nframes_t timeline_position = 0; // FIXME: ?
- // FIXME: kluuuuudge: assumes tempo never changes after start
- const double frames_per_beat = smfs->session().tempo_map().tempo_at(
- timeline_position).frames_per_beat(
- smfs->session().engine().frame_rate(),
- smfs->session().tempo_map().meter_at(timeline_position));
-
- smfs->update_length(0, (nframes_t) ceil ((t / (double)source->ppqn()) * frames_per_beat));
+ const double length_beats = ceil(t / (double)source->ppqn());
+ smfs->update_length(0, smfs->converter().to(length_beats));
smfs->end_write();
- if (status.cancel)
+ if (status.cancel) {
break;
+ }
}
} catch (...) {
@@ -382,11 +376,11 @@ remove_file_source (boost::shared_ptr<Source> source)
}
// This function is still unable to cleanly update an existing source, even though
-// it is possible to set the import_status flag accordingly. The functinality
+// it is possible to set the ImportStatus flag accordingly. The functinality
// is disabled at the GUI until the Source implementations are able to provide
// the necessary API.
void
-Session::import_audiofiles (import_status& status)
+Session::import_audiofiles (ImportStatus& status)
{
uint32_t cnt = 1;
typedef vector<boost::shared_ptr<Source> > Sources;
diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc
index 70abb99e56..ece0d9b104 100644
--- a/libs/ardour/midi_source.cc
+++ b/libs/ardour/midi_source.cc
@@ -52,16 +52,20 @@ sigc::signal<void,MidiSource *> MidiSource::MidiSourceCreated;
MidiSource::MidiSource (Session& s, string name)
: Source (s, name, DataType::MIDI)
, _timeline_position(0)
+ , _read_data_count(0)
+ , _write_data_count(0)
+ , _converter(s, _timeline_position)
, _writing (false)
, _last_read_end(0)
{
- _read_data_count = 0;
- _write_data_count = 0;
}
MidiSource::MidiSource (Session& s, const XMLNode& node)
: Source (s, node)
, _timeline_position(0)
+ , _read_data_count(0)
+ , _write_data_count(0)
+ , _converter(s, _timeline_position)
, _writing (false)
, _last_read_end(0)
{
@@ -110,12 +114,7 @@ MidiSource::midi_read (MidiRingBuffer<nframes_t>& dst, nframes_t start, nframes_
Glib::Mutex::Lock lm (_lock);
if (_model) {
- // FIXME: assumes tempo never changes after start
- const Tempo& tempo = _session.tempo_map().tempo_at(_timeline_position);
- const double frames_per_beat = tempo.frames_per_beat(
- _session.engine().frame_rate(),
- _session.tempo_map().meter_at(_timeline_position));
-#define BEATS_TO_FRAMES(t) (((t) * frames_per_beat) + stamp_offset - negative_stamp_offset)
+#define BEATS_TO_FRAMES(t) (_converter.to(t) + stamp_offset - negative_stamp_offset)
Evoral::Sequence<double>::const_iterator& i = _model_iter;
@@ -162,6 +161,13 @@ MidiSource::file_changed (string path)
}
void
+MidiSource::set_timeline_position (nframes_t when)
+{
+ _timeline_position = when;
+ _converter.set_origin(when);
+}
+
+void
MidiSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame)
{
set_timeline_position(start_frame); // why do I have a feeling this can break somehow...
diff --git a/libs/ardour/quantize.cc b/libs/ardour/quantize.cc
index e4a2809277..76eb924612 100644
--- a/libs/ardour/quantize.cc
+++ b/libs/ardour/quantize.cc
@@ -62,19 +62,12 @@ Quantize::run (boost::shared_ptr<Region> r)
boost::shared_ptr<MidiModel> model = src->model();
- // FIXME: Model really needs to be switched to beat time (double) ASAP
-
- const Tempo& t = session.tempo_map().tempo_at(r->start());
- const Meter& m = session.tempo_map().meter_at(r->start());
-
- double q_frames = _q * (m.frames_per_bar(t, session.frame_rate()) / (double)m.beats_per_bar());
-
for (Evoral::Sequence<MidiModel::TimeType>::Notes::iterator i = model->notes().begin();
i != model->notes().end(); ++i) {
- const double new_time = lrint((*i)->time() / q_frames) * q_frames;
- double new_dur = lrint((*i)->length() / q_frames) * q_frames;
+ const double new_time = lrint((*i)->time() / _q) * _q;
+ double new_dur = lrint((*i)->length() / _q) * _q;
if (new_dur == 0.0)
- new_dur = q_frames;
+ new_dur = _q;
(*i)->set_time(new_time);
(*i)->set_length(new_dur);
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 5fd09ef1bb..ab0c290191 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -41,7 +41,6 @@
#include <ardour/midi_ring_buffer.h>
#include <ardour/session.h>
#include <ardour/smf_source.h>
-#include <ardour/tempo.h>
#include "i18n.h"
@@ -145,13 +144,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& dst, nframes_t start, nfram
size_t scratch_size = 0; // keep track of scratch to minimize reallocs
- // FIXME: assumes tempo never changes after start
- const Tempo& tempo = _session.tempo_map().tempo_at(_timeline_position);
- const double frames_per_beat = tempo.frames_per_beat(
- _session.engine().frame_rate(),
- _session.tempo_map().meter_at(_timeline_position));
-
- const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * ppqn());
+ const uint64_t start_ticks = (uint64_t)(_converter.from(start) * ppqn());
if (_last_read_end == 0 || start != _last_read_end) {
cerr << "SMFSource::read_unlocked seeking to " << start << endl;
@@ -183,8 +176,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& dst, nframes_t start, nfram
ev_type = EventTypeMap::instance().midi_event_type(ev_buffer[0]);
assert(time >= start_ticks);
- const nframes_t ev_frame_time = (nframes_t)(
- ((time / (double)ppqn()) * frames_per_beat)) + stamp_offset;
+ const nframes_t ev_frame_time = _converter.to(time / (double)ppqn()) + stamp_offset;
if (ev_frame_time < start + dur) {
dst.write(ev_frame_time - negative_stamp_offset, ev_type, ev_size, ev_buffer);
@@ -323,24 +315,19 @@ SMFSource::append_event_unlocked_frames(const Evoral::Event<nframes_t>& ev)
return;
}
- // FIXME: assumes tempo never changes after start
- const Tempo& tempo = _session.tempo_map().tempo_at(_timeline_position);
- const double frames_per_beat = tempo.frames_per_beat(
- _session.engine().frame_rate(),
- _session.tempo_map().meter_at(_timeline_position));
-
- uint32_t delta_time = (uint32_t)((ev.time() - _last_ev_time_frames)
- / frames_per_beat * (double)ppqn());
+ const nframes_t delta_time_frames = ev.time() - _last_ev_time_frames;
+ const double delta_time_beats = _converter.from(delta_time_frames);
+ const uint32_t delta_time_ticks = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
- Evoral::SMF::append_event_delta(delta_time, ev.size(), ev.buffer());
+ Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer());
_last_ev_time_frames = ev.time();
_write_data_count += ev.size();
if (_model) {
- double beat_time = ev.time() / frames_per_beat;
+ const double ev_time_beats = _converter.from(ev.time());
const Evoral::Event<double> beat_ev(
- ev.event_type(), beat_time, ev.size(), (uint8_t*)ev.buffer());
+ ev.event_type(), ev_time_beats, ev.size(), (uint8_t*)ev.buffer());
_model->append(beat_ev);
}
}
diff --git a/libs/evoral/evoral/TimeConverter.hpp b/libs/evoral/evoral/TimeConverter.hpp
new file mode 100644
index 0000000000..3f434d9dd7
--- /dev/null
+++ b/libs/evoral/evoral/TimeConverter.hpp
@@ -0,0 +1,43 @@
+/* This file is part of Evoral.
+ * Copyright (C) 2009 Dave Robillard <http://drobilla.net>
+ * Copyright (C) 2009 Paul Davis
+ *
+ * Evoral 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.
+ *
+ * Evoral 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 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef EVORAL_TIME_CONVERTER_HPP
+#define EVORAL_TIME_CONVERTER_HPP
+
+namespace Evoral {
+
+/** A bidirectional converter between two different time units.
+ *
+ * Think of the conversion method names as if they are written in-between
+ * the two template parameters (i.e. "A <name> B").
+ */
+template<typename A, typename B>
+class TimeConverter {
+public:
+ virtual ~TimeConverter() {}
+
+ /** Convert A time to B time (A to B) */
+ virtual B to(A a) const = 0;
+
+ /** Convert B time to A time (A from B) */
+ virtual A from(B b) const = 0;
+};
+
+} // namespace Evoral
+
+#endif // EVORAL_TIME_CONVERTER_HPP