1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-24 06:10:09 +01:00

Fixed playback/redraw interactions (redraw was converting from seconds to beats while player was trying to read seconds in another thread). Added compile-time option make channel select be the down position. Fixed problem with MIDI track mute to eliminate hung notes.

This commit is contained in:
rbdannenberg
2010-10-07 21:36:39 +00:00
parent f52bafbf05
commit 2fd5555378
6 changed files with 106 additions and 40 deletions

View File

@@ -698,6 +698,7 @@ void Alg_events::append(Alg_event_ptr event)
Alg_events::~Alg_events()
{
assert(!in_use);
// individual events are not deleted, only the array
if (events) {
delete[] events;
@@ -2622,7 +2623,15 @@ void Alg_tracks::reset()
if (tracks) delete [] tracks;
tracks = NULL;
len = 0;
maxlen = 0; // Modified by Ning Hu Nov.19 2002
maxlen = 0;
}
void Alg_tracks::set_in_use(bool flag)
{
for (int i = 0; i < len; i++) {
tracks[i]->in_use = flag;
}
}
@@ -2680,15 +2689,8 @@ bool Alg_iterator::earlier(int i, int j)
// followed immediately with the same timestamp by a note-on (common
// in MIDI files), the note-off will be scheduled first
Alg_pending_event_ptr p_i = &(pending_events[i]);
Alg_event_ptr e_i = (*(p_i->events))[p_i->index];
double t_i = (p_i->note_on ? e_i->time :
e_i->get_end_time() - ALG_EPS) + p_i->offset;
Alg_pending_event_ptr p_j = &(pending_events[j]);
Alg_event_ptr e_j = (*(p_j->events))[p_j->index];
double t_j = (p_j->note_on ? e_j->time :
e_j->get_end_time() - ALG_EPS) + p_j->offset;
double t_i = pending_events[i].time;
double t_j = pending_events[j].time;
if (t_i < t_j) return true;
// not sure if this case really exists or this is the best rule, but
@@ -2707,6 +2709,17 @@ void Alg_iterator::insert(Alg_events_ptr events, long index,
pending_events[len].note_on = note_on;
pending_events[len].cookie = cookie;
pending_events[len].offset = offset;
Alg_event_ptr event = (*events)[index];
pending_events[len].time = (note_on ? event->time :
event->get_end_time() - ALG_EPS) + offset;
/* BEGIN DEBUG *
printf("insert %p=%p[%d] @ %g\n", event, events, index,
pending_events[len].time);
printf(" is_note %d note_on %d time %g dur %g end_time %g offset %g\n",
event->is_note(), note_on, event->time, event->get_duration(),
event->get_end_time(), offset);
}
* END DEBUG */
int loc = len;
int loc_parent = HEAP_PARENT(loc);
len++;
@@ -2720,12 +2733,12 @@ void Alg_iterator::insert(Alg_events_ptr events, long index,
loc = loc_parent;
loc_parent = HEAP_PARENT(loc);
}
// printf("After insert:"); show();
}
bool Alg_iterator::remove_next(Alg_events_ptr &events, long &index,
bool &note_on, void *&cookie,
double &offset)
double &offset, double &time)
{
if (len == 0) return false; // empty!
events = pending_events[0].events;
@@ -2734,6 +2747,7 @@ bool Alg_iterator::remove_next(Alg_events_ptr &events, long &index,
offset = pending_events[0].offset;
cookie = pending_events[0].cookie;
offset = pending_events[0].offset;
time = pending_events[0].time;
len--;
pending_events[0] = pending_events[len];
// sift down
@@ -3421,7 +3435,8 @@ Alg_event_ptr Alg_iterator::next(bool *note_on, void **cookie_ptr,
// return the next event in time from any track
{
bool on;
if (!remove_next(events_ptr, index, on, cookie, offset)) {
double when;
if (!remove_next(events_ptr, index, on, cookie, offset, when)) {
return NULL;
}
if (note_on) *note_on = on;
@@ -3484,6 +3499,13 @@ void Alg_seq::merge_tracks()
}
void Alg_seq::set_in_use(bool flag)
{
Alg_track::set_in_use(flag);
track_list.set_in_use(flag);
}
// sr_letter_to_type = {"i": 'Integer', "r": 'Real', "s": 'String',
// "l": 'Logical', "a": 'Symbol'}

View File

@@ -324,6 +324,9 @@ public:
// creating a new track and adding notes to it. It is *not*
// updated after uninsert(), so use it with care.
double last_note_off;
// initially false, in_use can be used to mark "do not delete". If an
// Alg_events instance is deleted while "in_use", an assertion will fail.
bool in_use;
virtual int length() { return len; }
Alg_event_ptr &operator[](int i) {
assert(i >= 0 && i < len);
@@ -333,6 +336,7 @@ public:
maxlen = len = 0;
events = NULL;
last_note_off = 0;
in_use = false;
}
// destructor deletes the events array, but not the
// events themselves
@@ -797,6 +801,7 @@ public:
virtual Alg_event_list *find(double t, double len, bool all,
long channel_mask, long event_type_mask);
virtual void set_in_use(bool flag) { in_use = flag; }
//
// MIDI playback
//
@@ -891,6 +896,7 @@ public:
void append(Alg_track_ptr track);
void add_track(int track_num, Alg_time_map_ptr time_map, bool seconds);
void reset();
void set_in_use(bool flag); // handy to set in_use flag on all tracks
} *Alg_tracks_ptr;
@@ -912,6 +918,7 @@ typedef struct Alg_pending_event {
long index; // offset of this event
bool note_on; // is this a note-on or a note-off (if applicable)?
double offset; // time offset for events
double time; // time for this event
} *Alg_pending_event_ptr;
@@ -934,7 +941,7 @@ private:
void *cookie, double offset);
// returns the info on the next pending event in the priority queue
bool remove_next(Alg_events_ptr &events, long &index, bool &note_on,
void *&cookie, double &offset);
void *&cookie, double &offset, double &time);
public:
bool note_off_flag; // remembers if we are iterating over note-off
// events as well as note-on and update events
@@ -1096,6 +1103,7 @@ public:
double *num, double *den);
// void set_events(Alg_event_ptr *events, long len, long max);
void merge_tracks(); // move all track data into one track
void set_in_use(bool flag); // set in_use flag on all tracks
} *Alg_seq_ptr, &Alg_seq_ref;