From ae7fcd43a6feafc4affbf65d8c8ee46906651c11 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 27 Aug 2016 01:39:50 +0000 Subject: [PATCH] Windows MIDI cleanup. Removal of some remaining unused functionality lingering from the DOS days and some formatting changes that happened along the way. If anything breaks with music on Windows, this is probably the commit to look at. git-svn-id: https://svn.eduke32.com/eduke32@5817 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/_midi.h | 235 +-- polymer/eduke32/source/jaudiolib/src/fx_man.c | 37 +- polymer/eduke32/source/midi.c | 1265 +++++------------ polymer/eduke32/source/midi.h | 25 +- polymer/eduke32/source/music.c | 28 +- 5 files changed, 423 insertions(+), 1167 deletions(-) diff --git a/polymer/eduke32/source/_midi.h b/polymer/eduke32/source/_midi.h index 164d1be21..84ae5bf25 100644 --- a/polymer/eduke32/source/_midi.h +++ b/polymer/eduke32/source/_midi.h @@ -1,10 +1,12 @@ +//------------------------------------------------------------------------- /* -Copyright (C) 1994-1995 Apogee Software, Ltd. +Copyright (C) 2016 EDuke32 developers and contributors -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 file is part of EDuke32. + +EDuke32 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,20 +17,8 @@ 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) - */ -/********************************************************************** - module: _MIDI.H - - author: James R. Dose - date: May 25, 1994 - - Private header for MIDI.C. Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ +//------------------------------------------------------------------------- #ifndef ___MIDI_H #define ___MIDI_H @@ -103,180 +93,55 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #define EMIDI_GeneralMIDI 0 -#define EMIDI_AffectsCurrentCard( c, type ) \ - ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) ) - - +#define EMIDI_AffectsCurrentCard(c, type) (((c) == EMIDI_ALL_CARDS) || ((c) == (type))) #define EMIDI_NUM_CONTEXTS 7 -typedef struct - { - char *pos; - char *loopstart; - int16_t loopcount; - int16_t RunningStatus; - unsigned time; - int32_t FPSecondsPerTick; - int16_t tick; - int16_t beat; - int16_t measure; - int16_t BeatsPerMeasure; - int16_t TicksPerBeat; - int16_t TimeBase; - int32_t delay; - int16_t active; - } songcontext; typedef struct - { - char *start; - char *pos; +{ + char *pos; + char *loopstart; + int16_t loopcount; + int16_t RunningStatus; + unsigned time; + int32_t FPSecondsPerTick; + int16_t tick; + int16_t beat; + int16_t measure; + int16_t BeatsPerMeasure; + int16_t TicksPerBeat; + int16_t TimeBase; + int32_t delay; + int16_t active; +} songcontext; - int32_t delay; - int16_t active; - int16_t RunningStatus; +typedef struct +{ + char *start; + char *pos; - int16_t currentcontext; - songcontext context[ EMIDI_NUM_CONTEXTS ]; + int32_t delay; + int16_t active; + int16_t RunningStatus; - char EMIDI_IncludeTrack; - char EMIDI_ProgramChange; - char EMIDI_VolumeChange; - } track; + int16_t currentcontext; + songcontext context[EMIDI_NUM_CONTEXTS]; -static int32_t _MIDI_ReadNumber( void *from, size_t size ); -static int32_t _MIDI_ReadDelta( track *ptr ); -static void _MIDI_ResetTracks( void ); -static void _MIDI_AdvanceTick( void ); -static void _MIDI_MetaEvent( track *Track ); -static void _MIDI_SysEx( track *Track ); -static int32_t _MIDI_InterpretControllerInfo( track *Track, int32_t TimeSet, - int32_t channel, int32_t c1, int32_t c2 ); -static int32_t _MIDI_SendControlChange( int32_t channel, int32_t c1, int32_t c2 ); -static void _MIDI_SetChannelVolume( int32_t channel, int32_t volume ); -static void _MIDI_SendChannelVolumes( void ); -static int32_t _MIDI_ProcessNextTick( void ); -static void _MIDI_InitEMIDI( void ); + char EMIDI_IncludeTrack; + char EMIDI_ProgramChange; + char EMIDI_VolumeChange; +} track; -/* - if ( c1 == EMIDI_LOOP_START ) - { - if ( c2 == 0 ) - { - Track->context[ 0 ].loopcount = EMIDI_INFINITE; - } - else - { - Track->context[ 0 ].loopcount = c2; - } - - Track->context[ 0 ].pos = Track->pos; - Track->context[ 0 ].loopstart = Track->pos; - Track->context[ 0 ].RunningStatus = Track->RunningStatus; - Track->context[ 0 ].time = _MIDI_Time; - Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - Track->context[ 0 ].tick = _MIDI_Tick; - Track->context[ 0 ].beat = _MIDI_Beat; - Track->context[ 0 ].measure = _MIDI_Measure; - Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; - Track->context[ 0 ].TimeBase = _MIDI_TimeBase; - break; - } - - if ( ( c1 == EMIDI_LOOP_END ) && - ( c2 == EMIDI_END_LOOP_VALUE ) ) - { - if ( ( Track->context[ 0 ].loopstart != NULL ) && - ( Track->context[ 0 ].loopcount != 0 ) ) - { - if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE ) - { - Track->context[ 0 ].loopcount--; - } - - Track->pos = Track->context[ 0 ].loopstart; - Track->RunningStatus = Track->context[ 0 ].RunningStatus; - - if ( !TimeSet ) - { - _MIDI_Time = Track->context[ 0 ].time; - _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick; - _MIDI_Tick = Track->context[ 0 ].tick; - _MIDI_Beat = Track->context[ 0 ].beat; - _MIDI_Measure = Track->context[ 0 ].measure; - _MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure; - _MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat; - _MIDI_TimeBase = Track->context[ 0 ].TimeBase; - TimeSet = TRUE; - } - } - break; - } - - if ( c1 == MIDI_MONO_MODE_ON ) - { - Track->pos++; - } - - if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) ) - { - _MIDI_SetChannelVolume( channel, c2 ); - break; - } - else if ( ( c1 == EMIDI_VOLUME_CHANGE ) && - ( Track->EMIDI_VolumeChange ) ) - { - _MIDI_SetChannelVolume( channel, c2 ); - break; - } - - if ( ( c1 == EMIDI_PROGRAM_CHANGE ) && - ( Track->EMIDI_ProgramChange ) ) - { - _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] ); - break; - } - - if ( c1 == EMIDI_CONTEXT_START ) - { - break; - } - - if ( c1 == EMIDI_CONTEXT_END ) - { - if ( ( Track->currentcontext != _MIDI_Context ) || - ( Track->context[ _MIDI_Context ].pos == NULL ) - { - break; - } - - Track->currentcontext = _MIDI_Context; - Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; - Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; - Track->pos = Track->context[ _MIDI_Context ].pos; - Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; - - if ( TimeSet ) - { - break; - } - - _MIDI_Time = Track->context[ _MIDI_Context ].time; - _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; - _MIDI_Tick = Track->context[ _MIDI_Context ].tick; - _MIDI_Beat = Track->context[ _MIDI_Context ].beat; - _MIDI_Measure = Track->context[ _MIDI_Context ].measure; - _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; - _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; - _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; - TimeSet = TRUE; - break; - } - - if ( _MIDI_Funcs->ControlChange ) - { - _MIDI_Funcs->ControlChange( channel, c1, c2 ); - } - */ +static int32_t _MIDI_ReadNumber(void *from, size_t size); +static int32_t _MIDI_ReadDelta(track *ptr); +static void _MIDI_ResetTracks(void); +static void _MIDI_AdvanceTick(void); +static void _MIDI_MetaEvent(track *Track); +static void _MIDI_SysEx(track *Track); +static int32_t _MIDI_InterpretControllerInfo(track *Track, int32_t TimeSet, int32_t channel, int32_t c1, int32_t c2); +static int32_t _MIDI_SendControlChange(int32_t channel, int32_t c1, int32_t c2); +static void _MIDI_SetChannelVolume(int32_t channel, int32_t volume); +static void _MIDI_SendChannelVolumes(void); +static int32_t _MIDI_ProcessNextTick(void); +static void _MIDI_InitEMIDI(void); #endif diff --git a/polymer/eduke32/source/jaudiolib/src/fx_man.c b/polymer/eduke32/source/jaudiolib/src/fx_man.c index 7b0f37762..aaad679a3 100644 --- a/polymer/eduke32/source/jaudiolib/src/fx_man.c +++ b/polymer/eduke32/source/jaudiolib/src/fx_man.c @@ -1,12 +1,12 @@ +//------------------------------------------------------------------------- /* -Copyright (C) 1994-1995 Apogee Software, Ltd. -Copyright (C) 2015 EDuke32 developers -Copyright (C) 2015 Voidpoint, LLC +Copyright (C) 2016 EDuke32 developers and contributors -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 file is part of EDuke32. + +EDuke32 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,18 +17,8 @@ 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -/********************************************************************** - module: FX_MAN.C - - author: James R. Dose - date: March 17, 1994 - - Device independant sound effect routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ +//------------------------------------------------------------------------- #include "compat.h" #include @@ -48,13 +38,10 @@ const char *FX_ErrorString(int32_t ErrorNumber) switch (ErrorNumber) { case FX_Warning: - case FX_Error: ErrorString = FX_ErrorString(FX_ErrorCode); break; - - case FX_Ok: ErrorString = "Fx ok."; break; - - case FX_MultiVocError: ErrorString = MV_ErrorString(MV_Error); break; - - default: ErrorString = "Unknown Fx error code."; break; + case FX_Error: ErrorString = FX_ErrorString(FX_ErrorCode); break; + case FX_Ok: ErrorString = "Fx ok."; break; + case FX_MultiVocError: ErrorString = MV_ErrorString(MV_Error); break; + default: ErrorString = "Unknown Fx error code."; break; } return ErrorString; diff --git a/polymer/eduke32/source/midi.c b/polymer/eduke32/source/midi.c index e702444b4..87410fc08 100644 --- a/polymer/eduke32/source/midi.c +++ b/polymer/eduke32/source/midi.c @@ -51,8 +51,6 @@ static const int32_t _MIDI_CommandLengths[ NUM_MIDI_CHANNELS ] = 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 }; -static int32_t (*_MIDI_RerouteFunctions[ NUM_MIDI_CHANNELS ])(int32_t, int32_t, int32_t); - static track *_MIDI_TrackPtr = NULL; static int32_t _MIDI_TrackMemSize; static int32_t _MIDI_NumTracks; @@ -84,11 +82,6 @@ static int32_t _MIDI_ActiveTracks; static int32_t _MIDI_TotalVolume = MIDI_MaxVolume; static int32_t _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ]; -static int32_t _MIDI_UserChannelVolume[ NUM_MIDI_CHANNELS ] = -{ - 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256 -}; static midifuncs *_MIDI_Funcs = NULL; @@ -96,40 +89,14 @@ static int32_t Reset = FALSE; int32_t MIDI_Tempo = 120; -char MIDI_PatchMap[ 128 ]; - - -/********************************************************************** - - Memory locked functions: - -**********************************************************************/ - - -/*--------------------------------------------------------------------- - Function: _MIDI_ReadNumber - - Reads a variable length number from a MIDI track. ----------------------------------------------------------------------*/ - -static int32_t _MIDI_ReadNumber -( - void *from, - size_t size -) - +static int32_t _MIDI_ReadNumber(void *from, size_t size) { - char *FromPtr; - int32_t value; - if (size > 4) - { size = 4; - } - FromPtr = (char *)from; + char *FromPtr = (char *)from; + int32_t value = 0; - value = 0; while (size--) { value <<= 8; @@ -139,27 +106,17 @@ static int32_t _MIDI_ReadNumber return value; } - -/*--------------------------------------------------------------------- - Function: _MIDI_ReadDelta - - Reads a variable length encoded delta delay time from the MIDI data. ----------------------------------------------------------------------*/ - -static int32_t _MIDI_ReadDelta -( - track *ptr -) - +static int32_t _MIDI_ReadDelta(track *ptr) { - int32_t value; - char c; + int32_t value; GET_NEXT_EVENT(ptr, value); if (value & 0x80) { value &= 0x7f; + char c; + do { GET_NEXT_EVENT(ptr, c); @@ -171,22 +128,8 @@ static int32_t _MIDI_ReadDelta return value; } - -/*--------------------------------------------------------------------- - Function: _MIDI_ResetTracks - - Sets the track pointers to the beginning of the song. ----------------------------------------------------------------------*/ - -static void _MIDI_ResetTracks -( - void -) - +static void _MIDI_ResetTracks(void) { - int32_t i; - track *ptr; - _MIDI_Tick = 0; _MIDI_Beat = 1; _MIDI_Measure = 1; @@ -194,14 +137,12 @@ static void _MIDI_ResetTracks _MIDI_BeatsPerMeasure = 4; _MIDI_TicksPerBeat = _MIDI_Division; _MIDI_TimeBase = 4; - _MIDI_PositionInTicks = 0; - //_MIDI_GlobalPositionInTicks = 0; _MIDI_ActiveTracks = 0; _MIDI_Context = 0; - ptr = _MIDI_TrackPtr; - for (i = 0; i < _MIDI_NumTracks; i++) + track *ptr = _MIDI_TrackPtr; + for (int i = 0; i < _MIDI_NumTracks; ++i) { ptr->pos = ptr->start; ptr->delay = _MIDI_ReadDelta(ptr); @@ -212,26 +153,13 @@ static void _MIDI_ResetTracks ptr->context[ 0 ].loopcount = 0; if (ptr->active) - { _MIDI_ActiveTracks++; - } ptr++; } } - -/*--------------------------------------------------------------------- - Function: _MIDI_AdvanceTick - - Increment tick counters. ----------------------------------------------------------------------*/ - -static void _MIDI_AdvanceTick -( - void -) - +static void _MIDI_AdvanceTick(void) { _MIDI_PositionInTicks++; _MIDI_Time += _MIDI_FPSecondsPerTick; @@ -249,99 +177,62 @@ static void _MIDI_AdvanceTick } } - -/*--------------------------------------------------------------------- - Function: _MIDI_SysEx - - Interpret SysEx Event. ----------------------------------------------------------------------*/ - -static void _MIDI_SysEx -( - track *Track -) - +static void _MIDI_SysEx(track *Track) { - int32_t length; - - length = _MIDI_ReadDelta(Track); + int32_t length = _MIDI_ReadDelta(Track); Track->pos += length; } -/*--------------------------------------------------------------------- - Function: _MIDI_MetaEvent - - Interpret Meta Event. ----------------------------------------------------------------------*/ - -static void _MIDI_MetaEvent -( - track *Track -) - +static void _MIDI_MetaEvent(track *Track) { int32_t command; int32_t length; - int32_t denominator; - int32_t tempo; GET_NEXT_EVENT(Track, command); GET_NEXT_EVENT(Track, length); switch (command) { - case MIDI_END_OF_TRACK : - Track->active = FALSE; + case MIDI_END_OF_TRACK: + Track->active = FALSE; - _MIDI_ActiveTracks--; - break; + _MIDI_ActiveTracks--; + break; - case MIDI_TEMPO_CHANGE : - tempo = tabledivide32_noinline(60000000L, _MIDI_ReadNumber(Track->pos, 3)); - MIDI_SetTempo(tempo); - break; - - case MIDI_TIME_SIGNATURE : - if ((_MIDI_Tick > 0) || (_MIDI_Beat > 1)) + case MIDI_TEMPO_CHANGE: { - _MIDI_Measure++; + int32_t tempo = tabledivide32_noinline(60000000L, _MIDI_ReadNumber(Track->pos, 3)); + MIDI_SetTempo(tempo); + break; } - _MIDI_Tick = 0; - _MIDI_Beat = 1; - - _MIDI_BeatsPerMeasure = (int32_t)*Track->pos; - denominator = (int32_t)*(Track->pos + 1); - _MIDI_TimeBase = 1; - while (denominator > 0) + case MIDI_TIME_SIGNATURE: { - _MIDI_TimeBase += _MIDI_TimeBase; - denominator--; + if ((_MIDI_Tick > 0) || (_MIDI_Beat > 1)) + _MIDI_Measure++; + + _MIDI_Tick = 0; + _MIDI_Beat = 1; + _MIDI_TimeBase = 1; + _MIDI_BeatsPerMeasure = (int32_t)*Track->pos; + int32_t denominator = (int32_t) * (Track->pos + 1); + + do + { + _MIDI_TimeBase += _MIDI_TimeBase; + denominator--; + } while (denominator > 0); + + _MIDI_TicksPerBeat = tabledivide32_noinline(_MIDI_Division * 4, _MIDI_TimeBase); + break; } - _MIDI_TicksPerBeat = tabledivide32_noinline(_MIDI_Division * 4, _MIDI_TimeBase); - break; } Track->pos += length; } - -/*--------------------------------------------------------------------- - Function: _MIDI_InterpretControllerInfo - - Interprets the MIDI controller info. ----------------------------------------------------------------------*/ - -static int32_t _MIDI_InterpretControllerInfo -( - track *Track, - int32_t TimeSet, - int32_t channel, - int32_t c1, - int32_t c2 -) - +static int32_t _MIDI_InterpretControllerInfo(track *Track, int32_t TimeSet, int32_t channel, int32_t c1, int32_t c2) { track *trackptr; int32_t tracknum; @@ -349,399 +240,284 @@ static int32_t _MIDI_InterpretControllerInfo switch (c1) { - case MIDI_MONO_MODE_ON : - Track->pos++; - break; - - case MIDI_VOLUME : - if (!Track->EMIDI_VolumeChange) - { - _MIDI_SetChannelVolume(channel, c2); - } - break; - - case EMIDI_INCLUDE_TRACK : - case EMIDI_EXCLUDE_TRACK : - break; - - case EMIDI_PROGRAM_CHANGE : - if (Track->EMIDI_ProgramChange) - { - _MIDI_Funcs->ProgramChange(channel, MIDI_PatchMap[ c2 & 0x7f ]); - } - break; - - case EMIDI_VOLUME_CHANGE : - if (Track->EMIDI_VolumeChange) - { - _MIDI_SetChannelVolume(channel, c2); - } - break; - - case EMIDI_CONTEXT_START : - break; - - case EMIDI_CONTEXT_END : - if ((Track->currentcontext == _MIDI_Context) || - (_MIDI_Context < 0) || - (Track->context[ _MIDI_Context ].pos == NULL)) - { + case MIDI_MONO_MODE_ON : + Track->pos++; break; - } - Track->currentcontext = _MIDI_Context; - Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; - Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; - Track->pos = Track->context[ _MIDI_Context ].pos; - Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; - - if (TimeSet) - { + case MIDI_VOLUME : + if (!Track->EMIDI_VolumeChange) + _MIDI_SetChannelVolume(channel, c2); break; - } - _MIDI_Time = Track->context[ _MIDI_Context ].time; - _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; - _MIDI_Tick = Track->context[ _MIDI_Context ].tick; - _MIDI_Beat = Track->context[ _MIDI_Context ].beat; - _MIDI_Measure = Track->context[ _MIDI_Context ].measure; - _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; - _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; - _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; - TimeSet = TRUE; - break; - - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - if (c2 == 0) - { - loopcount = EMIDI_INFINITE; - } - else - { - loopcount = c2; - } - - if (c1 == EMIDI_SONG_LOOP_START) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - } - else - { - trackptr = Track; - tracknum = 1; - } - - while (tracknum > 0) - { - trackptr->context[ 0 ].loopcount = loopcount; - trackptr->context[ 0 ].pos = trackptr->pos; - trackptr->context[ 0 ].loopstart = trackptr->pos; - trackptr->context[ 0 ].RunningStatus = trackptr->RunningStatus; - trackptr->context[ 0 ].active = trackptr->active; - trackptr->context[ 0 ].delay = trackptr->delay; - trackptr->context[ 0 ].time = _MIDI_Time; - trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - trackptr->context[ 0 ].tick = _MIDI_Tick; - trackptr->context[ 0 ].beat = _MIDI_Beat; - trackptr->context[ 0 ].measure = _MIDI_Measure; - trackptr->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - trackptr->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; - trackptr->context[ 0 ].TimeBase = _MIDI_TimeBase; - trackptr++; - tracknum--; - } - break; - - case EMIDI_LOOP_END : - case EMIDI_SONG_LOOP_END : - if ((c2 != EMIDI_END_LOOP_VALUE) || - (Track->context[ 0 ].loopstart == NULL) || - (Track->context[ 0 ].loopcount == 0)) - { + case EMIDI_INCLUDE_TRACK : + case EMIDI_EXCLUDE_TRACK : break; - } - if (c1 == EMIDI_SONG_LOOP_END) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - _MIDI_ActiveTracks = 0; - } - else - { - trackptr = Track; - tracknum = 1; - _MIDI_ActiveTracks--; - } + case EMIDI_PROGRAM_CHANGE : + if (Track->EMIDI_ProgramChange) + _MIDI_Funcs->ProgramChange(channel, c2 & 0x7f); + break; - while (tracknum > 0) - { - if (trackptr->context[ 0 ].loopcount != EMIDI_INFINITE) + case EMIDI_VOLUME_CHANGE : + if (Track->EMIDI_VolumeChange) + _MIDI_SetChannelVolume(channel, c2); + break; + + case EMIDI_CONTEXT_START : + break; + + case EMIDI_CONTEXT_END : + if ((Track->currentcontext == _MIDI_Context) || (_MIDI_Context < 0) || + (Track->context[_MIDI_Context].pos == NULL)) + break; + + Track->currentcontext = _MIDI_Context; + Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; + Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; + Track->pos = Track->context[ _MIDI_Context ].pos; + Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; + + if (TimeSet) { - trackptr->context[ 0 ].loopcount--; + break; } - trackptr->pos = trackptr->context[ 0 ].loopstart; - trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus; - trackptr->delay = trackptr->context[ 0 ].delay; - trackptr->active = trackptr->context[ 0 ].active; - if (trackptr->active) + _MIDI_Time = Track->context[ _MIDI_Context ].time; + _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; + _MIDI_Tick = Track->context[ _MIDI_Context ].tick; + _MIDI_Beat = Track->context[ _MIDI_Context ].beat; + _MIDI_Measure = Track->context[ _MIDI_Context ].measure; + _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; + _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; + _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; + TimeSet = TRUE; + break; + + case EMIDI_LOOP_START : + case EMIDI_SONG_LOOP_START : + loopcount = (c2 == 0) ? EMIDI_INFINITE : c2; + + if (c1 == EMIDI_SONG_LOOP_START) { - _MIDI_ActiveTracks++; + trackptr = _MIDI_TrackPtr; + tracknum = _MIDI_NumTracks; + } + else + { + trackptr = Track; + tracknum = 1; } - if (!TimeSet) + while (tracknum > 0) { - _MIDI_Time = trackptr->context[ 0 ].time; - _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick; - _MIDI_Tick = trackptr->context[ 0 ].tick; - _MIDI_Beat = trackptr->context[ 0 ].beat; - _MIDI_Measure = trackptr->context[ 0 ].measure; - _MIDI_BeatsPerMeasure = trackptr->context[ 0 ].BeatsPerMeasure; - _MIDI_TicksPerBeat = trackptr->context[ 0 ].TicksPerBeat; - _MIDI_TimeBase = trackptr->context[ 0 ].TimeBase; - TimeSet = TRUE; + trackptr->context[ 0 ].loopcount = loopcount; + trackptr->context[ 0 ].pos = trackptr->pos; + trackptr->context[ 0 ].loopstart = trackptr->pos; + trackptr->context[ 0 ].RunningStatus = trackptr->RunningStatus; + trackptr->context[ 0 ].active = trackptr->active; + trackptr->context[ 0 ].delay = trackptr->delay; + trackptr->context[ 0 ].time = _MIDI_Time; + trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; + trackptr->context[ 0 ].tick = _MIDI_Tick; + trackptr->context[ 0 ].beat = _MIDI_Beat; + trackptr->context[ 0 ].measure = _MIDI_Measure; + trackptr->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; + trackptr->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; + trackptr->context[ 0 ].TimeBase = _MIDI_TimeBase; + trackptr++; + tracknum--; + } + break; + + case EMIDI_LOOP_END : + case EMIDI_SONG_LOOP_END : + if ((c2 != EMIDI_END_LOOP_VALUE) || (Track->context[0].loopstart == NULL) || (Track->context[0].loopcount == 0)) + break; + + if (c1 == EMIDI_SONG_LOOP_END) + { + trackptr = _MIDI_TrackPtr; + tracknum = _MIDI_NumTracks; + _MIDI_ActiveTracks = 0; + } + else + { + trackptr = Track; + tracknum = 1; + _MIDI_ActiveTracks--; } - trackptr++; - tracknum--; - } - break; + while (tracknum > 0) + { + if (trackptr->context[ 0 ].loopcount != EMIDI_INFINITE) + { + trackptr->context[ 0 ].loopcount--; + } - default : - if (_MIDI_Funcs->ControlChange) - { - _MIDI_Funcs->ControlChange(channel, c1, c2); - } + trackptr->pos = trackptr->context[ 0 ].loopstart; + trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus; + trackptr->delay = trackptr->context[ 0 ].delay; + trackptr->active = trackptr->context[ 0 ].active; + if (trackptr->active) + { + _MIDI_ActiveTracks++; + } + + if (!TimeSet) + { + _MIDI_Time = trackptr->context[ 0 ].time; + _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick; + _MIDI_Tick = trackptr->context[ 0 ].tick; + _MIDI_Beat = trackptr->context[ 0 ].beat; + _MIDI_Measure = trackptr->context[ 0 ].measure; + _MIDI_BeatsPerMeasure = trackptr->context[ 0 ].BeatsPerMeasure; + _MIDI_TicksPerBeat = trackptr->context[ 0 ].TicksPerBeat; + _MIDI_TimeBase = trackptr->context[ 0 ].TimeBase; + TimeSet = TRUE; + } + + trackptr++; + tracknum--; + } + break; + + default : + if (_MIDI_Funcs->ControlChange) + _MIDI_Funcs->ControlChange(channel, c1, c2); } return TimeSet; } - -/*--------------------------------------------------------------------- - Function: _MIDI_ServiceRoutine - - Task that interperates the MIDI data. ----------------------------------------------------------------------*/ - -static int32_t _MIDI_ServiceRoutine(void) +static void _MIDI_ServiceRoutine(void) { - int32_t event; - int32_t channel; - int32_t command; - track *Track; - int32_t tracknum; - int32_t status; - int32_t c1 = 0; - int32_t c2 = 0; - int32_t TimeSet = FALSE; + if (!_MIDI_SongActive) + return; - if (_MIDI_SongActive) + track *Track = _MIDI_TrackPtr; + int32_t tracknum = 0; + int32_t TimeSet = FALSE; + + while (tracknum < _MIDI_NumTracks) { - Track = _MIDI_TrackPtr; - tracknum = 0; - while (tracknum < _MIDI_NumTracks) + while ((Track->active) && (Track->delay == 0)) { - while ((Track->active) && (Track->delay == 0)) + int32_t event; + GET_NEXT_EVENT(Track, event); + + if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) { - GET_NEXT_EVENT(Track, event); - - if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) + switch (event) { - switch (event) - { - case MIDI_SYSEX : - case MIDI_SYSEX_CONTINUE : - _MIDI_SysEx(Track); - break; - - case MIDI_META_EVENT : - _MIDI_MetaEvent(Track); - break; - } - - if (Track->active) - { - Track->delay = _MIDI_ReadDelta(Track); - } - continue; + case MIDI_SYSEX: + case MIDI_SYSEX_CONTINUE: _MIDI_SysEx(Track); break; + case MIDI_META_EVENT: _MIDI_MetaEvent(Track); break; } - if (event & MIDI_RUNNING_STATUS) - { - Track->RunningStatus = event; - } - else - { - event = Track->RunningStatus; - Track->pos--; - } + if (Track->active) + Track->delay = _MIDI_ReadDelta(Track); + continue; + } - channel = GET_MIDI_CHANNEL(event); - command = GET_MIDI_COMMAND(event); + if (event & MIDI_RUNNING_STATUS) + Track->RunningStatus = event; + else + { + event = Track->RunningStatus; + Track->pos--; + } - if (_MIDI_CommandLengths[ command ] > 0) - { - GET_NEXT_EVENT(Track, c1); - if (_MIDI_CommandLengths[ command ] > 1) - { - GET_NEXT_EVENT(Track, c2); - } - } + int const channel = GET_MIDI_CHANNEL(event); + int const command = GET_MIDI_COMMAND(event); + int32_t c1 = 0; + int32_t c2 = 0; - if (_MIDI_RerouteFunctions[ channel ] != NULL) - { - status = _MIDI_RerouteFunctions[ channel ](event, c1, c2); + if (_MIDI_CommandLengths[ command ] > 0) + { + GET_NEXT_EVENT(Track, c1); + if (_MIDI_CommandLengths[ command ] > 1) + GET_NEXT_EVENT(Track, c2); + } - if (status == MIDI_DONT_PLAY) - { - Track->delay = _MIDI_ReadDelta(Track); - continue; - } - } - - switch (command) - { - case MIDI_NOTE_OFF : + switch (command) + { + case MIDI_NOTE_OFF: if (_MIDI_Funcs->NoteOff) - { _MIDI_Funcs->NoteOff(channel, c1, c2); - } break; - case MIDI_NOTE_ON : + case MIDI_NOTE_ON: if (_MIDI_Funcs->NoteOn) - { _MIDI_Funcs->NoteOn(channel, c1, c2); - } break; - case MIDI_POLY_AFTER_TCH : + case MIDI_POLY_AFTER_TCH: if (_MIDI_Funcs->PolyAftertouch) - { _MIDI_Funcs->PolyAftertouch(channel, c1, c2); - } break; - case MIDI_CONTROL_CHANGE : + case MIDI_CONTROL_CHANGE: TimeSet = _MIDI_InterpretControllerInfo(Track, TimeSet, channel, c1, c2); break; - case MIDI_PROGRAM_CHANGE : + case MIDI_PROGRAM_CHANGE: if ((_MIDI_Funcs->ProgramChange) && (!Track->EMIDI_ProgramChange)) - { - _MIDI_Funcs->ProgramChange(channel, MIDI_PatchMap[ c1 & 0x7f ]); - } + _MIDI_Funcs->ProgramChange(channel, c1 & 0x7f); break; - case MIDI_AFTER_TOUCH : + case MIDI_AFTER_TOUCH: if (_MIDI_Funcs->ChannelAftertouch) - { _MIDI_Funcs->ChannelAftertouch(channel, c1); - } break; - case MIDI_PITCH_BEND : + case MIDI_PITCH_BEND: if (_MIDI_Funcs->PitchBend) - { _MIDI_Funcs->PitchBend(channel, c1, c2); - } break; - default : - break; - } - - Track->delay = _MIDI_ReadDelta(Track); + default: break; } - Track->delay--; - Track++; - tracknum++; - - if (_MIDI_ActiveTracks == 0) - { - _MIDI_ResetTracks(); - if (_MIDI_Loop) - { - tracknum = 0; - Track = _MIDI_TrackPtr; - } - else - { - _MIDI_SongActive = FALSE; - break; - } - } + Track->delay = _MIDI_ReadDelta(Track); } - _MIDI_AdvanceTick(); - _MIDI_GlobalPositionInTicks++; + Track->delay--; + Track++; + tracknum++; + + if (_MIDI_ActiveTracks == 0) + { + _MIDI_ResetTracks(); + if (_MIDI_Loop) + { + tracknum = 0; + Track = _MIDI_TrackPtr; + } + else + { + _MIDI_SongActive = FALSE; + break; + } + } } - return 0; + + _MIDI_AdvanceTick(); + _MIDI_GlobalPositionInTicks++; } - -/*--------------------------------------------------------------------- - Function: _MIDI_SendControlChange - - Sends a control change to the proper device ----------------------------------------------------------------------*/ - -static int32_t _MIDI_SendControlChange -( - int32_t channel, - int32_t c1, - int32_t c2 -) - +static int32_t _MIDI_SendControlChange(int32_t channel, int32_t c1, int32_t c2) { - int32_t status; - - if (_MIDI_RerouteFunctions[ channel ] != NULL) - { - status = _MIDI_RerouteFunctions[ channel ](0xB0 + channel, - c1, c2); - if (status == MIDI_DONT_PLAY) - { - return MIDI_Ok; - } - } - - if (_MIDI_Funcs == NULL) - { + if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) return MIDI_Error; - } - - if (_MIDI_Funcs->ControlChange == NULL) - { - return MIDI_Error; - } _MIDI_Funcs->ControlChange(channel, c1, c2); return MIDI_Ok; } - -/*--------------------------------------------------------------------- - Function: MIDI_AllNotesOff - - Sends all notes off commands on all midi channels. ----------------------------------------------------------------------*/ - -int32_t MIDI_AllNotesOff -( - void -) - +int32_t MIDI_AllNotesOff(void) { - int32_t channel; - - for (channel = 0; channel < NUM_MIDI_CHANNELS; channel++) + for (int channel = 0; channel < NUM_MIDI_CHANNELS; channel++) { _MIDI_SendControlChange(channel, 0x40, 0); _MIDI_SendControlChange(channel, MIDI_ALL_NOTES_OFF, 0); @@ -751,151 +527,30 @@ int32_t MIDI_AllNotesOff return MIDI_Ok; } - -/*--------------------------------------------------------------------- - Function: _MIDI_SetChannelVolume - - Sets the volume of the specified midi channel. ----------------------------------------------------------------------*/ - -static void _MIDI_SetChannelVolume -( - int32_t channel, - int32_t volume -) - +static void _MIDI_SetChannelVolume(int32_t channel, int32_t volume) { - int32_t status; - int32_t remotevolume; - _MIDI_ChannelVolume[ channel ] = volume; - if (_MIDI_RerouteFunctions[ channel ] != NULL) - { - remotevolume = volume * _MIDI_TotalVolume; - remotevolume *= _MIDI_UserChannelVolume[ channel ]; - remotevolume = tabledivide32_noinline(remotevolume, MIDI_MaxVolume); - remotevolume >>= 8; - - status = _MIDI_RerouteFunctions[ channel ](0xB0 + channel, - MIDI_VOLUME, remotevolume); - if (status == MIDI_DONT_PLAY) - { - return; - } - } - - if (_MIDI_Funcs == NULL) - { + if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) return; - } - - if (_MIDI_Funcs->ControlChange == NULL) - { - return; - } - - // For user volume - volume *= _MIDI_UserChannelVolume[ channel ]; volume *= _MIDI_TotalVolume; volume = tabledivide32_noinline(volume, MIDI_MaxVolume); - // For user volume - volume >>= 8; - _MIDI_Funcs->ControlChange(channel, MIDI_VOLUME, volume); } - -/*--------------------------------------------------------------------- - Function: MIDI_SetUserChannelVolume - - Sets the volume of the specified midi channel. ----------------------------------------------------------------------*/ - -void MIDI_SetUserChannelVolume -( - int32_t channel, - int32_t volume -) - +static void _MIDI_SendChannelVolumes(void) { - // Convert channel from 1-16 to 0-15 - channel--; - - volume = max(0, volume); - volume = min(volume, 256); - - if ((channel >= 0) && (channel < NUM_MIDI_CHANNELS)) - { - _MIDI_UserChannelVolume[ channel ] = volume; - _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[ channel ]); - } + for (int channel = 0; channel < NUM_MIDI_CHANNELS; channel++) + _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[channel]); } - -/*--------------------------------------------------------------------- - Function: MIDI_ResetUserChannelVolume - - Sets the volume of the specified midi channel. ----------------------------------------------------------------------*/ - -void MIDI_ResetUserChannelVolume -( - void -) - +int32_t MIDI_Reset(void) { - int32_t channel; - - for (channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_UserChannelVolume[ channel ] = 256; - } - - _MIDI_SendChannelVolumes(); -} - - -/*--------------------------------------------------------------------- - Function: _MIDI_SendChannelVolumes - - Sets the volume on all the midi channels. ----------------------------------------------------------------------*/ - -static void _MIDI_SendChannelVolumes -( - void -) - -{ - int32_t channel; - - for (channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[ channel ]); - } -} - - -/*--------------------------------------------------------------------- - Function: MIDI_Reset - - Resets the MIDI device to General Midi defaults. ----------------------------------------------------------------------*/ - -int32_t MIDI_Reset -( - void -) - -{ - int32_t channel; - MIDI_AllNotesOff(); - for (channel = 0; channel < NUM_MIDI_CHANNELS; channel++) + for (int channel = 0; channel < NUM_MIDI_CHANNELS; channel++) { _MIDI_SendControlChange(channel, MIDI_RESET_ALL_CONTROLLERS, 0); _MIDI_SendControlChange(channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB); @@ -912,170 +567,67 @@ int32_t MIDI_Reset return MIDI_Ok; } - -/*--------------------------------------------------------------------- - Function: MIDI_SetVolume - - Sets the total volume of the music. ----------------------------------------------------------------------*/ - -int32_t MIDI_SetVolume -( - int32_t volume -) - +int32_t MIDI_SetVolume(int32_t volume) { - int32_t i; - if (_MIDI_Funcs == NULL) - { return MIDI_NullMidiModule; - } - - volume = min(MIDI_MaxVolume, volume); - volume = max(0, volume); - - _MIDI_TotalVolume = volume; + _MIDI_TotalVolume = max(0, min(MIDI_MaxVolume, volume)); _MIDI_SendChannelVolumes(); return MIDI_Ok; } +int32_t MIDI_GetVolume(void) { return (_MIDI_Funcs == NULL) ? MIDI_NullMidiModule : _MIDI_TotalVolume; } -/*--------------------------------------------------------------------- - Function: MIDI_GetVolume +void MIDI_SetLoopFlag(int32_t loopflag) { _MIDI_Loop = loopflag; } - Returns the total volume of the music. ----------------------------------------------------------------------*/ - -int32_t MIDI_GetVolume(void) +void MIDI_ContinueSong(void) { - return (_MIDI_Funcs == NULL) ? MIDI_NullMidiModule : _MIDI_TotalVolume; + if (!_MIDI_SongLoaded) + return; + + _MIDI_SongActive = TRUE; + MPU_Unpause(); } - - -/*--------------------------------------------------------------------- - Function: MIDI_SetLoopFlag - - Sets whether the song should loop when finished or not. ----------------------------------------------------------------------*/ - -void MIDI_SetLoopFlag -( - int32_t loopflag -) - -{ - _MIDI_Loop = loopflag; -} - - -/*--------------------------------------------------------------------- - Function: MIDI_ContinueSong - - Continues playback of a paused song. ----------------------------------------------------------------------*/ - -void MIDI_ContinueSong -( - void -) - +void MIDI_PauseSong(void) { if (_MIDI_SongLoaded) - { - _MIDI_SongActive = TRUE; - MPU_Unpause(); - } + return; + + _MIDI_SongActive = FALSE; + MIDI_AllNotesOff(); + MPU_Pause(); } +void MIDI_SetMidiFuncs(midifuncs *funcs) { _MIDI_Funcs = funcs; } -/*--------------------------------------------------------------------- - Function: MIDI_PauseSong - - Pauses playback of the current song. ----------------------------------------------------------------------*/ - -void MIDI_PauseSong -( - void -) - +void MIDI_StopSong(void) { - if (_MIDI_SongLoaded) - { - _MIDI_SongActive = FALSE; - MIDI_AllNotesOff(); - MPU_Pause(); - } + if (!_MIDI_SongLoaded) + return; + + _MIDI_SongActive = FALSE; + _MIDI_SongLoaded = FALSE; + + MIDI_Reset(); + _MIDI_ResetTracks(); + + DO_FREE_AND_NULL(_MIDI_TrackPtr); + + _MIDI_NumTracks = 0; + _MIDI_TrackMemSize = 0; + + _MIDI_TotalTime = 0; + _MIDI_TotalTicks = 0; + _MIDI_TotalBeats = 0; + _MIDI_TotalMeasures = 0; + + MPU_Reset(); } - -/*--------------------------------------------------------------------- - Function: MIDI_SetMidiFuncs - - Selects the routines that send the MIDI data to the music device. ----------------------------------------------------------------------*/ - -void MIDI_SetMidiFuncs -( - midifuncs *funcs -) - -{ - _MIDI_Funcs = funcs; -} - - -/*--------------------------------------------------------------------- - Function: MIDI_StopSong - - Stops playback of the currently playing song. ----------------------------------------------------------------------*/ - -void MIDI_StopSong -( - void -) - -{ - if (_MIDI_SongLoaded) - { - _MIDI_SongActive = FALSE; - _MIDI_SongLoaded = FALSE; - - MIDI_Reset(); - _MIDI_ResetTracks(); - - DO_FREE_AND_NULL(_MIDI_TrackPtr); - - _MIDI_NumTracks = 0; - _MIDI_TrackMemSize = 0; - - _MIDI_TotalTime = 0; - _MIDI_TotalTicks = 0; - _MIDI_TotalBeats = 0; - _MIDI_TotalMeasures = 0; - - MPU_Reset(); - } -} - - -/*--------------------------------------------------------------------- - Function: MIDI_PlaySong - - Begins playback of a MIDI song. ----------------------------------------------------------------------*/ - -int32_t MIDI_PlaySong -( - char *song, - int32_t loopflag -) - +int32_t MIDI_PlaySong(char *song, int32_t loopflag) { int32_t numtracks; int32_t format; @@ -1085,26 +637,19 @@ int32_t MIDI_PlaySong char *ptr; if (_MIDI_SongLoaded) - { MIDI_StopSong(); - } MPU_Init(MUSIC_SoundDevice); _MIDI_Loop = loopflag; if (_MIDI_Funcs == NULL) - { return MIDI_NullMidiModule; - } if (B_UNBUF32(song) != MIDI_HEADER_SIGNATURE) - { return MIDI_InvalidMidiFile; - } song += 4; - headersize = _MIDI_ReadNumber(song, 4); song += 4; format = _MIDI_ReadNumber(song, 2); @@ -1117,22 +662,19 @@ int32_t MIDI_PlaySong } if (format > MAX_FORMAT) - { return MIDI_UnknownMidiFormat; - } ptr = song + headersize; if (_MIDI_NumTracks == 0) - { return MIDI_NoTracks; - } _MIDI_TrackMemSize = _MIDI_NumTracks * sizeof(track); _MIDI_TrackPtr = (track *)Xmalloc(_MIDI_TrackMemSize); CurrentTrack = _MIDI_TrackPtr; numtracks = _MIDI_NumTracks; + while (numtracks--) { if (B_UNBUF32(ptr) != MIDI_TRACK_SIGNATURE) @@ -1155,9 +697,7 @@ int32_t MIDI_PlaySong _MIDI_ResetTracks(); if (!Reset) - { MIDI_Reset(); - } Reset = FALSE; @@ -1173,18 +713,7 @@ int32_t MIDI_PlaySong return MIDI_Ok; } - -/*--------------------------------------------------------------------- - Function: MIDI_SetTempo - - Sets the song tempo. ----------------------------------------------------------------------*/ - -void MIDI_SetTempo -( - int32_t tempo -) - +void MIDI_SetTempo(int32_t tempo) { int32_t tickspersecond; @@ -1199,152 +728,89 @@ void MIDI_SetDivision(int32_t division) MPU_SetDivision(division); } +int32_t MIDI_GetTempo(void) { return MIDI_Tempo; } -/*--------------------------------------------------------------------- - Function: MIDI_GetTempo - - Returns the song tempo. ----------------------------------------------------------------------*/ - -int32_t MIDI_GetTempo -( - void -) - +static int32_t _MIDI_ProcessNextTick(void) { - return MIDI_Tempo; -} - - -/*--------------------------------------------------------------------- - Function: _MIDI_ProcessNextTick - - Sets the position of the song pointer. ----------------------------------------------------------------------*/ - -static int32_t _MIDI_ProcessNextTick -( - void -) - -{ - int32_t event; - int32_t channel; - int32_t command; - track *Track; - int32_t tracknum; - int32_t status; - int32_t c1 = 0; - int32_t c2 = 0; int32_t TimeSet = FALSE; - Track = _MIDI_TrackPtr; - tracknum = 0; + track *Track = _MIDI_TrackPtr; + int32_t tracknum = 0; + while ((tracknum < _MIDI_NumTracks) && (Track != NULL)) { while ((Track->active) && (Track->delay == 0)) { + int32_t event; + GET_NEXT_EVENT(Track, event); if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) { switch (event) { - case MIDI_SYSEX : - case MIDI_SYSEX_CONTINUE : - _MIDI_SysEx(Track); - break; - - case MIDI_META_EVENT : - _MIDI_MetaEvent(Track); - break; + case MIDI_SYSEX: + case MIDI_SYSEX_CONTINUE: _MIDI_SysEx(Track); break; + case MIDI_META_EVENT: _MIDI_MetaEvent(Track); break; } if (Track->active) - { Track->delay = _MIDI_ReadDelta(Track); - } continue; } if (event & MIDI_RUNNING_STATUS) - { Track->RunningStatus = event; - } else { event = Track->RunningStatus; Track->pos--; } - channel = GET_MIDI_CHANNEL(event); - command = GET_MIDI_COMMAND(event); + int const channel = GET_MIDI_CHANNEL(event); + int const command = GET_MIDI_COMMAND(event); + int32_t c1 = 0; + int32_t c2 = 0; if (_MIDI_CommandLengths[ command ] > 0) { GET_NEXT_EVENT(Track, c1); + if (_MIDI_CommandLengths[ command ] > 1) - { GET_NEXT_EVENT(Track, c2); - } - } - - if (_MIDI_RerouteFunctions[ channel ] != NULL) - { - status = _MIDI_RerouteFunctions[ channel ](event, c1, c2); - - if (status == MIDI_DONT_PLAY) - { - Track->delay = _MIDI_ReadDelta(Track); - continue; - } } switch (command) { - case MIDI_NOTE_OFF : - break; + case MIDI_NOTE_OFF: + case MIDI_NOTE_ON: break; - case MIDI_NOTE_ON : - break; + case MIDI_POLY_AFTER_TCH: + if (_MIDI_Funcs->PolyAftertouch) + _MIDI_Funcs->PolyAftertouch(channel, c1, c2); + break; - case MIDI_POLY_AFTER_TCH : - if (_MIDI_Funcs->PolyAftertouch) - { - _MIDI_Funcs->PolyAftertouch(channel, c1, c2); - } - break; + case MIDI_CONTROL_CHANGE: + TimeSet = _MIDI_InterpretControllerInfo(Track, TimeSet, channel, c1, c2); + break; - case MIDI_CONTROL_CHANGE : - TimeSet = _MIDI_InterpretControllerInfo(Track, TimeSet, - channel, c1, c2); - break; + case MIDI_PROGRAM_CHANGE: + if ((_MIDI_Funcs->ProgramChange) && (!Track->EMIDI_ProgramChange)) + _MIDI_Funcs->ProgramChange(channel, c1); + break; - case MIDI_PROGRAM_CHANGE : - if ((_MIDI_Funcs->ProgramChange) && - (!Track->EMIDI_ProgramChange)) - { - _MIDI_Funcs->ProgramChange(channel, c1); - } - break; + case MIDI_AFTER_TOUCH: + if (_MIDI_Funcs->ChannelAftertouch) + _MIDI_Funcs->ChannelAftertouch(channel, c1); + break; - case MIDI_AFTER_TOUCH : - if (_MIDI_Funcs->ChannelAftertouch) - { - _MIDI_Funcs->ChannelAftertouch(channel, c1); - } - break; + case MIDI_PITCH_BEND: + if (_MIDI_Funcs->PitchBend) + _MIDI_Funcs->PitchBend(channel, c1, c2); + break; - case MIDI_PITCH_BEND : - if (_MIDI_Funcs->PitchBend) - { - _MIDI_Funcs->PitchBend(channel, c1, c2); - } - break; - - default : - break; + default: break; } Track->delay = _MIDI_ReadDelta(Track); @@ -1355,9 +821,7 @@ static int32_t _MIDI_ProcessNextTick tracknum++; if (_MIDI_ActiveTracks == 0) - { break; - } } _MIDI_AdvanceTick(); @@ -1366,30 +830,9 @@ static int32_t _MIDI_ProcessNextTick } -/*--------------------------------------------------------------------- - Function: MIDI_InitEMIDI - - Sets up the EMIDI ----------------------------------------------------------------------*/ - -static void _MIDI_InitEMIDI -( - void -) - +static void _MIDI_InitEMIDI(void) { - int32_t event; - int32_t command; -// int32_t channel; - int32_t length; - int32_t IncludeFound; - track *Track; - int32_t tracknum; - int32_t type; - int32_t c1; - int32_t c2; - - type = EMIDI_GeneralMIDI; + int32_t type = EMIDI_GeneralMIDI; _MIDI_ResetTracks(); @@ -1398,8 +841,9 @@ static void _MIDI_InitEMIDI _MIDI_TotalBeats = 0; _MIDI_TotalMeasures = 0; - Track = _MIDI_TrackPtr; - tracknum = 0; + track *Track = _MIDI_TrackPtr; + int32_t tracknum = 0; + while ((tracknum < _MIDI_NumTracks) && (Track != NULL)) { _MIDI_Tick = 0; @@ -1429,23 +873,21 @@ static void _MIDI_InitEMIDI Track->delay--; } - IncludeFound = FALSE; + int32_t IncludeFound = FALSE; + while (Track->active) { + int32_t event; + GET_NEXT_EVENT(Track, event); if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) { switch (event) { - case MIDI_SYSEX : - case MIDI_SYSEX_CONTINUE : - _MIDI_SysEx(Track); - break; - - case MIDI_META_EVENT : - _MIDI_MetaEvent(Track); - break; + case MIDI_SYSEX: + case MIDI_SYSEX_CONTINUE: _MIDI_SysEx(Track); break; + case MIDI_META_EVENT: _MIDI_MetaEvent(Track); break; } if (Track->active) @@ -1462,9 +904,7 @@ static void _MIDI_InitEMIDI } if (event & MIDI_RUNNING_STATUS) - { Track->RunningStatus = event; - } else { event = Track->RunningStatus; @@ -1472,15 +912,15 @@ static void _MIDI_InitEMIDI } // channel = GET_MIDI_CHANNEL(event); - command = GET_MIDI_COMMAND(event); - length = _MIDI_CommandLengths[ command ]; + int const command = GET_MIDI_COMMAND(event); + int length = _MIDI_CommandLengths[ command ]; if (command == MIDI_CONTROL_CHANGE) { if (*Track->pos == MIDI_MONO_MODE_ON) - { length++; - } + + int32_t c1, c2; GET_NEXT_EVENT(Track, c1); GET_NEXT_EVENT(Track, c2); length -= 2; @@ -1489,15 +929,7 @@ static void _MIDI_InitEMIDI { case EMIDI_LOOP_START : case EMIDI_SONG_LOOP_START : - if (c2 == 0) - { - Track->context[ 0 ].loopcount = EMIDI_INFINITE; - } - else - { - Track->context[ 0 ].loopcount = c2; - } - + Track->context[ 0 ].loopcount = (c2 == 0) ? EMIDI_INFINITE : c2; Track->context[ 0 ].pos = Track->pos; Track->context[ 0 ].loopstart = Track->pos; Track->context[ 0 ].RunningStatus = Track->RunningStatus; @@ -1590,11 +1022,10 @@ static void _MIDI_InitEMIDI _MIDI_TotalTime = max(_MIDI_TotalTime, _MIDI_Time); if (RELATIVE_BEAT(_MIDI_Measure, _MIDI_Beat, _MIDI_Tick) > - RELATIVE_BEAT(_MIDI_TotalMeasures, _MIDI_TotalBeats, - _MIDI_TotalTicks)) + RELATIVE_BEAT(_MIDI_TotalMeasures, _MIDI_TotalBeats, _MIDI_TotalTicks)) { - _MIDI_TotalTicks = _MIDI_Tick; - _MIDI_TotalBeats = _MIDI_Beat; + _MIDI_TotalTicks = _MIDI_Tick; + _MIDI_TotalBeats = _MIDI_Beat; _MIDI_TotalMeasures = _MIDI_Measure; } diff --git a/polymer/eduke32/source/midi.h b/polymer/eduke32/source/midi.h index 0efacb205..a38fd3503 100644 --- a/polymer/eduke32/source/midi.h +++ b/polymer/eduke32/source/midi.h @@ -1,10 +1,12 @@ +//------------------------------------------------------------------------- /* -Copyright (C) 1994-1995 Apogee Software, Ltd. +Copyright (C) 2016 EDuke32 developers and contributors -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 file is part of EDuke32. + +EDuke32 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,19 +17,8 @@ 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; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) */ -/********************************************************************** - module: MIDI.H - - author: James R. Dose - date: May 25, 1994 - - Public header for MIDI.C. Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ +//------------------------------------------------------------------------- #ifndef __MIDI_H #define __MIDI_H diff --git a/polymer/eduke32/source/music.c b/polymer/eduke32/source/music.c index 622ffc049..7d10a1e36 100644 --- a/polymer/eduke32/source/music.c +++ b/polymer/eduke32/source/music.c @@ -1,6 +1,6 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2010 EDuke32 developers and contributors +Copyright (C) 2016 EDuke32 developers and contributors This file is part of EDuke32. @@ -20,17 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- -/********************************************************************** - module: MUSIC.C - - author: James R. Dose - date: March 25, 1994 - - Device independant music playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - #include #include #include "music.h" @@ -61,20 +50,16 @@ int32_t MUSIC_InitMidi(int32_t card, midifuncs *Funcs, int32_t Address); #define MUSIC_SetErrorCode(status) MUSIC_ErrorCode = (status); const char *MUSIC_ErrorString(int32_t ErrorNumber) - { const char *ErrorString; switch (ErrorNumber) { case MUSIC_Warning: - case MUSIC_Error: ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode); break; - - case MUSIC_Ok: ErrorString = "Music ok."; break; - - case MUSIC_MidiError: ErrorString = "Error playing MIDI file."; break; - - default: ErrorString = "Unknown Music error code."; break; + case MUSIC_Error: ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode); break; + case MUSIC_Ok: ErrorString = "Music ok."; break; + case MUSIC_MidiError: ErrorString = "Error playing MIDI file."; break; + default: ErrorString = "Unknown Music error code."; break; } return ErrorString; @@ -83,9 +68,6 @@ const char *MUSIC_ErrorString(int32_t ErrorNumber) int32_t MUSIC_Init(int32_t SoundCard, int32_t Address) { - for (int i = 0; i < 128; i++) - MIDI_PatchMap[i] = i; - MUSIC_SoundDevice = SoundCard; return MUSIC_InitMidi(SoundCard, &MUSIC_MidiFunctions, Address);