216 lines
4.9 KiB
C++
216 lines
4.9 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. */
|
|||
|
/*******************************************************************************/
|
|||
|
|
|||
|
#include "midievent.H"
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include "debug.h"
|
|||
|
|
|||
|
namespace MIDI
|
|||
|
{
|
|||
|
static const char *opcode_names[] =
|
|||
|
{
|
|||
|
"Note Off",
|
|||
|
"Note On",
|
|||
|
"Aftertouch",
|
|||
|
"Control Change",
|
|||
|
"Program Change",
|
|||
|
"Channel Pressure",
|
|||
|
"Pitch Wheel"
|
|||
|
};
|
|||
|
|
|||
|
midievent::midievent ( void )
|
|||
|
{
|
|||
|
_sysex = NULL;
|
|||
|
_timestamp = 0;
|
|||
|
_data.status = NOTE_OFF;
|
|||
|
_data.msb = _data.lsb = 0;
|
|||
|
}
|
|||
|
|
|||
|
midievent::~midievent ( void )
|
|||
|
{
|
|||
|
if ( _sysex )
|
|||
|
delete _sysex;
|
|||
|
|
|||
|
_sysex = NULL;
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
midievent::pitch ( void ) const
|
|||
|
{
|
|||
|
return ((_data.msb << 7) | _data.lsb) - 0x2000;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::pitch ( int n )
|
|||
|
{
|
|||
|
n += 0x2000;
|
|||
|
|
|||
|
_data.lsb = n & 0x7F;
|
|||
|
_data.msb = (n >> 7) & 0x7F;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::data ( byte_t D1, byte_t D2 )
|
|||
|
{
|
|||
|
_data.lsb = D1 & 0x7F;
|
|||
|
_data.msb = D2 & 0x7F;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::data ( byte_t *D1, byte_t *D2 ) const
|
|||
|
{
|
|||
|
*D1 = _data.lsb;
|
|||
|
*D2 = _data.msb;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::raw ( byte_t *p, int l) const
|
|||
|
{
|
|||
|
memcpy( p, &_data, l );
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
midievent::size ( void ) const
|
|||
|
{
|
|||
|
return midievent::event_size( opcode() );
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::note_velocity ( int vel )
|
|||
|
{
|
|||
|
_data.msb = vel & 0x7F;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
midievent::note ( char note )
|
|||
|
{
|
|||
|
_data.lsb = note & 0x7F;
|
|||
|
}
|
|||
|
|
|||
|
unsigned char
|
|||
|
midievent::note_velocity ( void ) const
|
|||
|
{
|
|||
|
return _data.msb;
|
|||
|
}
|
|||
|
|
|||
|
bool
|
|||
|
midievent::is_same_note ( midievent * e ) const
|
|||
|
{
|
|||
|
return channel() == e->channel() && note() == e->note();
|
|||
|
}
|
|||
|
|
|||
|
/** get name from opcode */
|
|||
|
const char *
|
|||
|
midievent::name ( void ) const
|
|||
|
{
|
|||
|
return opcode_names[ (opcode() >> 4) - 8 ];
|
|||
|
}
|
|||
|
|
|||
|
/** get opcode from name */
|
|||
|
int
|
|||
|
midievent::name ( const char *name ) const
|
|||
|
{
|
|||
|
for ( unsigned int i = elementsof( opcode_names ); i--; )
|
|||
|
if ( ! strcmp( name, opcode_names[ i ] ) )
|
|||
|
return (i + 8) << 4;
|
|||
|
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
/** print event in hexadecimal */
|
|||
|
void
|
|||
|
midievent::print ( void ) const
|
|||
|
{
|
|||
|
printf( "[%06f] %02X %02X %02X\n",
|
|||
|
_timestamp,
|
|||
|
_data.status,
|
|||
|
_data.lsb,
|
|||
|
_data.msb );
|
|||
|
}
|
|||
|
|
|||
|
/** print event in english/decimal */
|
|||
|
void
|
|||
|
midievent::pretty_print ( void ) const
|
|||
|
{
|
|||
|
printf(
|
|||
|
"[%06f] %-15s c: %2d d1: %3d d2: %3d\n",
|
|||
|
_timestamp,
|
|||
|
name(),
|
|||
|
channel(),
|
|||
|
_data.lsb,
|
|||
|
_data.msb );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*********/
|
|||
|
/* Sysex */
|
|||
|
/*********/
|
|||
|
|
|||
|
midievent::sysex::sysex ( void )
|
|||
|
{
|
|||
|
_data = NULL;
|
|||
|
_size = 0;
|
|||
|
_alloc = 0;
|
|||
|
}
|
|||
|
|
|||
|
midievent::sysex::~sysex ( void )
|
|||
|
{
|
|||
|
if ( _data )
|
|||
|
free( _data );
|
|||
|
|
|||
|
_data = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/** add bytes to sysex message */
|
|||
|
void
|
|||
|
midievent::sysex::append ( byte_t *data, size_t size )
|
|||
|
{
|
|||
|
if ( _size + size > _alloc )
|
|||
|
_data = (byte_t *)realloc( _data, _alloc += 256 );
|
|||
|
|
|||
|
memcpy( data + _size, data, size );
|
|||
|
|
|||
|
_size += size;
|
|||
|
}
|
|||
|
|
|||
|
/** return SysEx data */
|
|||
|
const byte_t *
|
|||
|
midievent::sysex::data ( void ) const
|
|||
|
{
|
|||
|
return _data;
|
|||
|
}
|
|||
|
|
|||
|
long
|
|||
|
midievent::sysex::size ( void ) const
|
|||
|
{
|
|||
|
return _size;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
bool
|
|||
|
midievent::operator== ( const midievent &rhs ) const
|
|||
|
{
|
|||
|
return _timestamp == rhs._timestamp &&
|
|||
|
! bcmp( (void*)&_data, (void*)&rhs._data, size() );
|
|||
|
}
|
|||
|
}
|