non/nonlib/MIDI/midievent.C

216 lines
4.9 KiB
C++
Raw Normal View History

/*******************************************************************************/
/* 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() );
}
}