238 lines
6.4 KiB
C++
238 lines
6.4 KiB
C++
|
|
/*******************************************************************************/
|
|
/* Copyright (C) 2008 Jonathan Moore Liles */
|
|
/* */
|
|
/* 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. */
|
|
/* */
|
|
/* This program is distributed in the hope that it will be useful, but WITHOUT */
|
|
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
|
|
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
|
|
/* more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU General Public License along */
|
|
/* with This program; see the file COPYING. If not,write to the Free Software */
|
|
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
/*******************************************************************************/
|
|
|
|
/* this class represents a single raw MIDI event plus a timestamp */
|
|
|
|
#pragma once
|
|
|
|
#include "types.h"
|
|
#include <stdlib.h>
|
|
|
|
namespace MIDI
|
|
{
|
|
class midievent
|
|
{
|
|
|
|
public:
|
|
|
|
class sysex {
|
|
size_t _size, _alloc;
|
|
byte_t *_data;
|
|
|
|
public:
|
|
|
|
sysex ( void );
|
|
~sysex ( void );
|
|
|
|
void append ( byte_t *data, size_t size );
|
|
const byte_t * data ( void ) const;
|
|
long size ( void ) const;
|
|
|
|
};
|
|
|
|
private:
|
|
|
|
sysex *_sysex;
|
|
|
|
tick_t _timestamp; /* in ticks */
|
|
struct {
|
|
byte_t status, /* full status byte */
|
|
lsb, /* data 1 */
|
|
msb; /* data 2 */
|
|
} _data;
|
|
|
|
public:
|
|
|
|
static inline byte_t
|
|
event_size ( byte_t op )
|
|
{
|
|
switch ( op )
|
|
{
|
|
case NOTE_ON: case NOTE_OFF: case AFTERTOUCH:
|
|
case CONTROL_CHANGE: case PITCH_WHEEL:
|
|
return 3;
|
|
case PROGRAM_CHANGE: case CHANNEL_PRESSURE:
|
|
return 2;
|
|
default:
|
|
return 1;
|
|
}
|
|
};
|
|
|
|
/* define MIDI status bytes */
|
|
enum {
|
|
STATUS_BIT = 0x80,
|
|
NOTE_OFF = 0x80,
|
|
NOTE_ON = 0x90,
|
|
AFTERTOUCH = 0xA0,
|
|
CONTROL_CHANGE = 0xB0,
|
|
PROGRAM_CHANGE = 0xC0,
|
|
CHANNEL_PRESSURE = 0xD0,
|
|
PITCH_WHEEL = 0xE0,
|
|
CLEAR_CHAN_MASK = 0xF0,
|
|
MIDI_CLOCK = 0xF8,
|
|
SYSEX = 0xF0,
|
|
SYSEX_END = 0xF7,
|
|
META = 0xFF
|
|
};
|
|
|
|
midievent ( void );
|
|
virtual ~midievent ( void );
|
|
|
|
tick_t timestamp ( void ) const;
|
|
void timestamp ( tick_t time );
|
|
void status ( byte_t status );
|
|
byte_t status ( void ) const;
|
|
void channel ( byte_t channel );
|
|
byte_t channel ( void ) const;
|
|
byte_t opcode ( void ) const;
|
|
void opcode ( byte_t o );
|
|
void lsb ( byte_t n );
|
|
void msb ( byte_t n );
|
|
byte_t lsb ( void ) const;
|
|
byte_t msb ( void ) const;
|
|
int pitch ( void ) const;
|
|
void pitch ( int n );
|
|
void data ( byte_t D1, byte_t D2 );
|
|
void data ( byte_t *D1, byte_t *D2 ) const;
|
|
void raw ( byte_t *p, int l) const;
|
|
byte_t size ( void ) const;
|
|
void note_velocity ( byte_t vel );
|
|
bool is_note_on ( void ) const;
|
|
bool is_note_off ( void ) const;
|
|
virtual unsigned char note ( void ) const;
|
|
virtual void note ( char note );
|
|
unsigned char note_velocity ( void ) const;
|
|
bool is_same_note ( midievent * e ) const;
|
|
const char * name ( void ) const;
|
|
int name ( const char *name ) const;
|
|
void print ( void ) const;
|
|
void pretty_print ( void ) const;
|
|
|
|
bool operator< ( const midievent &rhs ) const;
|
|
bool operator>= ( const midievent &rhs ) const;
|
|
|
|
bool operator== ( const midievent &rhs ) const;
|
|
|
|
};
|
|
|
|
|
|
/**********************/
|
|
/* Inlined accessors */
|
|
/**********************/
|
|
|
|
|
|
inline tick_t
|
|
midievent::timestamp ( void ) const
|
|
{
|
|
return _timestamp;
|
|
}
|
|
|
|
inline void
|
|
midievent::timestamp ( tick_t time )
|
|
{
|
|
_timestamp = time;
|
|
}
|
|
|
|
inline void
|
|
midievent::status ( byte_t status )
|
|
{
|
|
_data.status = status;
|
|
}
|
|
|
|
inline byte_t
|
|
midievent::status ( void ) const
|
|
{
|
|
return _data.status;
|
|
}
|
|
|
|
inline void
|
|
midievent::channel ( byte_t channel )
|
|
{
|
|
_data.status = (_data.status & 0xF0) | (channel & 0x0F);
|
|
}
|
|
|
|
inline byte_t
|
|
midievent::channel ( void ) const
|
|
{
|
|
return _data.status & 0x0F;
|
|
}
|
|
|
|
inline byte_t
|
|
midievent::opcode ( void ) const
|
|
{
|
|
return _data.status & 0xF0;
|
|
}
|
|
|
|
|
|
inline void
|
|
midievent::opcode ( byte_t opcode )
|
|
{
|
|
_data.status = (_data.status & 0x0F) | (opcode & 0xF0);
|
|
}
|
|
|
|
inline void
|
|
midievent::lsb ( byte_t n )
|
|
{
|
|
_data.lsb = n & 0x7F;
|
|
}
|
|
|
|
inline void
|
|
midievent::msb ( byte_t n )
|
|
{
|
|
_data.msb = n & 0x7F;
|
|
}
|
|
|
|
inline byte_t
|
|
midievent::lsb ( void ) const
|
|
{
|
|
return _data.lsb;
|
|
}
|
|
|
|
inline byte_t
|
|
midievent::msb ( void ) const
|
|
{
|
|
return _data.msb;
|
|
}
|
|
|
|
inline bool
|
|
midievent::is_note_on ( void ) const
|
|
{
|
|
return (opcode() == NOTE_ON);
|
|
}
|
|
|
|
inline bool
|
|
midievent::is_note_off ( void ) const
|
|
{
|
|
return (opcode() == NOTE_OFF);
|
|
}
|
|
|
|
inline bool
|
|
midievent::operator< ( const midievent &rhs ) const
|
|
{
|
|
return _timestamp < rhs._timestamp;
|
|
}
|
|
|
|
inline bool
|
|
midievent::operator>= ( const midievent &rhs ) const
|
|
{
|
|
return _timestamp >= rhs._timestamp;
|
|
}
|
|
|
|
}
|