mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
Comment out excessive terminal output.
Write all events (not just notes) to SMF file from MidiModel (just use iterator instead of hand-hacked MidiModel::write_to). Various MIDI bug fixes. git-svn-id: svn://localhost/ardour2/branches/3.0@3312 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
d2465f311f
commit
e55e3fde7c
10 changed files with 76 additions and 121 deletions
|
|
@ -623,7 +623,7 @@ AutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEvent
|
||||||
bool
|
bool
|
||||||
AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
AutomationTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
|
||||||
{
|
{
|
||||||
return cut_copy_clear_one (*_line, selection, op);
|
return (_line ? cut_copy_clear_one (*_line, selection, op) : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public:
|
||||||
*/
|
*/
|
||||||
class MidiModel : public boost::noncopyable, public Automatable {
|
class MidiModel : public boost::noncopyable, public Automatable {
|
||||||
public:
|
public:
|
||||||
MidiModel(MidiSource *s, size_t size=0);
|
MidiModel(MidiSource* s, size_t size=0);
|
||||||
|
|
||||||
void write_lock();
|
void write_lock();
|
||||||
void write_unlock();
|
void write_unlock();
|
||||||
|
|
@ -91,7 +91,6 @@ public:
|
||||||
inline size_t n_notes() const { return _notes.size(); }
|
inline size_t n_notes() const { return _notes.size(); }
|
||||||
inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
|
inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
|
||||||
|
|
||||||
|
|
||||||
inline static bool note_time_comparator (const boost::shared_ptr<const Note> a,
|
inline static bool note_time_comparator (const boost::shared_ptr<const Note> a,
|
||||||
const boost::shared_ptr<const Note> b) {
|
const boost::shared_ptr<const Note> b) {
|
||||||
return a->time() < b->time();
|
return a->time() < b->time();
|
||||||
|
|
@ -149,7 +148,8 @@ public:
|
||||||
void set_edited(bool yn) { _edited = yn; }
|
void set_edited(bool yn) { _edited = yn; }
|
||||||
bool write_to(boost::shared_ptr<MidiSource> source);
|
bool write_to(boost::shared_ptr<MidiSource> source);
|
||||||
|
|
||||||
// MidiModel doesn't use the normal AutomationList serialisation code, as CC data is in the .mid
|
// MidiModel doesn't use the normal AutomationList serialisation code
|
||||||
|
// since controller data is stored in the .mid
|
||||||
XMLNode& get_state();
|
XMLNode& get_state();
|
||||||
int set_state(const XMLNode&) { return 0; }
|
int set_state(const XMLNode&) { return 0; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ class SMFSource : public MidiSource {
|
||||||
bool writable() const { return _flags & Writable; }
|
bool writable() const { return _flags & Writable; }
|
||||||
|
|
||||||
int open();
|
int open();
|
||||||
|
void close();
|
||||||
void seek_to_end();
|
void seek_to_end();
|
||||||
void write_footer();
|
void write_footer();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ class SndFileSource : public AudioFileSource {
|
||||||
|
|
||||||
void init ();
|
void init ();
|
||||||
int open();
|
int open();
|
||||||
void close();
|
|
||||||
int setup_broadcast_info (nframes_t when, struct tm&, time_t);
|
int setup_broadcast_info (nframes_t when, struct tm&, time_t);
|
||||||
|
|
||||||
/* destructive */
|
/* destructive */
|
||||||
|
|
|
||||||
|
|
@ -556,7 +556,7 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
|
||||||
{
|
{
|
||||||
Port* newport = 0;
|
Port* newport = 0;
|
||||||
|
|
||||||
cerr << "trying to register port with name " << portname << endl;
|
/*cerr << "trying to register port with name " << portname << endl;*/
|
||||||
try {
|
try {
|
||||||
if (dtype == DataType::AUDIO) {
|
if (dtype == DataType::AUDIO) {
|
||||||
newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle());
|
newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle());
|
||||||
|
|
@ -566,16 +566,16 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
|
||||||
throw unknown_type();
|
throw unknown_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "successfully got port " << portname << " with address " << newport << endl;
|
/*cerr << "successfully got port " << portname << " with address " << newport << endl;*/
|
||||||
|
|
||||||
RCUWriter<Ports> writer (ports);
|
RCUWriter<Ports> writer (ports);
|
||||||
boost::shared_ptr<Ports> ps = writer.get_copy ();
|
boost::shared_ptr<Ports> ps = writer.get_copy ();
|
||||||
cerr << "Address of ports list: " << ps << endl
|
/*cerr << "Address of ports list: " << ps << endl
|
||||||
<< "Ports set size before insert: " << ps->size() << endl;
|
<< "Ports set size before insert: " << ps->size() << endl;*/
|
||||||
ps->insert (ps->begin(), newport);
|
ps->insert (ps->begin(), newport);
|
||||||
cerr << "Ports set size after insert: " << ps->size() << endl;
|
/*cerr << "Ports set size after insert: " << ps->size() << endl;*/
|
||||||
/* writer goes out of scope, forces update */
|
|
||||||
|
|
||||||
|
/* writer goes out of scope, forces update */
|
||||||
|
|
||||||
return newport;
|
return newport;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1436,10 +1436,6 @@ AutomationList::get_state ()
|
||||||
XMLNode&
|
XMLNode&
|
||||||
AutomationList::state (bool full)
|
AutomationList::state (bool full)
|
||||||
{
|
{
|
||||||
cerr << "getting ";
|
|
||||||
if(full)
|
|
||||||
cerr << "full ";
|
|
||||||
cerr << "state for AutomationList " << _parameter.to_string() << " list size: " << size() << endl;
|
|
||||||
XMLNode* root = new XMLNode (X_("AutomationList"));
|
XMLNode* root = new XMLNode (X_("AutomationList"));
|
||||||
char buf[64];
|
char buf[64];
|
||||||
LocaleGuard lg (X_("POSIX"));
|
LocaleGuard lg (X_("POSIX"));
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ MidiModel::const_iterator::const_iterator(const MidiModel& model, double t)
|
||||||
_locked = false;
|
_locked = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("MIDI Iterator = %X @ %lf\n", _event.type(), _event.time());
|
//printf("New MIDI Iterator = %X @ %lf\n", _event.type(), _event.time());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ const MidiModel::const_iterator& MidiModel::const_iterator::operator++()
|
||||||
assert((_event.is_note() || _event.is_cc() || _event.is_pgm_change() || _event.is_pitch_bender() || _event.is_channel_aftertouch()));
|
assert((_event.is_note() || _event.is_cc() || _event.is_pgm_change() || _event.is_pitch_bender() || _event.is_channel_aftertouch()));
|
||||||
|
|
||||||
// Increment past current control event
|
// Increment past current control event
|
||||||
if (_control_iter != _control_iters.end() && _control_iter->automation_list && _event.is_cc()) {
|
if (!_event.is_note() && _control_iter != _control_iters.end() && _control_iter->automation_list) {
|
||||||
double x, y;
|
double x, y;
|
||||||
cerr << "control_iter x:" << _control_iter->x << " y:" << _control_iter->y << endl;
|
cerr << "control_iter x:" << _control_iter->x << " y:" << _control_iter->y << endl;
|
||||||
const bool ret = _control_iter->automation_list->rt_safe_earliest_event_unlocked(
|
const bool ret = _control_iter->automation_list->rt_safe_earliest_event_unlocked(
|
||||||
|
|
@ -212,24 +212,24 @@ const MidiModel::const_iterator& MidiModel::const_iterator::operator++()
|
||||||
// Use the next earliest controller iff it's earlier than the note event
|
// Use the next earliest controller iff it's earlier than the note event
|
||||||
if (_control_iter != _control_iters.end()
|
if (_control_iter != _control_iters.end()
|
||||||
&& _control_iter->x != DBL_MAX
|
&& _control_iter->x != DBL_MAX
|
||||||
&& _control_iter != old_control_iter)
|
)//&& _control_iter != old_control_iter)
|
||||||
if (type == NIL || _control_iter->x < t)
|
if (type == NIL || _control_iter->x < t)
|
||||||
type = AUTOMATION;
|
type = AUTOMATION;
|
||||||
|
|
||||||
if (type == NOTE_ON) {
|
if (type == NOTE_ON) {
|
||||||
cerr << "********** MIDI Iterator = note on" << endl;
|
//cerr << "********** MIDI Iterator = note on" << endl;
|
||||||
_event = MIDI::Event((*_note_iter)->on_event(), false);
|
_event = MIDI::Event((*_note_iter)->on_event(), false);
|
||||||
_active_notes.push(*_note_iter);
|
_active_notes.push(*_note_iter);
|
||||||
++_note_iter;
|
++_note_iter;
|
||||||
} else if (type == NOTE_OFF) {
|
} else if (type == NOTE_OFF) {
|
||||||
cerr << "********** MIDI Iterator = note off" << endl;
|
//cerr << "********** MIDI Iterator = note off" << endl;
|
||||||
_event = MIDI::Event(_active_notes.top()->off_event(), false);
|
_event = MIDI::Event(_active_notes.top()->off_event(), false);
|
||||||
_active_notes.pop();
|
_active_notes.pop();
|
||||||
} else if (type == AUTOMATION) {
|
} else if (type == AUTOMATION) {
|
||||||
cerr << "********** MIDI Iterator = AUTOMATION" << endl;
|
//cerr << "********** MIDI Iterator = Automation" << endl;
|
||||||
_model->control_to_midi_event(_event, *_control_iter);
|
_model->control_to_midi_event(_event, *_control_iter);
|
||||||
} else {
|
} else {
|
||||||
cerr << "********** MIDI Iterator = END" << endl;
|
//cerr << "********** MIDI Iterator = End" << endl;
|
||||||
_is_end = true;
|
_is_end = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +483,8 @@ void MidiModel::append(const MIDI::Event& ev)
|
||||||
write_lock();
|
write_lock();
|
||||||
_edited = true;
|
_edited = true;
|
||||||
|
|
||||||
cerr << "MidiModel::append event type: " << hex << "0x" << int(ev.type()) << endl;
|
/*cerr << "MidiModel append event type: "
|
||||||
|
<< hex << "0x" << (int)ev.type() << endl;*/
|
||||||
|
|
||||||
assert(_notes.empty() || ev.time() >= _notes.back()->time());
|
assert(_notes.empty() || ev.time() >= _notes.back()->time());
|
||||||
assert(_writing);
|
assert(_writing);
|
||||||
|
|
@ -507,7 +508,7 @@ void MidiModel::append(const MIDI::Event& ev)
|
||||||
append_automation_event_unlocked(MidiChannelAftertouchAutomation,
|
append_automation_event_unlocked(MidiChannelAftertouchAutomation,
|
||||||
ev.channel(), ev.time(), ev.channel_aftertouch(), 0);
|
ev.channel(), ev.time(), ev.channel_aftertouch(), 0);
|
||||||
} else {
|
} else {
|
||||||
printf("MM Unknown event type %X\n", ev.type());
|
printf("WARNING: MidiModel: Unknown event type %X\n", ev.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
write_unlock();
|
write_unlock();
|
||||||
|
|
@ -607,7 +608,7 @@ void MidiModel::append_automation_event_unlocked(AutomationType type,
|
||||||
Parameter param(type, id, chan);
|
Parameter param(type, id, chan);
|
||||||
boost::shared_ptr<AutomationControl> control = Automatable::control(param, true);
|
boost::shared_ptr<AutomationControl> control = Automatable::control(param, true);
|
||||||
control->list()->fast_simple_add(time, value);
|
control->list()->fast_simple_add(time, value);
|
||||||
cerr << "control list size after fast simple add: " << control->list()->size() << endl;
|
/*cerr << "control list size after fast simple add: " << control->list()->size() << endl;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiModel::add_note_unlocked(const boost::shared_ptr<Note> note)
|
void MidiModel::add_note_unlocked(const boost::shared_ptr<Note> note)
|
||||||
|
|
@ -877,76 +878,27 @@ struct EventTimeComparator {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Write the model to a MidiSource (i.e. save the model).
|
||||||
|
* This is different from manually using read to write to a source in that
|
||||||
|
* note off events are written regardless of the track mode. This is so the
|
||||||
|
* user can switch a recorded track (with note durations from some instrument)
|
||||||
|
* to percussive, save, reload, then switch it back to sustained without
|
||||||
|
* destroying the original note durations.
|
||||||
|
*/
|
||||||
bool MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
bool MidiModel::write_to(boost::shared_ptr<MidiSource> source)
|
||||||
{
|
{
|
||||||
cerr << "Writing model to " << source->name() << endl;
|
|
||||||
|
|
||||||
/* This could be done using a temporary MidiRingBuffer and using
|
|
||||||
* MidiModel::read and MidiSource::write, but this is more efficient
|
|
||||||
* and doesn't require any buffer size assumptions (ie it's worth
|
|
||||||
* the code duplication).
|
|
||||||
*
|
|
||||||
* This is also different from read in that note off events are written
|
|
||||||
* regardless of the track mode. This is so the user can switch a
|
|
||||||
* recorded track (with note durations from some instrument) to percussive,
|
|
||||||
* save, reload, then switch it back to sustained preserving the original
|
|
||||||
* note durations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
read_lock();
|
read_lock();
|
||||||
|
|
||||||
LaterNoteEndComparator cmp;
|
const NoteMode old_note_mode = _note_mode;
|
||||||
ActiveNotes active_notes(cmp);
|
_note_mode = Sustained;
|
||||||
|
|
||||||
EventTimeComparator comp;
|
|
||||||
typedef std::priority_queue<
|
|
||||||
const MIDI::Event*,
|
|
||||||
std::deque<const MIDI::Event*>,
|
|
||||||
EventTimeComparator> MidiEvents;
|
|
||||||
|
|
||||||
MidiEvents events(comp);
|
|
||||||
|
|
||||||
/* Why sort manually, when a priority queue does the job for us,
|
|
||||||
* (I am probably wrong here, but I needed that to test program
|
|
||||||
* change code quickly) ???
|
|
||||||
* */
|
|
||||||
// Foreach note
|
|
||||||
for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) {
|
|
||||||
|
|
||||||
// Write any pending note offs earlier than this note on
|
|
||||||
while ( !active_notes.empty() ) {
|
|
||||||
const boost::shared_ptr<const Note> earliest_off =
|
|
||||||
active_notes.top();
|
|
||||||
const MIDI::Event& off_ev = earliest_off->off_event();
|
|
||||||
if (off_ev.time() <= (*n)->time()) {
|
|
||||||
events.push(&off_ev);
|
|
||||||
active_notes.pop();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write this note on
|
|
||||||
events.push(&(*n)->on_event());
|
|
||||||
if ((*n)->duration() > 0)
|
|
||||||
active_notes.push(*n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write any trailing note offs
|
|
||||||
while ( !active_notes.empty() ) {
|
|
||||||
events.push(&active_notes.top()->off_event());
|
|
||||||
active_notes.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!events.empty()) {
|
|
||||||
source->append_event_unlocked(Frames, *events.top());
|
|
||||||
//cerr << "MidiModel::write_to appending event with time:" << dec << int(events.top()->time()) << hex << " buffer: 0x" << int(events.top()->buffer()[0]) << " 0x" << int(events.top()->buffer()[1]) << " 0x" << int(events.top()->buffer()[2]) << endl;
|
|
||||||
events.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
_edited = false;
|
|
||||||
|
|
||||||
|
for (const_iterator i = begin(); i != end(); ++i)
|
||||||
|
source->append_event_unlocked(Frames, *i);
|
||||||
|
|
||||||
|
_note_mode = old_note_mode;
|
||||||
|
|
||||||
read_unlock();
|
read_unlock();
|
||||||
|
_edited = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@ MidiRegion::master_read_at (MidiRingBuffer& out, nframes_t position, nframes_t d
|
||||||
nframes_t
|
nframes_t
|
||||||
MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
|
MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const
|
||||||
{
|
{
|
||||||
cerr << "reading from region " << _name << " position: " << _position << " start: " << _start << endl;
|
/*cerr << "MidiRegion " << _name << "._read_at(" << position << ") - "
|
||||||
cerr << _name << "._read_at(" << position << ") - " << position << " duration: " << dur << endl;
|
<< position << " duration: " << dur << endl;*/
|
||||||
|
|
||||||
nframes_t internal_offset = 0;
|
nframes_t internal_offset = 0;
|
||||||
nframes_t src_offset = 0;
|
nframes_t src_offset = 0;
|
||||||
|
|
@ -174,7 +174,7 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t pos
|
||||||
|
|
||||||
nframes_t output_buffer_position = 0;
|
nframes_t output_buffer_position = 0;
|
||||||
nframes_t negative_output_buffer_position = 0;
|
nframes_t negative_output_buffer_position = 0;
|
||||||
if(_position >= _start) {
|
if (_position >= _start) {
|
||||||
// handle resizing of beginnings of regions correctly
|
// handle resizing of beginnings of regions correctly
|
||||||
output_buffer_position = _position - _start;
|
output_buffer_position = _position - _start;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,6 @@ Parameter::Parameter(const std::string& str)
|
||||||
sscanf(str.c_str(), "midicc-%d-%d", &channel, &_id);
|
sscanf(str.c_str(), "midicc-%d-%d", &channel, &_id);
|
||||||
assert(channel < 16);
|
assert(channel < 16);
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
cout << "LOADED PARAMETER " << str << " chan " << _channel << " id " << _id << endl;
|
|
||||||
//_id = atoi(str.c_str()+7);
|
|
||||||
} else {
|
} else {
|
||||||
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
|
PBD::warning << "Unknown Parameter '" << str << "'" << endmsg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,14 @@ SMFSource::init (string pathstr, bool must_exist)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Attempt to open the SMF file for reading and writing.
|
||||||
|
*
|
||||||
|
* Currently SMFSource is always read/write.
|
||||||
|
*
|
||||||
|
* \return 0 on success
|
||||||
|
* -1 if the file can not be opened for reading,
|
||||||
|
* -2 if the file can not be opened for writing
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
SMFSource::open()
|
SMFSource::open()
|
||||||
{
|
{
|
||||||
|
|
@ -153,6 +161,11 @@ SMFSource::open()
|
||||||
// We're making a new file
|
// We're making a new file
|
||||||
} else {
|
} else {
|
||||||
_fd = fopen(path().c_str(), "w+");
|
_fd = fopen(path().c_str(), "w+");
|
||||||
|
if (_fd == NULL) {
|
||||||
|
cerr << "ERROR: Can not open SMF file " << path() << " for writing: " <<
|
||||||
|
strerror(errno) << endl;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
_track_size = 4;
|
_track_size = 4;
|
||||||
|
|
||||||
// Write a tentative header just to pad things out so writing happens in the right spot
|
// Write a tentative header just to pad things out so writing happens in the right spot
|
||||||
|
|
@ -160,10 +173,21 @@ SMFSource::open()
|
||||||
write_footer();
|
write_footer();
|
||||||
seek_to_end();
|
seek_to_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (_fd == 0) ? -1 : 0;
|
return (_fd == 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SMFSource::close()
|
||||||
|
{
|
||||||
|
if (_fd) {
|
||||||
|
flush_header();
|
||||||
|
flush_footer();
|
||||||
|
fclose(_fd);
|
||||||
|
_fd = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SMFSource::seek_to_end()
|
SMFSource::seek_to_end()
|
||||||
{
|
{
|
||||||
|
|
@ -171,7 +195,7 @@ SMFSource::seek_to_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SMFSource::flush_header ()
|
SMFSource::flush_header()
|
||||||
{
|
{
|
||||||
// FIXME: write timeline position somehow?
|
// FIXME: write timeline position somehow?
|
||||||
|
|
||||||
|
|
@ -211,8 +235,6 @@ SMFSource::flush_footer()
|
||||||
void
|
void
|
||||||
SMFSource::write_footer()
|
SMFSource::write_footer()
|
||||||
{
|
{
|
||||||
//cerr << "SMF " << name() << " writing EOT at byte " << ftell(_fd) << endl;
|
|
||||||
|
|
||||||
write_var_len(0);
|
write_var_len(0);
|
||||||
char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event
|
char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event
|
||||||
fwrite(eot, 1, 3, _fd);
|
fwrite(eot, 1, 3, _fd);
|
||||||
|
|
@ -318,11 +340,11 @@ SMFSource::read_event(uint32_t* delta_t, uint32_t* size, Byte** buf) const
|
||||||
if (event_size > 1)
|
if (event_size > 1)
|
||||||
fread((*buf) + 1, 1, *size - 1, _fd);
|
fread((*buf) + 1, 1, *size - 1, _fd);
|
||||||
|
|
||||||
printf("%s read event: delta = %u, size = %u, data = ", _name.c_str(), *delta_t, *size);
|
/*printf("%s read event: delta = %u, size = %u, data = ", _name.c_str(), *delta_t, *size);
|
||||||
for (size_t i=0; i < *size; ++i) {
|
for (size_t i=0; i < *size; ++i) {
|
||||||
printf("%X ", (*buf)[i]);
|
printf("%X ", (*buf)[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");*/
|
||||||
|
|
||||||
return (int)*size;
|
return (int)*size;
|
||||||
}
|
}
|
||||||
|
|
@ -451,12 +473,13 @@ SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt)
|
||||||
void
|
void
|
||||||
SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev)
|
SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev)
|
||||||
{
|
{
|
||||||
//printf("%s - append chan = %u, time = %lf, size = %u, data = ", _path.c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
|
/*printf("%s - append chan = %u, time = %lf, size = %u, data = ",
|
||||||
|
name().c_str(), (unsigned)ev.channel(), ev.time(), ev.size());
|
||||||
for (size_t i=0; i < ev.size(); ++i) {
|
for (size_t i=0; i < ev.size(); ++i) {
|
||||||
printf("%X ", ev.buffer()[i]);
|
printf("%X ", ev.buffer()[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");*/
|
||||||
|
|
||||||
assert(ev.time() >= 0);
|
assert(ev.time() >= 0);
|
||||||
assert(ev.time() >= _last_ev_time);
|
assert(ev.time() >= _last_ev_time);
|
||||||
|
|
||||||
|
|
@ -535,6 +558,7 @@ SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_fra
|
||||||
{
|
{
|
||||||
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
|
MidiSource::mark_streaming_midi_write_started (mode, start_frame);
|
||||||
_last_ev_time = 0;
|
_last_ev_time = 0;
|
||||||
|
fseek(_fd, _header_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -546,20 +570,9 @@ SMFSource::mark_streaming_write_completed ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_model->set_edited(false);
|
||||||
flush_header();
|
flush_header();
|
||||||
flush_footer();
|
flush_footer();
|
||||||
|
|
||||||
#if 0
|
|
||||||
Glib::Mutex::Lock lm (_lock);
|
|
||||||
|
|
||||||
|
|
||||||
next_peak_clear_should_notify = true;
|
|
||||||
|
|
||||||
if (_peaks_built || pending_peak_builds.empty()) {
|
|
||||||
_peaks_built = true;
|
|
||||||
PeaksReady (); /* EMIT SIGNAL */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -861,13 +874,8 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||||
if (lock)
|
if (lock)
|
||||||
Glib::Mutex::Lock lm (_lock);
|
Glib::Mutex::Lock lm (_lock);
|
||||||
|
|
||||||
if (_model && !force_reload && !_model->empty()) {
|
if (_model && !force_reload && !_model->empty())
|
||||||
//cerr << _name << " NOT reloading model " << _model.get() << " (" << _model->n_notes()
|
|
||||||
// << " notes)" << endl;
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
cerr << _name << " loading model" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! _model) {
|
if (! _model) {
|
||||||
_model = boost::shared_ptr<MidiModel>(new MidiModel(this));
|
_model = boost::shared_ptr<MidiModel>(new MidiModel(this));
|
||||||
|
|
@ -912,6 +920,7 @@ SMFSource::load_model(bool lock, bool force_reload)
|
||||||
}
|
}
|
||||||
|
|
||||||
_model->end_write(false);
|
_model->end_write(false);
|
||||||
|
_model->set_edited(false);
|
||||||
|
|
||||||
free(ev.buffer());
|
free(ev.buffer());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue