mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
Fix timing on MIDI import.
git-svn-id: svn://localhost/ardour2/branches/3.0@3093 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
68bfed0a46
commit
0d0bd81a75
8 changed files with 31 additions and 18 deletions
|
|
@ -909,10 +909,7 @@ SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool&
|
|||
} else if (SMFSource::safe_file_extension (*i)) {
|
||||
SMFReader reader(*i);
|
||||
if (reader.num_tracks() > 1) {
|
||||
cout << *i << " MULTI CHANNEL" << endl;
|
||||
multichannel = true;
|
||||
} else {
|
||||
cout << *i << " SINGLE CHANNEL" << endl;
|
||||
multichannel = true; // "channel" == track here...
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ typedef std::pair<boost::shared_ptr<const AutomationList>, std::pair<double,doub
|
|||
* note events (ie with a start time and a duration) rather than separate
|
||||
* note on and off events (controller data is not here since it's represented
|
||||
* as an AutomationList)
|
||||
*
|
||||
* FIXME: Currently this stores event time stamps in frames. This is almost
|
||||
* certainly wrong, or at least wrong most of the time (if we add an option).
|
||||
* This reeeeeeally needs fixing, but frame time runs deep in Ardour...
|
||||
*/
|
||||
class MidiModel : public boost::noncopyable, public Automatable {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class MidiSource : public Source
|
|||
virtual nframes_t midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset) const;
|
||||
virtual nframes_t midi_write (MidiRingBuffer& src, nframes_t cnt);
|
||||
|
||||
virtual void append_event_unlocked(const MidiEvent& ev) = 0;
|
||||
virtual void append_event_unlocked(EventTimeUnit unit, const MidiEvent& ev) = 0;
|
||||
|
||||
virtual void mark_for_remove() = 0;
|
||||
virtual void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class SMFSource : public MidiSource {
|
|||
void set_allow_remove_if_empty (bool yn);
|
||||
void mark_for_remove();
|
||||
|
||||
void append_event_unlocked(const MidiEvent& ev);
|
||||
void append_event_unlocked(EventTimeUnit unit, const MidiEvent& ev);
|
||||
|
||||
int flush_header ();
|
||||
int flush_footer ();
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@ namespace ARDOUR {
|
|||
Percussive
|
||||
};
|
||||
|
||||
enum EventTimeUnit {
|
||||
Frames,
|
||||
Beats
|
||||
};
|
||||
|
||||
struct BBT_Time {
|
||||
uint32_t bars;
|
||||
uint32_t beats;
|
||||
|
|
|
|||
|
|
@ -290,10 +290,10 @@ write_midi_data_to_new_files (SMFReader* source, Session::import_status& status,
|
|||
break;
|
||||
|
||||
t += delta_t;
|
||||
ev.time() = t * (double)source->ppqn();
|
||||
ev.time() = (double)t / (double)source->ppqn();
|
||||
ev.size() = size;
|
||||
|
||||
smfs->append_event_unlocked(ev);
|
||||
smfs->append_event_unlocked(Beats, ev);
|
||||
if (status.progress < 0.99)
|
||||
status.progress += 0.01;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
|||
const boost::shared_ptr<const Note> earliest_off = active_notes.top();
|
||||
const MidiEvent& off_ev = earliest_off->off_event();
|
||||
if (off_ev.time() <= (*n)->time()) {
|
||||
source->append_event_unlocked(off_ev);
|
||||
source->append_event_unlocked(Frames, off_ev);
|
||||
active_notes.pop();
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -668,14 +668,14 @@ MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
|||
}
|
||||
|
||||
// Write this note on
|
||||
source->append_event_unlocked((*n)->on_event());
|
||||
source->append_event_unlocked(Frames, (*n)->on_event());
|
||||
if ((*n)->duration() > 0)
|
||||
active_notes.push(*n);
|
||||
}
|
||||
|
||||
// Write any trailing note offs
|
||||
while ( ! active_notes.empty() ) {
|
||||
source->append_event_unlocked(active_notes.top()->off_event());
|
||||
source->append_event_unlocked(Frames, active_notes.top()->off_event());
|
||||
active_notes.pop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
|||
time -= _timeline_position;
|
||||
|
||||
const MidiEvent ev(time, size, buf);
|
||||
append_event_unlocked(ev);
|
||||
append_event_unlocked(Frames, ev);
|
||||
|
||||
if (_model)
|
||||
_model->append(ev);
|
||||
|
|
@ -454,7 +454,7 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
|||
|
||||
|
||||
void
|
||||
SMFSource::append_event_unlocked(const MidiEvent& ev)
|
||||
SMFSource::append_event_unlocked(EventTimeUnit unit, const MidiEvent& ev)
|
||||
{
|
||||
/*printf("%s - append chan = %u, time = %lf, size = %u, data = ", _path.c_str(),
|
||||
(unsigned)ev.channel(), ev.time(), ev.size());
|
||||
|
|
@ -466,12 +466,19 @@ SMFSource::append_event_unlocked(const MidiEvent& ev)
|
|||
assert(ev.time() >= 0);
|
||||
assert(ev.time() >= _last_ev_time);
|
||||
|
||||
uint32_t delta_time = 0;
|
||||
|
||||
if (unit == Frames) {
|
||||
// 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(),
|
||||
_session.tempo_map().meter_at(_timeline_position));
|
||||
|
||||
const uint32_t delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn);
|
||||
delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn);
|
||||
} else {
|
||||
assert(unit == Beats);
|
||||
delta_time = (uint32_t)((ev.time() - _last_ev_time) * _ppqn);
|
||||
}
|
||||
|
||||
const size_t stamp_size = write_var_len(delta_time);
|
||||
fwrite(ev.buffer(), 1, ev.size(), _fd);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue