diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 535b65a195..3e1cf4f648 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -760,6 +760,9 @@ Editor::add_sources (vector paths, SourceList& sources, nframes64 region_name = region_name_from_path ((*x)->path(), false, true, sources.size(), n); + cout << "REGION NAME: " << region_name << endl; + cout << "SOURCE LENGTH: " << (*x)->length() << endl; + regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0, Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 8e7d786722..61b39c9142 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -191,9 +191,9 @@ private: bool is_sorted() const; #endif - void append_note_on_unlocked(double time, uint8_t note, uint8_t velocity); - void append_note_off_unlocked(double time, uint8_t note); - void append_cc_unlocked(double time, uint8_t number, uint8_t value); + void append_note_on_unlocked(uint8_t chan, double time, uint8_t note, uint8_t velocity); + void append_note_off_unlocked(uint8_t chan, double time, uint8_t note); + void append_cc_unlocked(uint8_t chan, double time, uint8_t number, uint8_t value); mutable Glib::RWLock _lock; @@ -201,7 +201,7 @@ private: NoteMode _note_mode; typedef std::vector WriteNotes; - WriteNotes _write_notes; + WriteNotes _write_notes[16]; bool _writing; bool _edited; diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index d4a1bc72e7..b028e1c1a7 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -289,12 +289,6 @@ write_midi_data_to_new_files (SMFReader* source, Session::import_status& status, if (source->read_event(4, ev.buffer(), &size, &delta_t) < 0) break; - // FIXME: kluuudge - if (ev.channel() != 0) { - cout << "Skipping event with channel " << ev.channel() << endl; - continue; - } - t += delta_t; ev.time() = t * (double)source->ppqn(); ev.size() = size; diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 921824c615..7c3bc73fb8 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -304,6 +304,7 @@ MidiDiskstream::set_destructive (bool yn) void MidiDiskstream::set_note_mode (NoteMode m) { + cout << "MDS: SET NOTE MODE: " << m << endl; _note_mode = m; midi_playlist()->set_note_mode(m); if (_write_source && _write_source->model()) diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 51793a4189..b2c7369edd 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -331,7 +331,8 @@ MidiModel::start_write() //cerr << "MM " << this << " START WRITE, MODE = " << enum_2_string(_note_mode) << endl; write_lock(); _writing = true; - _write_notes.clear(); + for (int i = 0; i < 16; ++i) + _write_notes[i].clear(); write_unlock(); } @@ -362,7 +363,14 @@ MidiModel::end_write(bool delete_stuck) } } - _write_notes.clear(); + for (int i = 0; i < 16; ++i) { + if (!_write_notes[i].empty()) { + cerr << "WARNING: MidiModel::end_write: Channel " << i << " has " + << _write_notes[i].size() << " stuck notes" << endl; + } + _write_notes[i].clear(); + } + _writing = false; write_unlock(); } @@ -383,11 +391,11 @@ MidiModel::append(const MidiEvent& ev) assert(_writing); if (ev.is_note_on()) - append_note_on_unlocked(ev.time(), ev.note(), ev.velocity()); + append_note_on_unlocked(ev.channel(), ev.time(), ev.note(), ev.velocity()); else if (ev.is_note_off()) - append_note_off_unlocked(ev.time(), ev.note()); + append_note_off_unlocked(ev.channel(), ev.time(), ev.note()); else if (ev.is_cc()) - append_cc_unlocked(ev.time(), ev.cc_number(), ev.cc_value()); + append_cc_unlocked(ev.channel(), ev.time(), ev.cc_number(), ev.cc_value()); else printf("MM Unknown event type %X\n", ev.type()); @@ -396,32 +404,36 @@ MidiModel::append(const MidiEvent& ev) void -MidiModel::append_note_on_unlocked(double time, uint8_t note_num, uint8_t velocity) +MidiModel::append_note_on_unlocked(uint8_t chan, double time, uint8_t note_num, uint8_t velocity) { - //cerr << "MidiModel " << this << " note " << (int)note_num << " on @ " << time << endl; + /*cerr << "MidiModel " << this << " chan " << (int)chan << + " note " << (int)note_num << " on @ " << time << endl;*/ + assert(chan < 16); assert(_writing); + _notes.push_back(boost::shared_ptr(new Note(time, 0, note_num, velocity))); if (_note_mode == Sustained) { //cerr << "MM Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl; - _write_notes.push_back(_notes.size() - 1); - } else { - //cerr << "MM Percussive: NOT appending active note on" << endl; - } + _write_notes[chan].push_back(_notes.size() - 1); + }/* else { + cerr << "MM Percussive: NOT appending active note on" << endl; + }*/ } void -MidiModel::append_note_off_unlocked(double time, uint8_t note_num) +MidiModel::append_note_off_unlocked(uint8_t chan, double time, uint8_t note_num) { - //cerr << "MidiModel " << this << " note " << (int)note_num << " off @ " << time << endl; + /*cerr << "MidiModel " << this << " chan " << (int)chan << + " note " << (int)note_num << " off @ " << time << endl;*/ + assert(chan < 16); assert(_writing); + if (_note_mode == Percussive) { - //cerr << "MM Ignoring note off (percussive mode)" << endl; + cerr << "MidiModel Ignoring note off (percussive mode)" << endl; return; - } else { - //cerr << "MM Attempting to resolve note off " << (unsigned)(uint8_t)note_num << endl; } /* FIXME: make _write_notes fixed size (127 noted) for speed */ @@ -429,28 +441,42 @@ MidiModel::append_note_off_unlocked(double time, uint8_t note_num) /* FIXME: note off velocity for that one guy out there who actually has * keys that send it */ - for (WriteNotes::iterator n = _write_notes.begin(); n != _write_notes.end(); ++n) { + bool resolved = false; + + for (WriteNotes::iterator n = _write_notes[chan].begin(); n != _write_notes[chan].end(); ++n) { Note& note = *_notes[*n].get(); //cerr << (unsigned)(uint8_t)note.note() << " ? " << (unsigned)note_num << endl; if (note.note() == note_num) { assert(time >= note.time()); note.set_duration(time - note.time()); - _write_notes.erase(n); + _write_notes[chan].erase(n); //cerr << "MM resolved note, duration: " << note.duration() << endl; + resolved = true; break; } } + + if (!resolved) + cerr << "MidiModel " << this << " spurious note off chan " << (int)chan + << ", note " << (int)note_num << " @ " << time << endl; } void -MidiModel::append_cc_unlocked(double time, uint8_t number, uint8_t value) +MidiModel::append_cc_unlocked(uint8_t chan, double time, uint8_t number, uint8_t value) { + /*cerr << "MidiModel " << this << " chan " << (int)chan << + " CC " << (int)number << " = " << (int)value << " @ " << time << endl;*/ + + assert(chan < 16); + assert(_writing); + + if (chan != 0) // FIXME + cerr << "WARNING: CC on non-0 channel, channel information lost!" << endl; + Parameter param(MidiCCAutomation, number); boost::shared_ptr control = Automatable::control(param, true); - //cerr << "MidiModel " << this << "(" << control.get() << ") add CC " << (int)number << " = " << (int)value - // << " @ " << time << endl; control->list()->fast_simple_add(time, (double)value); } diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc index 9720384130..d8e59efd4a 100644 --- a/libs/ardour/midi_playlist.cc +++ b/libs/ardour/midi_playlist.cc @@ -42,6 +42,7 @@ using namespace std; MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) : Playlist (session, node, DataType::MIDI, hidden) + , _note_mode(Sustained) { const XMLProperty* prop = node.property("type"); assert(prop && DataType(prop->value()) == DataType::MIDI); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 8e41df84ef..e1fa109342 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -80,6 +80,7 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo MidiTrack::MidiTrack (Session& sess, const XMLNode& node) : Track (sess, node) , _immediate_events(1024) // FIXME: size? + , _note_mode(Sustained) { _set_state(node, false); @@ -690,6 +691,7 @@ MidiTrack::unfreeze () void MidiTrack::set_note_mode (NoteMode m) { + cout << _name << " SET NOTE MODE " << m << endl; _note_mode = m; midi_diskstream()->set_note_mode(m); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index a7c693fb2d..52cfc093cc 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -130,6 +130,7 @@ Session::Session (AudioEngine &eng, _session_dir (new SessionDirectory(fullpath)), pending_events (2048), //midi_requests (128), // the size of this should match the midi request pool size + post_transport_work((PostTransportWork)0), _send_smpte_update (false), diskstreams (new DiskstreamList), routes (new RouteList), diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 59ad7269db..4903cf384f 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -444,14 +444,14 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) void SMFSource::append_event_unlocked(const MidiEvent& ev) { - /*printf("SMF %s - writing event, time = %lf, size = %u, data = ", _path.c_str(), ev.time(), ev.size()); + printf("%s - append chan = %u, time = %lf, size = %u, data = ", _path.c_str(), + (unsigned)ev.channel(), ev.time(), ev.size()); for (size_t i=0; i < ev.size(); ++i) { printf("%X ", ev.buffer()[i]); } - printf("\n");*/ + printf("\n"); assert(ev.time() >= 0); - assert(ev.time() >= _last_ev_time); // FIXME: assumes tempo never changes after start