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:
@@ -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 ¬e_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'}
|
||||
|
||||
|
||||
@@ -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 ¬e_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;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user