222 lines
5.0 KiB
C
222 lines
5.0 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 );
|
||
}
|
||
|
||
byte_t
|
||
midievent::size ( void ) const
|
||
{
|
||
return midievent::event_size( opcode() );
|
||
}
|
||
|
||
void
|
||
midievent::note_velocity ( byte_t vel )
|
||
{
|
||
_data.msb = vel & 0x7F;
|
||
}
|
||
|
||
byte_t
|
||
midievent::note ( void ) const
|
||
{
|
||
return _data.lsb;
|
||
}
|
||
|
||
void
|
||
midievent::note ( char note )
|
||
{
|
||
_data.lsb = note & 0x7F;
|
||
}
|
||
|
||
byte_t
|
||
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() );
|
||
}
|
||
}
|