diff options
Diffstat (limited to 'src/sound/MidiEvent.cpp')
-rw-r--r-- | src/sound/MidiEvent.cpp | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/sound/MidiEvent.cpp b/src/sound/MidiEvent.cpp new file mode 100644 index 0000000..975b7aa --- /dev/null +++ b/src/sound/MidiEvent.cpp @@ -0,0 +1,289 @@ +// -*- c-indentation-style:"stroustrup" c-basic-offset: 4 -*- +/* + Rosegarden + A sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral right of the authors to claim authorship of this work + has been asserted. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "Midi.h" +#include "MidiEvent.h" +#include <iostream> + +// MidiEvent is a representation of MIDI which we use +// for the import/export of MidiFiles. It uses std::strings for +// meta event messages which makes them nice and easy to handle. +// +// +namespace Rosegarden +{ + +using std::string; +using std::cout; +using std::endl; + +MidiEvent::MidiEvent() +{} + +MidiEvent::MidiEvent(timeT deltaTime, + MidiByte eventCode): + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(0), + m_data2(0), + m_metaEventCode(0), + m_metaMessage("") +{} + +MidiEvent::MidiEvent(timeT deltaTime, + MidiByte eventCode, + MidiByte data1): + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(data1), + m_data2(0), + m_metaEventCode(0), + m_metaMessage("") +{} + +MidiEvent::MidiEvent(timeT deltaTime, + MidiByte eventCode, + MidiByte data1, + MidiByte data2): + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(data1), + m_data2(data2), + m_metaEventCode(0), + m_metaMessage("") + +{} + +MidiEvent::MidiEvent(timeT deltaTime, + MidiByte eventCode, + MidiByte metaEventCode, + const string &metaMessage): + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(0), + m_data2(0), + m_metaEventCode(metaEventCode), + m_metaMessage(metaMessage) +{} + +MidiEvent::MidiEvent(timeT deltaTime, + MidiByte eventCode, + const string &sysEx): + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(0), + m_data2(0), + m_metaEventCode(0), + m_metaMessage(sysEx) +{} + +MidiEvent::~MidiEvent() +{} + +// Show a representation of our MidiEvent purely for information +// purposes (also demos how we decode them) +// +// +void +MidiEvent::print() +{ + timeT tempo; + int tonality; + string sharpflat; + + if (m_metaEventCode) { + switch (m_metaEventCode) { + case MIDI_SEQUENCE_NUMBER: + cout << "MIDI SEQUENCE NUMBER" << endl; + break; + + case MIDI_TEXT_EVENT: + cout << "MIDI TEXT:\t\"" << m_metaMessage << "\"" << endl; + break; + + case MIDI_COPYRIGHT_NOTICE: + cout << "COPYRIGHT:\t\"" << m_metaMessage << "\"" << endl; + + case MIDI_TRACK_NAME: + cout << "TRACK NAME:\t\"" << m_metaMessage << "\"" << endl; + break; + + case MIDI_INSTRUMENT_NAME: + cout << "INSTRUMENT NAME:\t\"" << m_metaMessage << "\"" << endl; + break; + + case MIDI_LYRIC: + cout << "LYRIC:\t\"" << m_metaMessage << "\"" << endl; + break; + + case MIDI_TEXT_MARKER: + cout << "MARKER:\t\"" << m_metaMessage << "\"" << endl; + break; + + case MIDI_CUE_POINT: + cout << "CUE POINT:\t\"" << m_metaMessage << "\"" << endl; + break; + + // Sets a Channel number for a TRACK before it starts + case MIDI_CHANNEL_PREFIX: + cout << "CHANNEL PREFIX:\t" + << (timeT)m_metaMessage[0] + << endl; + break; + + // These are actually the same case but this is not an + // official META event - it just crops up a lot. We + // assume it's a MIDI_CHANNEL_PREFIX though + // + case MIDI_CHANNEL_PREFIX_OR_PORT: + cout << "FIXED CHANNEL PREFIX:\t" + << (timeT)m_metaMessage[0] << endl; + break; + + case MIDI_END_OF_TRACK: + cout << "END OF TRACK" << endl; + break; + + case MIDI_SET_TEMPO: + tempo = + ((timeT)(((MidiByte)m_metaMessage[0]) << 16)) + + ((timeT)(((MidiByte)m_metaMessage[1]) << 8)) + + (short)(MidiByte)m_metaMessage[2]; + + tempo = 60000000 / tempo; + cout << "SET TEMPO:\t" << tempo << endl; + break; + + case MIDI_SMPTE_OFFSET: + cout << "SMPTE TIME CODE:\t" + << (timeT)m_metaMessage[0] + << ":" << (timeT)m_metaMessage[1] + << ":" << (timeT)m_metaMessage[2] + << " - fps = " << (timeT)m_metaMessage[3] + << " - subdivsperframe = " + << (timeT)m_metaMessage[4] + << endl; + break; + + case MIDI_TIME_SIGNATURE: + cout << "TIME SIGNATURE:\t" + << (timeT)m_metaMessage[0] + << "/" + << (1 << (timeT)m_metaMessage[1]) << endl; + break; + + case MIDI_KEY_SIGNATURE: + tonality = (int)m_metaMessage[0]; + + if (tonality < 0) { + sharpflat = -tonality + " flat"; + } else { + sharpflat = tonality; + sharpflat += " sharp"; + } + + cout << "KEY SIGNATURE:\t" << sharpflat << " " + << (((int)m_metaMessage[1]) == 0 ? "major" : "minor") + << endl; + + break; + + case MIDI_SEQUENCER_SPECIFIC: + cout << "SEQUENCER SPECIFIC:\t\"" << m_metaMessage << endl; + break; + + + default: + cout << "Undefined MIDI META event - " + << (timeT)m_metaEventCode << endl; + break; + } + } else { + switch (m_eventCode & MIDI_MESSAGE_TYPE_MASK) { + case MIDI_NOTE_ON: + cout << "NOTE ON:\t" << (int)m_data1 << " - " + << (int)m_data2 << endl; + break; + + case MIDI_NOTE_OFF: + cout << "NOTE OFF:\t" << (int)m_data1 << " - " + << (int)m_data2 << endl; + break; + + case MIDI_POLY_AFTERTOUCH: + cout << "POLY AFTERTOUCH:\t" << (int)m_data1 + << " - " << (int)m_data2 << endl; + break; + + case MIDI_CTRL_CHANGE: + cout << "CTRL CHANGE:\t" << (int)m_data1 + << " - " << (int)m_data2 << endl; + break; + + case MIDI_PITCH_BEND: + cout << "PITCH BEND:\t" << (int)m_data1 + << " - " << (int)m_data2 << endl; + break; + + case MIDI_PROG_CHANGE: + cout << "PROG CHANGE:\t" << (int)m_data1 << endl; + break; + + case MIDI_CHNL_AFTERTOUCH: + cout << "CHNL AFTERTOUCH\t" << (int)m_data1 << endl; + break; + + default: + cout << "Undefined MIDI event" << endl; + break; + } + } + + + return ; +} + +// Adds the argument to _deltaTime and returns the result +// thus aggregating the times as we go aint +timeT +MidiEvent::addTime(const timeT &time) +{ + m_deltaTime += time; + return m_deltaTime; +} + + +// Compare based on time +// +bool +operator<(const MidiEvent &a, const MidiEvent &b) +{ + return a.getTime() < b.getTime(); +} + + +} + + |