MuseScore/synthesizer/event.h

340 lines
11 KiB
C
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2011 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __EVENT_H__
#define __EVENT_H__
2013-05-13 18:49:17 +02:00
#include <map>
namespace Ms {
2012-05-26 14:26:10 +02:00
class Note;
2016-11-19 11:51:21 +01:00
class XmlWriter;
2012-05-26 14:26:10 +02:00
enum class BeatType : char;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2013-04-15 10:38:16 +02:00
// Event types
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
enum {
ME_INVALID = 0,
ME_NOTEOFF = 0x80,
ME_NOTEON = 0x90,
ME_POLYAFTER = 0xa0,
ME_CONTROLLER = 0xb0,
ME_PROGRAM = 0xc0,
ME_AFTERTOUCH = 0xd0,
ME_PITCHBEND = 0xe0,
ME_SYSEX = 0xf0,
ME_META = 0xff,
ME_SONGPOS = 0xf2,
ME_ENDSYSEX = 0xf7,
ME_CLOCK = 0xf8,
ME_START = 0xfa,
ME_CONTINUE = 0xfb,
ME_STOP = 0xfc,
ME_SENSE = 0xfe, // active sense (used by yamaha)
2013-04-08 10:31:17 +02:00
ME_NOTE = 0x1,
ME_CHORD = 0x2,
ME_TICK1 = 0x3, // metronome tick akzent
2013-08-13 05:01:38 +02:00
ME_TICK2 = 0x4, // metronome tick
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
// Midi Meta Events
//---------------------------------------------------------
enum {
META_SEQUENCE_NUMBER = 0,
META_TEXT = 1,
META_COPYRIGHT = 2,
META_TRACK_NAME = 3,
META_INSTRUMENT_NAME = 4,
META_LYRIC = 5,
META_MARKER = 6,
META_CUE_POINT = 7,
META_PROGRAM_NAME = 8, // MIDI Meta Events 8 and 9 were defined as above by the MMA in 1998
META_DEVICE_NAME = 9, // It is therefore necessary to redefine MuseScore's private meta events
META_TRACK_COMMENT = 0xf, // Using the block starting 0x10 seems sensible as that is currently clear
META_TITLE = 0x10, // mscore extension
META_SUBTITLE = 0x11, // mscore extension
META_COMPOSER = 0x12, // mscore extension
META_TRANSLATOR = 0x13, // mscore extension
META_POET = 0x14, // mscore extension
2012-05-26 14:26:10 +02:00
META_PORT_CHANGE = 0x21,
META_CHANNEL_PREFIX = 0x22,
META_EOT = 0x2f, // end of track
META_TEMPO = 0x51,
META_TIME_SIGNATURE = 0x58,
2015-01-30 14:09:49 +01:00
META_KEY_SIGNATURE = 0x59,
META_SPECIFIC = 0x7F // sequencer specific
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
// Midi Controller
//---------------------------------------------------------
enum {
CTRL_HBANK = 0x00,
CTRL_LBANK = 0x20,
CTRL_HDATA = 0x06,
CTRL_LDATA = 0x26,
CTRL_HNRPN = 0x63,
CTRL_LNRPN = 0x62,
CTRL_HRPN = 0x65,
CTRL_LRPN = 0x64,
CTRL_MODULATION = 0x01,
2018-12-22 11:43:23 +01:00
CTRL_BREATH = 0x02,
CTRL_FOOT = 0x04,
2012-05-26 14:26:10 +02:00
CTRL_PORTAMENTO_TIME = 0x05,
CTRL_VOLUME = 0x07,
CTRL_PANPOT = 0x0a,
CTRL_EXPRESSION = 0x0b,
CTRL_SUSTAIN = 0x40,
CTRL_PORTAMENTO = 0x41,
CTRL_SOSTENUTO = 0x42,
CTRL_SOFT_PEDAL = 0x43,
CTRL_HARMONIC_CONTENT = 0x47,
CTRL_RELEASE_TIME = 0x48,
CTRL_ATTACK_TIME = 0x49,
CTRL_BRIGHTNESS = 0x4a,
CTRL_PORTAMENTO_CONTROL = 0x54,
CTRL_REVERB_SEND = 0x5b,
CTRL_CHORUS_SEND = 0x5d,
CTRL_VARIATION_SEND = 0x5e,
CTRL_ALL_SOUNDS_OFF = 0x78, // 120
CTRL_RESET_ALL_CTRL = 0x79, // 121
CTRL_LOCAL_OFF = 0x7a, // 122
2013-03-26 19:59:51 +01:00
CTRL_ALL_NOTES_OFF = 0x7b, // 123
2012-05-26 14:26:10 +02:00
// special midi events are mapped to internal
// controller
//
2013-03-27 20:10:14 +01:00
CTRL_PROGRAM = 0x81,
2015-06-02 20:05:44 +02:00
/* = 0x82,*/
2013-03-27 20:10:14 +01:00
CTRL_PRESS = 0x83,
2013-05-11 01:35:40 +02:00
CTRL_POLYAFTER = 0x84
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
2013-04-15 10:38:16 +02:00
// MidiCoreEvent
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2013-04-15 10:38:16 +02:00
class MidiCoreEvent {
2013-04-08 10:31:17 +02:00
protected:
2013-04-25 10:52:02 +02:00
uchar _type = 0;
uchar _channel = 0;
uchar _a = 0;
uchar _b = 0;
2013-04-08 10:31:17 +02:00
public:
2013-04-15 10:38:16 +02:00
MidiCoreEvent() {}
MidiCoreEvent(uchar t, uchar c, uchar a, uchar b)
2013-05-11 01:35:40 +02:00
: _type(t), _channel(c), _a(a), _b(b) {}
2013-04-08 10:31:17 +02:00
void set(uchar t, uchar c, uchar a, uchar b) {
_type = t;
_channel = c;
_a = a;
_b = b;
}
uchar type() const { return _type; }
void setType(uchar t) { _type = t; }
uchar channel() const { return _channel; }
void setChannel(uchar c) { _channel = c; }
int dataA() const { return _a; }
int pitch() const { return _a; }
int controller() const { return _a; }
void setDataA(int v) { _a = v; }
void setPitch(int v) { _a = v; }
void setController(int v) { _a = v; }
int dataB() const { return _b; }
int velo() const { return _b; }
int value() const { return _b; }
void setDataB(int v) { _b = v; }
void setVelo(int v) { _b = v; }
void setValue(int v) { _b = v; }
void setData(int a, int b) { _a = a; _b = b; }
void setData(int t, int a, int b) { _type = t; _a = a; _b = b; }
2013-04-15 10:38:16 +02:00
bool isChannelEvent() const;
2016-11-19 11:51:21 +01:00
void write(XmlWriter&) const;
2013-04-25 10:52:02 +02:00
bool operator==(const MidiCoreEvent& e) const {
return e._type == _type && e._channel == _channel && e._a == _a && e._b == _b;
}
2013-04-15 10:38:16 +02:00
};
//---------------------------------------------------------
// MidiEvent
//---------------------------------------------------------
class MidiEvent : public MidiCoreEvent {
protected:
uchar* _edata; // always zero terminated (_data[_len] == 0; )
int _len;
int _metaType;
public:
MidiEvent() {}
MidiEvent(uchar t, uchar c, uchar a, uchar b)
2013-05-11 01:35:40 +02:00
: MidiCoreEvent(t, c, a, b), _edata(0), _len(0) {}
2013-04-15 10:38:16 +02:00
const uchar* edata() const { return _edata; }
void setEData(uchar* d) { _edata = d; }
int len() const { return _len; }
void setLen(int l) { _len = l; }
int metaType() const { return _metaType; }
void setMetaType(int v) { _metaType = v; }
};
//---------------------------------------------------------
// PlayEvent
// interface to Synthesizer
2013-04-15 10:38:16 +02:00
//---------------------------------------------------------
class PlayEvent : public MidiCoreEvent {
protected:
float _tuning = .0f;
public:
PlayEvent() : MidiCoreEvent() {}
PlayEvent(const MidiCoreEvent& e) : MidiCoreEvent(e) {}
PlayEvent(uchar t, uchar c, uchar a, uchar b)
2013-05-11 01:35:40 +02:00
: MidiCoreEvent(t, c, a, b) {}
2013-04-08 10:31:17 +02:00
float tuning() const { return _tuning; }
void setTuning(float v) { _tuning = v; }
};
//---------------------------------------------------------
// NPlayEvent
// used for Sequencer interface
//---------------------------------------------------------
class NPlayEvent : public PlayEvent {
const Note* _note = 0;
int _origin = -1;
int _discard = 0;
public:
NPlayEvent() : PlayEvent() {}
NPlayEvent(uchar t, uchar c, uchar a, uchar b)
2013-05-11 01:35:40 +02:00
: PlayEvent(t, c, a, b) {}
NPlayEvent(const MidiCoreEvent& e) : PlayEvent(e) {}
NPlayEvent(BeatType beatType);
const Note* note() const { return _note; }
void setNote(const Note* v) { _note = v; }
int getOriginatingStaff() const { return _origin; }
void setOriginatingStaff(int i) { _origin = i; }
void setDiscard(int d) { _discard = d; }
int discard() const { return _discard; }
bool isMuted() const;
};
2013-04-08 10:31:17 +02:00
//---------------------------------------------------------
// Event
//---------------------------------------------------------
2012-05-26 14:26:10 +02:00
2013-04-08 10:31:17 +02:00
class Event : public PlayEvent {
int _ontime;
int _noquantOntime;
int _noquantDuration;
int _duration;
int _tpc; // tonal pitch class
int _voice;
QList<Event> _notes;
uchar* _edata; // always zero terminated (_data[_len] == 0; )
int _len;
int _metaType;
const Note* _note;
2012-05-26 14:26:10 +02:00
public:
Event();
Event(const Event&);
Event(int t);
~Event();
bool operator==(const Event&) const;
2016-11-19 11:51:21 +01:00
void write(XmlWriter&) const;
2012-05-26 14:26:10 +02:00
void dump() const;
2013-04-08 10:31:17 +02:00
int noquantOntime() const { return _noquantOntime; }
void setNoquantOntime(int v) { _noquantOntime = v; }
int noquantDuration() const { return _noquantDuration; }
void setNoquantDuration(int v) { _noquantDuration = v; }
int ontime() const { return _ontime; }
void setOntime(int v) { _ontime = v; }
int duration() const { return _duration; }
void setDuration(int v) { _duration = v; }
int voice() const { return _voice; }
void setVoice(int val) { _voice = val; }
int offtime() const { return _ontime + _duration; }
QList<Event>& notes() { return _notes; }
const uchar* edata() const { return _edata; }
void setEData(uchar* d) { _edata = d; }
int len() const { return _len; }
void setLen(int l) { _len = l; }
int metaType() const { return _metaType; }
void setMetaType(int v) { _metaType = v; }
int tpc() const { return _tpc; }
void setTpc(int v) { _tpc = v; }
const Note* note() const { return _note; }
void setNote(const Note* v) { _note = v; }
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
// EventList
// EventMap
//---------------------------------------------------------
class EventList : public QList<Event> {
public:
void insert(const Event&);
void insertNote(int channel, Note*);
};
class EventMap : public std::multimap<int, NPlayEvent> {
int _highestChannel = 15;
public:
void fixupMIDI();
void registerChannel(int c) { if (c > _highestChannel) _highestChannel = c; }
};
2012-05-26 14:26:10 +02:00
typedef EventList::iterator iEvent;
typedef EventList::const_iterator ciEvent;
extern QString midiMetaName(int meta);
2013-05-13 18:49:17 +02:00
}
2012-05-26 14:26:10 +02:00
#endif