XMidiNoteStack.h

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003  The Pentagram Team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 // Tab Size = 4
00020 
00021 #ifndef XMIDINOTESTACK_H_INCLUDED
00022 #define XMIDINOTESTACK_H_INCLUDED
00023 
00024 #include "XMidiEvent.h"
00025 
00026 class XMidiNoteStack {
00027         XMidiEvent              *notes;         // Top of the stack
00028         int                             polyphony;
00029         int                             max_polyphony;
00030 public:
00031 
00032         XMidiNoteStack() : notes(0), polyphony(0), max_polyphony(0) { }
00033 
00034         // Just clear it. Don't care about what's actually in it
00035         inline void clear() {
00036                 notes=0;
00037                 polyphony=0;
00038                 max_polyphony=0;
00039         }
00040 
00041         // Pops the top of the stack if its off_time is <= time (6000th of second)
00042         inline XMidiEvent *PopTime(uint32 time) {
00043                 if (notes && notes->ex.note_on.note_time <= time)  {
00044                         XMidiEvent *note = notes;
00045                         notes = note->ex.note_on.next_note;
00046                         note->ex.note_on.next_note = 0;
00047                         polyphony--;
00048                         return note;
00049                 }
00050 
00051                 return 0;
00052         }
00053 
00054         // Pops the top of the stack
00055         inline XMidiEvent *Pop() {
00056                 if (notes)  {
00057                         XMidiEvent *note = notes;
00058                         notes = note->ex.note_on.next_note;
00059                         note->ex.note_on.next_note = 0;
00060                         polyphony--;
00061                         return note;
00062                 }
00063 
00064                 return 0;
00065         }
00066 
00067         // Pops the top of the stack
00068         inline XMidiEvent *Remove(XMidiEvent *event) {
00069                 XMidiEvent *prev = 0;
00070                 XMidiEvent *note = notes;
00071                 while (note) {
00072 
00073                         if (note == event) {
00074                                 if (prev) prev->ex.note_on.next_note = note->ex.note_on.next_note;
00075                                 else notes = note->ex.note_on.next_note;
00076                                 note->ex.note_on.next_note = 0;
00077                                 polyphony--;
00078                                 return note;
00079                         }
00080                         prev = note;
00081                         note = note->ex.note_on.next_note;
00082                 }
00083                 return 0;
00084         }
00085 
00086         // Finds the note that has same pitch and channel, and pops it
00087         inline XMidiEvent *FindAndPop(XMidiEvent *event) {
00088 
00089                 XMidiEvent *prev = 0;
00090                 XMidiEvent *note = notes;
00091                 while (note) {
00092 
00093                         if ((note->status & 0xF) == (event->status & 0xF) && note->data[0] == event->data[0]) {
00094                                 if (prev) prev->ex.note_on.next_note = note->ex.note_on.next_note;
00095                                 else notes = note->ex.note_on.next_note;
00096                                 note->ex.note_on.next_note = 0;
00097                                 polyphony--;
00098                                 return note;
00099                         }
00100                         prev = note;
00101                         note = note->ex.note_on.next_note;
00102                 }
00103                 return 0;
00104         }
00105 
00106         // Pushes a note onto the top of the stack
00107         inline void Push(XMidiEvent *event) {
00108                 event->ex.note_on.next_note = notes;
00109                 notes = event;
00110                 polyphony++;
00111                 if (max_polyphony < polyphony) max_polyphony = polyphony;
00112         }
00113 
00114         inline void Push(XMidiEvent *event, uint32 time) {
00115                 event->ex.note_on.note_time = time;
00116                 event->ex.note_on.next_note = 0;
00117 
00118                 polyphony++;
00119                 if (max_polyphony < polyphony) max_polyphony = polyphony;
00120 
00121                 if (!notes || time <= notes->ex.note_on.note_time) {
00122                         event->ex.note_on.next_note = notes;
00123                         notes = event;
00124                 }
00125                 else {
00126                         XMidiEvent *prev = notes;
00127                         while (prev) {
00128                                 XMidiEvent *note = prev->ex.note_on.next_note;
00129 
00130                                 if (!note || time <= note->ex.note_on.note_time) {
00131                                         event->ex.note_on.next_note = note;
00132                                         prev->ex.note_on.next_note = event;
00133                                         return;
00134                                 }
00135                                 prev = note;
00136                         }
00137                 }
00138         }
00139 
00140         // Finds the note that has same pitch and channel, and sets its after touch to our velocity
00141         inline void SetAftertouch(XMidiEvent *event) {
00142 
00143                 XMidiEvent *prev = 0;
00144                 XMidiEvent *note = notes;
00145                 while (note) {
00146 
00147                         if ((note->status & 0xF) == (event->status & 0xF) && note->data[0] == event->data[0]) {
00148                                 note->ex.note_on.actualvel = event->data[1];
00149                                 return;
00150                         }
00151                         prev = note;
00152                         note = note->ex.note_on.next_note;
00153                 }
00154         }
00155 
00156         inline XMidiEvent* GetNotes() {
00157                 return notes;
00158                 }
00159 
00160         inline int GetPolyphony() {
00161                 return polyphony;
00162         }
00163 
00164         inline int GetMaxPolyphony() {
00165                 return max_polyphony;
00166         }
00167 };
00168 
00169 #endif //XMIDINOTESTACK_H_INCLUDED

Generated on Fri Jul 27 22:27:55 2007 for pentagram by  doxygen 1.4.7