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 <stdio.h> @@ -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 <stdio.h> #include <stdlib.h> #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);