diff options
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 13 | ||||
-rw-r--r-- | gtk2_ardour/streamview.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/time_axis_view.cc | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/directory_names.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/session_directory.h | 7 | ||||
-rw-r--r-- | libs/ardour/ardour/smf_source.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/tempo.h | 2 | ||||
-rw-r--r-- | libs/ardour/directory_names.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session_directory.cc | 13 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 27 | ||||
-rw-r--r-- | libs/ardour/smf_source.cc | 44 |
12 files changed, 96 insertions, 21 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index c3a7e1830d..2282752b6e 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -87,13 +87,14 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd) set_colors (); - boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion> (_region); - mr->midi_source(0)->load_model(); + if (wfd) { + midi_region()->midi_source(0)->load_model(); - begin_write(); - for (size_t i=0; i < mr->midi_source(0)->model().n_events(); ++i) - add_event(mr->midi_source(0)->model().event_at(i)); - end_write(); + begin_write(); + for (size_t i=0; i < midi_region()->midi_source(0)->model().n_events(); ++i) + add_event(midi_region()->midi_source(0)->model().event_at(i)); + end_write(); + } } MidiRegionView::~MidiRegionView () diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index 2997661848..34b0238769 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -57,6 +57,8 @@ StreamView::StreamView (RouteTimeAxisView& tv) , region_color(_trackview.color()) , stream_base_color(0xFFFFFFFF) , layers(1) + , height(tv.height) + , layer_display(Overlaid) , last_rec_data_frame(0) { /* set_position() will position the group */ diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 1351ef9105..fdacf1178b 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -71,6 +71,8 @@ bool TimeAxisView::need_size_info = true; TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisView* rent, Canvas& canvas) : AxisView (sess), editor (ed), + y_position(0), + order(0), controls_table (2, 8) { if (need_size_info) { diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h index ff327e6ad9..c0f1831718 100644 --- a/libs/ardour/ardour/directory_names.h +++ b/libs/ardour/ardour/directory_names.h @@ -8,6 +8,7 @@ namespace ARDOUR { extern const char* const old_sound_dir_name; extern const char* const sound_dir_name; +extern const char* const midi_dir_name; extern const char* const dead_sound_dir_name; extern const char* const interchange_dir_name; extern const char* const peak_dir_name; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 80362e45b5..6cf7f9530b 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -256,6 +256,7 @@ class Session : public PBD::StatefulDestructible sigc::signal<void> DirtyChanged; std::string sound_dir (bool with_path = true) const; + std::string midi_dir (bool with_path = true) const; std::string peak_dir () const; std::string dead_sound_dir () const; std::string automation_dir () const; diff --git a/libs/ardour/ardour/session_directory.h b/libs/ardour/ardour/session_directory.h index d23c135e0b..7662894042 100644 --- a/libs/ardour/ardour/session_directory.h +++ b/libs/ardour/ardour/session_directory.h @@ -53,6 +53,13 @@ public: * of root_path()/interchange/session_name/audiofiles */ const path sound_path () const; + + /** + * @return the absolute path to the directory in which + * the session stores MIDI files, ie + * root_path()/interchange/session_name/midifiles + */ + const path midi_path () const; /** * @return The absolute path to the directory in which all diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h index ed1a0edb76..b4a0ada555 100644 --- a/libs/ardour/ardour/smf_source.h +++ b/libs/ardour/ardour/smf_source.h @@ -91,6 +91,8 @@ class SMFSource : public MidiSource { void load_model(bool lock=true); void destroy_model(); + uint16_t ppqn() const { return _ppqn; } + private: int init (string idstr, bool must_exist); @@ -110,6 +112,8 @@ class SMFSource : public MidiSource { uint32_t read_var_len() const; int read_event(MidiEvent& ev) const; + static const uint16_t _ppqn = 19200; + uint16_t _channel; string _path; Flag _flags; diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 5e3e93e48b..2d8462a751 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -195,7 +195,7 @@ class TempoMap : public PBD::StatefulDestructible BBTPointList *get_points (nframes_t start, nframes_t end) const; - void bbt_time (nframes_t when, BBT_Time&) 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; diff --git a/libs/ardour/directory_names.cc b/libs/ardour/directory_names.cc index 82f420a144..becef7c519 100644 --- a/libs/ardour/directory_names.cc +++ b/libs/ardour/directory_names.cc @@ -6,6 +6,7 @@ namespace ARDOUR { const char* const old_sound_dir_name = X_("sounds"); const char* const sound_dir_name = X_("audiofiles"); +const char* const midi_dir_name = X_("audiofiles"); const char* const peak_dir_name = X_("peaks"); const char* const dead_sound_dir_name = X_("dead_sounds"); const char* const interchange_dir_name = X_("interchange"); diff --git a/libs/ardour/session_directory.cc b/libs/ardour/session_directory.cc index 91b2587eb7..4a9ff1b988 100644 --- a/libs/ardour/session_directory.cc +++ b/libs/ardour/session_directory.cc @@ -106,6 +106,19 @@ SessionDirectory::sound_path () const } const path +SessionDirectory::midi_path () const +{ + // the new style sound directory + path l_midi_path(m_root_path); + + l_midi_path /= interchange_dir_name; + l_midi_path /= basename(m_root_path); + l_midi_path /= midi_dir_name; + + return l_midi_path; +} + +const path SessionDirectory::peak_path () const { return path(m_root_path) /= peak_dir_name; diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 285e3fd4c4..7f53f9c5b1 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2037,6 +2037,33 @@ Session::sound_dir (bool with_path) const } string +Session::midi_dir (bool with_path) const +{ + string res; + string full; + + if (with_path) { + res = _path; + } else { + full = _path; + } + + res += interchange_dir_name; + res += '/'; + res += legalize_for_path (_name); + res += '/'; + res += midi_dir_name; + + if (with_path) { + full = res; + } else { + full += res; + } + + return res; +} + +string Session::peak_dir () const { string res = _path; diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index e48e89a6e5..0bc02f3998 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -36,6 +36,8 @@ #include <ardour/session.h> #include <ardour/midi_ring_buffer.h> #include <ardour/midi_util.h> +#include <ardour/tempo.h> +#include <ardour/audioengine.h> #include "i18n.h" @@ -178,9 +180,9 @@ SMFSource::flush_header () assert(_fd); - const uint16_t type = GUINT16_TO_BE(0); // SMF Type 0 (single track) - const uint16_t ntracks = GUINT16_TO_BE(1); // Number of tracks (always 1 for Type 0) - const uint16_t division = GUINT16_TO_BE(1920); // FIXME FIXME FIXME PPQN + const uint16_t type = GUINT16_TO_BE(0); // SMF Type 0 (single track) + const uint16_t ntracks = GUINT16_TO_BE(1); // Number of tracks (always 1 for Type 0) + const uint16_t division = GUINT16_TO_BE(_ppqn); // Pulses per beat char data[6]; memcpy(data, &type, 2); @@ -241,8 +243,8 @@ SMFSource::find_first_event_after(nframes_t start) * * File position MUST be at the beginning of a delta time, or this will die very messily. * ev.buffer must be of size ev.size, and large enough for the event. The returned event - * will have it's time field set to it's delta time (so it's the caller's responsibility - * to calculate a real time for the event). + * will have it's time field set to it's delta time, in SMF tempo-based ticks, using the + * rate given by ppqn() (it is the caller's responsibility to calculate a real time). * * Returns event length (including status byte) on success, 0 if event was * skipped (eg a meta event), or -1 on EOF (or end of track). @@ -287,12 +289,14 @@ SMFSource::read_event(MidiEvent& ev) const return ev.size; } +/** All stamps in audio frames */ nframes_t SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const { //cerr << "SMF - read " << start << ", count=" << cnt << ", offset=" << stamp_offset << endl; - nframes_t time = 0; + // 64 bits ought to be enough for anybody + uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn _read_data_count = 0; @@ -307,6 +311,12 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n fseek(_fd, _header_size, 0); + // FIXME: assumes tempo never changes after start + const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( + _session.engine().frame_rate()); + + uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * _ppqn); + while (!feof(_fd)) { int ret = read_event(ev); if (ret == -1) { // EOF @@ -323,11 +333,12 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n time += ev.time; // accumulate delta time ev.time = time; // set ev.time to actual time (relative to source start) - if (ev.time >= start) { - if (ev.time > start + cnt) { + if (ev.time >= start_ticks) { + if (ev.time < start_ticks + (cnt / frames_per_beat)) { break; } else { - ev.time += stamp_offset; + ev.time = (nframes_t)(((ev.time / (double)_ppqn) * frames_per_beat)) + stamp_offset; + // write event time in absolute frames dst.write(ev.time, ev.size, ev.buffer); } } @@ -338,6 +349,7 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n return cnt; } +/** All stamps in audio frames */ nframes_t SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) { @@ -349,13 +361,16 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) fseek(_fd, 0, SEEK_END); - // FIXME: start of source time? + // FIXME: assumes tempo never changes after start + const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( + _session.engine().frame_rate()); for (size_t i=0; i < buf.size(); ++i) { MidiEvent& ev = buf[i]; assert(ev.time >= _timeline_position); ev.time -= _timeline_position; - uint32_t delta_time = ev.time - _last_ev_time; + assert(ev.time >= _last_ev_time); + const uint32_t delta_time = (uint32_t)(ev.time - _last_ev_time) / frames_per_beat * _ppqn; /*printf("SMF - writing event, delta = %u, size = %zu, data = ", delta_time, ev.size); @@ -366,10 +381,11 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) */ size_t stamp_size = write_var_len(delta_time); fwrite(ev.buffer, 1, ev.size, _fd); - _last_ev_time += delta_time; - _track_size += stamp_size + ev.size; + _track_size += stamp_size + ev.size; _write_data_count += ev.size; + + _last_ev_time = ev.time; } fflush(_fd); @@ -765,7 +781,7 @@ SMFSource::load_model(bool lock) fseek(_fd, _header_size, 0); - nframes_t time = 0; + double time = 0; MidiEvent ev; int ret; |