From 75d2e81e980094b705dcd7c9456631efa1576599 Mon Sep 17 00:00:00 2001 From: nukeykt Date: Sat, 8 Jun 2019 21:25:39 +0900 Subject: [PATCH] Move midi stuff to audiolib # Conflicts: # platform/Windows/eduke32.vcxproj # platform/Windows/nblood.vcxproj.filters # source/audiolib/include/al_midi.h # source/audiolib/include/opl3.h # source/audiolib/include/oplmidi.h # source/audiolib/src/_al_midi.h # source/audiolib/src/_oplmidi.h # source/audiolib/src/al_midi.cpp # source/audiolib/src/opl3.cpp # source/audiolib/src/oplmidi.cpp # source/duke3d/Dependencies.mak # source/duke3d/src/sdlmusic.cpp --- GNUmakefile | 31 +- platform/Windows/audiolib.vcxproj | 21 + platform/Windows/audiolib.vcxproj.filters | 48 + platform/Windows/eduke32.vcxproj | 11 - platform/Windows/eduke32.vcxproj.filters | 18 - platform/Windows/nblood.vcxproj | 7 - platform/Windows/nblood.vcxproj.filters | 21 - platform/Windows/rednukem.vcxproj | 11 - platform/Windows/rednukem.vcxproj.filters | 18 - source/{blood/src => audiolib/include}/midi.h | 0 .../{blood/src => audiolib/include}/mpu401.h | 0 source/{blood => audiolib}/src/_midi.h | 0 source/{blood => audiolib}/src/gmtimbre.cpp | 0 source/{blood => audiolib}/src/midi.cpp | 0 source/{blood => audiolib}/src/mpu401.cpp | 0 source/{blood => audiolib}/src/music.cpp | 0 source/{blood => audiolib}/src/sdlmusic.cpp | 0 source/blood/Dependencies.mak | 14 +- source/duke3d/src/_midi.h | 147 --- source/duke3d/src/midi.cpp | 952 ------------------ source/duke3d/src/midi.h | 87 -- source/duke3d/src/mpu401.cpp | 496 --------- source/duke3d/src/mpu401.h | 68 -- source/duke3d/src/music.cpp | 125 --- source/duke3d/src/sdlmusic.cpp | 483 --------- source/rr/Dependencies.mak | 4 - source/rr/src/_midi.h | 147 --- source/rr/src/midi.cpp | 952 ------------------ source/rr/src/midi.h | 87 -- source/rr/src/mpu401.cpp | 496 --------- source/rr/src/mpu401.h | 68 -- source/rr/src/music.cpp | 125 --- source/rr/src/sdlmusic.cpp | 481 --------- 33 files changed, 79 insertions(+), 4839 deletions(-) rename source/{blood/src => audiolib/include}/midi.h (100%) rename source/{blood/src => audiolib/include}/mpu401.h (100%) rename source/{blood => audiolib}/src/_midi.h (100%) rename source/{blood => audiolib}/src/gmtimbre.cpp (100%) rename source/{blood => audiolib}/src/midi.cpp (100%) rename source/{blood => audiolib}/src/mpu401.cpp (100%) rename source/{blood => audiolib}/src/music.cpp (100%) rename source/{blood => audiolib}/src/sdlmusic.cpp (100%) delete mode 100644 source/duke3d/src/_midi.h delete mode 100644 source/duke3d/src/midi.cpp delete mode 100644 source/duke3d/src/midi.h delete mode 100644 source/duke3d/src/mpu401.cpp delete mode 100644 source/duke3d/src/mpu401.h delete mode 100644 source/duke3d/src/music.cpp delete mode 100644 source/duke3d/src/sdlmusic.cpp delete mode 100644 source/rr/src/_midi.h delete mode 100644 source/rr/src/midi.cpp delete mode 100644 source/rr/src/midi.h delete mode 100644 source/rr/src/mpu401.cpp delete mode 100644 source/rr/src/mpu401.h delete mode 100644 source/rr/src/music.cpp delete mode 100644 source/rr/src/sdlmusic.cpp diff --git a/GNUmakefile b/GNUmakefile index 31285243f..4fc5ff6f6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -369,6 +369,9 @@ audiolib_objs := \ xa.cpp \ xmp.cpp \ driver_nosound.cpp \ + al_midi.cpp \ + gmtimbre.cpp \ + opl3.cpp \ audiolib_root := $(source)/$(audiolib) audiolib_src := $(audiolib_root)/src @@ -381,7 +384,7 @@ audiolib_deps := ifeq ($(PLATFORM),WINDOWS) ifeq ($(MIXERTYPE),WIN) - audiolib_objs += driver_directsound.cpp + audiolib_objs += driver_directsound.cpp music.cpp midi.cpp mpu401.cpp endif endif @@ -389,7 +392,7 @@ ifeq ($(MIXERTYPE),SDL) ifeq (,$(filter $(PLATFORM),DARWIN WINDOWS WII)) audiolib_cflags += `$(PKG_CONFIG) --cflags vorbis` endif - audiolib_objs += driver_sdl.cpp + audiolib_objs += driver_sdl.cpp sdlmusic.cpp endif ifneq (0,$(HAVE_XMP)) @@ -519,7 +522,7 @@ duke3d_cflags := -I$(duke3d_src) common_editor_deps := duke3d_common_editor engine_editor -duke3d_game_deps := duke3d_common_midi audiolib mact +duke3d_game_deps := audiolib mact duke3d_editor_deps := audiolib ifneq (0,$(NETCODE)) @@ -703,7 +706,6 @@ ifeq ($(PLATFORM),WINDOWS) endif ifeq ($(MIXERTYPE),WIN) LIBS += -ldsound - duke3d_common_midi_objs := music.cpp midi.cpp mpu401.cpp endif endif @@ -720,9 +722,6 @@ ifeq ($(RENDERTYPE),SDL) duke3d_game_rsrc_objs += game_icon.c duke3d_editor_rsrc_objs += build_icon.c endif -ifeq ($(MIXERTYPE),SDL) - duke3d_common_midi_objs := sdlmusic.cpp -endif #### Blood @@ -740,7 +739,7 @@ blood_obj := $(obj)/$(blood) blood_cflags := -I$(blood_src) -blood_game_deps := blood_common_midi audiolib mact libsmackerdec +blood_game_deps := audiolib mact libsmackerdec ifneq (0,$(NETCODE)) blood_game_deps += enet @@ -844,9 +843,6 @@ ifeq ($(PLATFORM),WINDOWS) ifeq ($(STARTUP_WINDOW),1) blood_game_objs += startwin.game.cpp endif - ifeq ($(MIXERTYPE),WIN) - blood_common_midi_objs := music.cpp midi.cpp mpu401.cpp al_midi.cpp gmtimbre.cpp opl3.cpp - endif endif ifeq (11,$(HAVE_GTK2)$(STARTUP_WINDOW)) @@ -856,9 +852,6 @@ endif ifeq ($(RENDERTYPE),SDL) blood_game_rsrc_objs += game_icon.c endif -ifeq ($(MIXERTYPE),SDL) - blood_common_midi_objs := sdlmusic.cpp oplmidi.cpp al_midi.cpp gmtimbre.cpp opl3.cpp -endif #### Redneck Rampage @@ -879,7 +872,7 @@ rr_cflags := -I$(rr_src) common_editor_deps := rr_common_editor engine_editor -rr_game_deps := rr_common_midi audiolib mact +rr_game_deps := audiolib mact rr_editor_deps := audiolib ifneq (0,$(NETCODE)) @@ -967,9 +960,6 @@ ifeq ($(PLATFORM),WINDOWS) ifeq ($(STARTUP_WINDOW),1) rr_game_objs += startwin.game.cpp endif - ifeq ($(MIXERTYPE),WIN) - rr_common_midi_objs := music.cpp midi.cpp mpu401.cpp - endif endif ifeq ($(PLATFORM),WII) @@ -985,9 +975,6 @@ ifeq ($(RENDERTYPE),SDL) rr_game_rsrc_objs += game_icon.c rr_editor_rsrc_objs += build_icon.c endif -ifeq ($(MIXERTYPE),SDL) - rr_common_midi_objs := sdlmusic.cpp -endif #### Shadow Warrior @@ -1000,7 +987,7 @@ sw_obj := $(obj)/$(sw) sw_cflags := -I$(sw_src) -sw_game_deps := duke3d_common_midi audiolib mact +sw_game_deps := audiolib mact sw_editor_deps := audiolib sw_game := voidsw diff --git a/platform/Windows/audiolib.vcxproj b/platform/Windows/audiolib.vcxproj index 74bbd9fc6..5abd7fbb3 100644 --- a/platform/Windows/audiolib.vcxproj +++ b/platform/Windows/audiolib.vcxproj @@ -189,6 +189,7 @@ + @@ -201,25 +202,45 @@ + + + + + + + + true + true + true + true + + + + + + + + + diff --git a/platform/Windows/audiolib.vcxproj.filters b/platform/Windows/audiolib.vcxproj.filters index 076b97490..29fbe0a84 100644 --- a/platform/Windows/audiolib.vcxproj.filters +++ b/platform/Windows/audiolib.vcxproj.filters @@ -53,6 +53,30 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -85,5 +109,29 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/platform/Windows/eduke32.vcxproj b/platform/Windows/eduke32.vcxproj index d01914666..5c97e50a5 100644 --- a/platform/Windows/eduke32.vcxproj +++ b/platform/Windows/eduke32.vcxproj @@ -184,7 +184,6 @@ - @@ -195,7 +194,6 @@ - @@ -240,9 +238,6 @@ - - - @@ -254,12 +249,6 @@ - - true - true - true - true - diff --git a/platform/Windows/eduke32.vcxproj.filters b/platform/Windows/eduke32.vcxproj.filters index 4e9ad0368..e969d0f0a 100644 --- a/platform/Windows/eduke32.vcxproj.filters +++ b/platform/Windows/eduke32.vcxproj.filters @@ -132,12 +132,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -194,15 +188,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -224,9 +209,6 @@ Source Files - - Source Files - Source Files diff --git a/platform/Windows/nblood.vcxproj b/platform/Windows/nblood.vcxproj index bb9c1ec65..5a03b76f0 100644 --- a/platform/Windows/nblood.vcxproj +++ b/platform/Windows/nblood.vcxproj @@ -214,7 +214,6 @@ - @@ -222,11 +221,8 @@ - - - @@ -334,9 +330,7 @@ - - @@ -357,7 +351,6 @@ - diff --git a/platform/Windows/nblood.vcxproj.filters b/platform/Windows/nblood.vcxproj.filters index f9a20c903..ec2e71df1 100644 --- a/platform/Windows/nblood.vcxproj.filters +++ b/platform/Windows/nblood.vcxproj.filters @@ -93,15 +93,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -234,9 +225,6 @@ Source Files - - Source Files - Source Files @@ -337,15 +325,6 @@ Header Files - - Header Files - - - Header Files - - - Header Files - Header Files diff --git a/platform/Windows/rednukem.vcxproj b/platform/Windows/rednukem.vcxproj index 73e8c1908..7408d4f3b 100644 --- a/platform/Windows/rednukem.vcxproj +++ b/platform/Windows/rednukem.vcxproj @@ -184,7 +184,6 @@ - @@ -195,7 +194,6 @@ - @@ -240,9 +238,6 @@ - - - @@ -254,12 +249,6 @@ - - true - true - true - true - diff --git a/platform/Windows/rednukem.vcxproj.filters b/platform/Windows/rednukem.vcxproj.filters index add4d899c..bfdba08c9 100644 --- a/platform/Windows/rednukem.vcxproj.filters +++ b/platform/Windows/rednukem.vcxproj.filters @@ -132,12 +132,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -194,15 +188,6 @@ Source Files - - Source Files - - - Source Files - - - Source Files - Source Files @@ -224,9 +209,6 @@ Source Files - - Source Files - Source Files diff --git a/source/blood/src/midi.h b/source/audiolib/include/midi.h similarity index 100% rename from source/blood/src/midi.h rename to source/audiolib/include/midi.h diff --git a/source/blood/src/mpu401.h b/source/audiolib/include/mpu401.h similarity index 100% rename from source/blood/src/mpu401.h rename to source/audiolib/include/mpu401.h diff --git a/source/blood/src/_midi.h b/source/audiolib/src/_midi.h similarity index 100% rename from source/blood/src/_midi.h rename to source/audiolib/src/_midi.h diff --git a/source/blood/src/gmtimbre.cpp b/source/audiolib/src/gmtimbre.cpp similarity index 100% rename from source/blood/src/gmtimbre.cpp rename to source/audiolib/src/gmtimbre.cpp diff --git a/source/blood/src/midi.cpp b/source/audiolib/src/midi.cpp similarity index 100% rename from source/blood/src/midi.cpp rename to source/audiolib/src/midi.cpp diff --git a/source/blood/src/mpu401.cpp b/source/audiolib/src/mpu401.cpp similarity index 100% rename from source/blood/src/mpu401.cpp rename to source/audiolib/src/mpu401.cpp diff --git a/source/blood/src/music.cpp b/source/audiolib/src/music.cpp similarity index 100% rename from source/blood/src/music.cpp rename to source/audiolib/src/music.cpp diff --git a/source/blood/src/sdlmusic.cpp b/source/audiolib/src/sdlmusic.cpp similarity index 100% rename from source/blood/src/sdlmusic.cpp rename to source/audiolib/src/sdlmusic.cpp diff --git a/source/blood/Dependencies.mak b/source/blood/Dependencies.mak index 0794ac543..d023ac2a4 100644 --- a/source/blood/Dependencies.mak +++ b/source/blood/Dependencies.mak @@ -41,8 +41,7 @@ common_h=\ $(blood_src)/common_game.h \ $(blood_src)/blood.h \ $(blood_src)/actor.h \ - $(blood_src)/ai.h \ - $(blood_src)/al_midi.h \ + $(blood_src)/ai.h \ $(blood_src)/asound.h \ $(blood_src)/callback.h \ $(blood_src)/choke.h \ @@ -69,12 +68,9 @@ common_h=\ $(blood_src)/map2d.h \ $(blood_src)/menu.h \ $(blood_src)/messages.h \ - $(blood_src)/midi.h \ $(blood_src)/mirrors.h \ $(blood_src)/misc.h \ - $(blood_src)/mpu401.h \ $(blood_src)/network.h \ - $(blood_src)/opl3.h \ $(blood_src)/osdcmds.h \ $(blood_src)/player.h \ $(blood_src)/pqueue.h \ @@ -181,11 +177,3 @@ $(mact_obj)/control.$o: $(mact_src)/control.cpp $(mact_inc)/control.h $(mact_inc $(mact_obj)/keyboard.$o: $(mact_src)/keyboard.cpp $(mact_inc)/keyboard.h $(engine_inc)/compat.h $(engine_inc)/baselayer.h $(mact_obj)/joystick.$o: $(mact_src)/joystick.cpp $(mact_inc)/joystick.h $(engine_inc)/baselayer.h $(mact_obj)/scriplib.$o: $(mact_src)/scriplib.cpp $(mact_inc)/scriplib.h $(mact_src)/_scrplib.h $(engine_inc)/compat.h - -$(blood_obj)/al_midi.$o: $(blood_src)/al_midi.cpp $(engine_inc)/compat.h $(blood_src)/al_midi.h $(blood_src)/_al_midi.h $(blood_src)/opl3.h -$(blood_obj)/gmtimbre.$o: $(blood_src)/gmtimbre.cpp -$(blood_obj)/opl3.$o: $(blood_src)/opl3.cpp -$(blood_obj)/midi.$o: $(blood_src)/midi.cpp $(blood_src)/_midi.h $(blood_src)/midi.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h -$(blood_obj)/oplmidi.$o: $(blood_src)/oplmidi.cpp $(blood_src)/_oplmidi.h $(blood_src)/oplmidi.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h -$(blood_obj)/mpu401.$o: $(blood_src)/mpu401.cpp $(blood_src)/mpu401.h $(audiolib_inc)/music.h -$(blood_obj)/music.$o: $(blood_src)/music.cpp $(blood_src)/midi.h $(blood_src)/mpu401.h $(blood_src)/al_midi.h $(audiolib_inc)/music.h diff --git a/source/duke3d/src/_midi.h b/source/duke3d/src/_midi.h deleted file mode 100644 index fe0e600b4..000000000 --- a/source/duke3d/src/_midi.h +++ /dev/null @@ -1,147 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef ___MIDI_H -#define ___MIDI_H -#include "compat.h" - -#define RELATIVE_BEAT( measure, beat, tick ) \ - ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) ) - -//Bobby Prince thinks this may be 100 -//#define GENMIDI_DefaultVolume 100 -#define GENMIDI_DefaultVolume 90 - -#define MAX_FORMAT 1 - -#define NUM_MIDI_CHANNELS 16 - -#define TIME_PRECISION 16 - -#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd" -#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk" - -#define MIDI_VOLUME 7 -#define MIDI_PAN 10 -#define MIDI_DETUNE 94 -#define MIDI_RHYTHM_CHANNEL 9 -#define MIDI_RPN_MSB 100 -#define MIDI_RPN_LSB 101 -#define MIDI_DATAENTRY_MSB 6 -#define MIDI_DATAENTRY_LSB 38 -#define MIDI_PITCHBEND_MSB 0 -#define MIDI_PITCHBEND_LSB 0 -#define MIDI_RUNNING_STATUS 0x80 -#define MIDI_NOTE_OFF 0x8 -#define MIDI_NOTE_ON 0x9 -#define MIDI_POLY_AFTER_TCH 0xA -#define MIDI_CONTROL_CHANGE 0xB -#define MIDI_PROGRAM_CHANGE 0xC -#define MIDI_AFTER_TOUCH 0xD -#define MIDI_PITCH_BEND 0xE -#define MIDI_SPECIAL 0xF -#define MIDI_SYSEX 0xF0 -#define MIDI_SYSEX_CONTINUE 0xF7 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_TIME_SIGNATURE 0x58 -#define MIDI_RESET_ALL_CONTROLLERS 0x79 -#define MIDI_ALL_NOTES_OFF 0x7b -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_SYSTEM_RESET 0xFF - -#define GET_NEXT_EVENT( track, data ) do { \ - ( data ) = *( track )->pos; \ - ( track )->pos += 1; \ -} while (0) - -#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf ) -#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 ) - -#define EMIDI_INFINITE -1 -#define EMIDI_END_LOOP_VALUE 127 -#define EMIDI_ALL_CARDS 127 -#define EMIDI_INCLUDE_TRACK 110 -#define EMIDI_EXCLUDE_TRACK 111 -#define EMIDI_PROGRAM_CHANGE 112 -#define EMIDI_VOLUME_CHANGE 113 -#define EMIDI_CONTEXT_START 114 -#define EMIDI_CONTEXT_END 115 -#define EMIDI_LOOP_START 116 -#define EMIDI_LOOP_END 117 -#define EMIDI_SONG_LOOP_START 118 -#define EMIDI_SONG_LOOP_END 119 - -#define EMIDI_GeneralMIDI 0 - -#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; - - int32_t delay; - int16_t active; - int16_t RunningStatus; - - int16_t currentcontext; - songcontext context[EMIDI_NUM_CONTEXTS]; - - char EMIDI_IncludeTrack; - char EMIDI_ProgramChange; - char EMIDI_VolumeChange; -} track; - -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 void _MIDI_InitEMIDI(void); - -#endif diff --git a/source/duke3d/src/midi.cpp b/source/duke3d/src/midi.cpp deleted file mode 100644 index f850f7027..000000000 --- a/source/duke3d/src/midi.cpp +++ /dev/null @@ -1,952 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/********************************************************************** - module: MIDI.C - - author: James R. Dose - date: May 25, 1994 - - Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -// This object is shared by all Build games with MIDI playback! - -#include "compat.h" -#include "music.h" -#include "_midi.h" -#include "midi.h" -#include "mpu401.h" -#include "compat.h" -#include "pragmas.h" - -#include "windows_inc.h" - -extern int32_t MUSIC_SoundDevice; - -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 track *_MIDI_TrackPtr = NULL; -static int32_t _MIDI_TrackMemSize; -static int32_t _MIDI_NumTracks; - -static int32_t _MIDI_SongActive = FALSE; -static int32_t _MIDI_SongLoaded = FALSE; -static int32_t _MIDI_Loop = FALSE; - -static int32_t _MIDI_Division; -static int32_t _MIDI_Tick = 0; -static int32_t _MIDI_Beat = 1; -static int32_t _MIDI_Measure = 1; -static uint32_t _MIDI_Time; -static int32_t _MIDI_BeatsPerMeasure; -static int32_t _MIDI_TicksPerBeat; -static int32_t _MIDI_TimeBase; -static int32_t _MIDI_FPSecondsPerTick; -static uint32_t _MIDI_TotalTime; -static int32_t _MIDI_TotalTicks; -static int32_t _MIDI_TotalBeats; -static int32_t _MIDI_TotalMeasures; - -uint32_t _MIDI_PositionInTicks; -uint32_t _MIDI_GlobalPositionInTicks; - -static int32_t _MIDI_Context; - -static int32_t _MIDI_ActiveTracks; -static int32_t _MIDI_TotalVolume = MIDI_MaxVolume; - -static int32_t _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ]; - -static midifuncs *_MIDI_Funcs = NULL; - -static int32_t Reset = FALSE; - -int32_t MIDI_Tempo = 120; - -static int32_t _MIDI_ReadNumber(void *from, size_t size) -{ - if (size > 4) - size = 4; - - char *FromPtr = (char *)from; - int32_t value = 0; - - while (size--) - { - value <<= 8; - value += *FromPtr++; - } - - return value; -} - -static int32_t _MIDI_ReadDelta(track *ptr) -{ - int32_t value; - - GET_NEXT_EVENT(ptr, value); - - if (value & 0x80) - { - value &= 0x7f; - char c; - - do - { - GET_NEXT_EVENT(ptr, c); - value = (value << 7) + (c & 0x7f); - } - while (c & 0x80); - } - - return value; -} - -static void _MIDI_ResetTracks(void) -{ - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = 0; - - track *ptr = _MIDI_TrackPtr; - for (bssize_t i = 0; i < _MIDI_NumTracks; ++i) - { - ptr->pos = ptr->start; - ptr->delay = _MIDI_ReadDelta(ptr); - ptr->active = ptr->EMIDI_IncludeTrack; - ptr->RunningStatus = 0; - ptr->currentcontext = 0; - ptr->context[ 0 ].loopstart = ptr->start; - ptr->context[ 0 ].loopcount = 0; - - if (ptr->active) - _MIDI_ActiveTracks++; - - ptr++; - } -} - -static void _MIDI_AdvanceTick(void) -{ - _MIDI_PositionInTicks++; - _MIDI_Time += _MIDI_FPSecondsPerTick; - - _MIDI_Tick++; - while (_MIDI_Tick > _MIDI_TicksPerBeat) - { - _MIDI_Tick -= _MIDI_TicksPerBeat; - _MIDI_Beat++; - } - while (_MIDI_Beat > _MIDI_BeatsPerMeasure) - { - _MIDI_Beat -= _MIDI_BeatsPerMeasure; - _MIDI_Measure++; - } -} - -static void _MIDI_SysEx(track *Track) -{ - int32_t length = _MIDI_ReadDelta(Track); - Track->pos += length; -} - - -static void _MIDI_MetaEvent(track *Track) -{ - int32_t command; - int32_t length; - - GET_NEXT_EVENT(Track, command); - GET_NEXT_EVENT(Track, length); - - switch (command) - { - case MIDI_END_OF_TRACK: - Track->active = FALSE; - - _MIDI_ActiveTracks--; - break; - - case MIDI_TEMPO_CHANGE: - { - int32_t tempo = tabledivide32_noinline(60000000L, _MIDI_ReadNumber(Track->pos, 3)); - MIDI_SetTempo(tempo); - break; - } - - case MIDI_TIME_SIGNATURE: - { - 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); - - while (denominator > 0) - { - _MIDI_TimeBase += _MIDI_TimeBase; - denominator--; - } - - _MIDI_TicksPerBeat = tabledivide32_noinline(_MIDI_Division * 4, _MIDI_TimeBase); - break; - } - } - - Track->pos += length; -} - -static int32_t _MIDI_InterpretControllerInfo(track *Track, int32_t TimeSet, int32_t channel, int32_t c1, int32_t c2) -{ - track *trackptr; - int32_t tracknum; - int32_t loopcount; - - 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, 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)) - 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; - - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - loopcount = (c2 == 0) ? EMIDI_INFINITE : 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)) - break; - - if (c1 == EMIDI_SONG_LOOP_END) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - _MIDI_ActiveTracks = 0; - } - else - { - trackptr = Track; - tracknum = 1; - _MIDI_ActiveTracks--; - } - - while (tracknum > 0) - { - if (trackptr->context[ 0 ].loopcount != EMIDI_INFINITE) - { - trackptr->context[ 0 ].loopcount--; - } - - 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; -} - -static void _MIDI_ServiceRoutine(void) -{ - if (!_MIDI_SongActive) - return; - - track *Track = _MIDI_TrackPtr; - int32_t tracknum = 0; - int32_t TimeSet = FALSE; - int32_t c1 = 0; - int32_t c2 = 0; - - while (tracknum < _MIDI_NumTracks) - { - 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; - } - - if (Track->active) - Track->delay = _MIDI_ReadDelta(Track); - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - - int const channel = GET_MIDI_CHANNEL(event); - int const command = GET_MIDI_COMMAND(event); - - if (_MIDI_CommandLengths[ command ] > 0) - { - GET_NEXT_EVENT(Track, c1); - if (_MIDI_CommandLengths[ command ] > 1) - GET_NEXT_EVENT(Track, c2); - } - - switch (command) - { - case MIDI_NOTE_OFF: - if (_MIDI_Funcs->NoteOff) - _MIDI_Funcs->NoteOff(channel, c1, c2); - break; - - case MIDI_NOTE_ON: - if (_MIDI_Funcs->NoteOn) - _MIDI_Funcs->NoteOn(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_PROGRAM_CHANGE: - if ((_MIDI_Funcs->ProgramChange) && (!Track->EMIDI_ProgramChange)) - _MIDI_Funcs->ProgramChange(channel, c1 & 0x7f); - 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; - - default: break; - } - - Track->delay = _MIDI_ReadDelta(Track); - } - - Track->delay--; - Track++; - tracknum++; - - if (_MIDI_ActiveTracks == 0) - { - _MIDI_ResetTracks(); - if (_MIDI_Loop) - { - tracknum = 0; - Track = _MIDI_TrackPtr; - } - else - { - _MIDI_SongActive = FALSE; - break; - } - } - } - - _MIDI_AdvanceTick(); - _MIDI_GlobalPositionInTicks++; -} - -static int32_t _MIDI_SendControlChange(int32_t channel, int32_t c1, int32_t c2) -{ - if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) - return MIDI_Error; - - _MIDI_Funcs->ControlChange(channel, c1, c2); - - return MIDI_Ok; -} - -int32_t MIDI_AllNotesOff(void) -{ - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, 0x40, 0); - _MIDI_SendControlChange(channel, MIDI_ALL_NOTES_OFF, 0); - _MIDI_SendControlChange(channel, 0x78, 0); - } - - return MIDI_Ok; -} - -static void _MIDI_SetChannelVolume(int32_t channel, int32_t volume) -{ - _MIDI_ChannelVolume[ channel ] = volume; - - if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) - return; - - volume *= _MIDI_TotalVolume; - volume = tabledivide32_noinline(volume, MIDI_MaxVolume); - - _MIDI_Funcs->ControlChange(channel, MIDI_VOLUME, volume); -} - -static void _MIDI_SendChannelVolumes(void) -{ - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[channel]); -} - -int32_t MIDI_Reset(void) -{ - MIDI_AllNotesOff(); - - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, MIDI_RESET_ALL_CONTROLLERS, 0); - _MIDI_SendControlChange(channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB); - _MIDI_SendControlChange(channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB); - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_MSB, 2); /* Pitch Bend Sensitivity MSB */ - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_LSB, 0); /* Pitch Bend Sensitivity LSB */ - _MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume; - } - - _MIDI_SendChannelVolumes(); - - Reset = TRUE; - - return MIDI_Ok; -} - -int32_t MIDI_SetVolume(int32_t volume) -{ - if (_MIDI_Funcs == NULL) - return MIDI_NullMidiModule; - - _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; } - -void MIDI_SetLoopFlag(int32_t loopflag) { _MIDI_Loop = loopflag; } - -void MIDI_ContinueSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = TRUE; - MPU_Unpause(); -} - -void MIDI_PauseSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = FALSE; - MIDI_AllNotesOff(); - MPU_Pause(); -} - -void MIDI_SetMidiFuncs(midifuncs *funcs) { _MIDI_Funcs = funcs; } - -void MIDI_StopSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = FALSE; - _MIDI_SongLoaded = FALSE; - - MPU_Reset(); - MPU_Init(MUSIC_SoundDevice); - - 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; - -} - -int32_t MIDI_PlaySong(char *song, int32_t loopflag) -{ - int32_t numtracks; - int32_t format; - int32_t headersize; - int32_t tracklength; - track *CurrentTrack; - char *ptr; - - 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); - int32_t My_MIDI_NumTracks = _MIDI_ReadNumber(song + 2, 2); - int32_t My_MIDI_Division = _MIDI_ReadNumber(song + 4, 2); - if (My_MIDI_Division < 0) - { - // If a SMPTE time division is given, just set to 96 so no errors occur - My_MIDI_Division = 96; - } - - if (format > MAX_FORMAT) - return MIDI_UnknownMidiFormat; - - ptr = song + headersize; - - if (My_MIDI_NumTracks == 0) - return MIDI_NoTracks; - - int32_t My_MIDI_TrackMemSize = My_MIDI_NumTracks * sizeof(track); - track * My_MIDI_TrackPtr = (track *)Xmalloc(My_MIDI_TrackMemSize); - - CurrentTrack = My_MIDI_TrackPtr; - numtracks = My_MIDI_NumTracks; - - while (numtracks--) - { - if (B_UNBUF32(ptr) != MIDI_TRACK_SIGNATURE) - { - DO_FREE_AND_NULL(My_MIDI_TrackPtr); - - My_MIDI_TrackMemSize = 0; - - return MIDI_InvalidTrack; - } - - tracklength = _MIDI_ReadNumber(ptr + 4, 4); - ptr += 8; - CurrentTrack->start = ptr; - ptr += tracklength; - CurrentTrack++; - } - - // at this point we know song load is successful - - if (_MIDI_SongLoaded) - MIDI_StopSong(); - - MPU_Init(MUSIC_SoundDevice); - - _MIDI_Loop = loopflag; - _MIDI_NumTracks = My_MIDI_NumTracks; - _MIDI_Division = My_MIDI_Division; - _MIDI_TrackMemSize = My_MIDI_TrackMemSize; - _MIDI_TrackPtr = My_MIDI_TrackPtr; - - _MIDI_InitEMIDI(); - _MIDI_ResetTracks(); - - if (!Reset) - MIDI_Reset(); - - Reset = FALSE; - - MIDI_SetDivision(_MIDI_Division); - //MIDI_SetTempo( 120 ); - - _MIDI_SongLoaded = TRUE; - _MIDI_SongActive = TRUE; - - while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); - MPU_BeginPlayback(); - - return MIDI_Ok; -} - -void MIDI_SetTempo(int32_t tempo) -{ - int32_t tickspersecond; - - MIDI_Tempo = tempo; - tickspersecond = ((tempo) * _MIDI_Division)/60; - _MIDI_FPSecondsPerTick = tabledivide32_noinline(1 << TIME_PRECISION, tickspersecond); - MPU_SetTempo(tempo); -} - -void MIDI_SetDivision(int32_t division) -{ - MPU_SetDivision(division); -} - -int32_t MIDI_GetTempo(void) { return MIDI_Tempo; } - -static void _MIDI_InitEMIDI(void) -{ - int32_t type = EMIDI_GeneralMIDI; - - _MIDI_ResetTracks(); - - _MIDI_TotalTime = 0; - _MIDI_TotalTicks = 0; - _MIDI_TotalBeats = 0; - _MIDI_TotalMeasures = 0; - - track *Track = _MIDI_TrackPtr; - int32_t tracknum = 0; - - while ((tracknum < _MIDI_NumTracks) && (Track != NULL)) - { - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = -1; - - Track->RunningStatus = 0; - Track->active = TRUE; - - Track->EMIDI_ProgramChange = FALSE; - Track->EMIDI_VolumeChange = FALSE; - Track->EMIDI_IncludeTrack = TRUE; - - memset(Track->context, 0, sizeof(Track->context)); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - - 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; - } - - if (Track->active) - { - Track->delay = _MIDI_ReadDelta(Track); - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - -// channel = GET_MIDI_CHANNEL(event); - 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; - - switch (c1) - { - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - 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; - 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; - - 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; - - case EMIDI_INCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Include track %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = TRUE; - } - else if (!IncludeFound) - { - //printf( "Track excluded %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_EXCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Exclude track %d on card %d\n", tracknum, c2 ); - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_PROGRAM_CHANGE : - if (!Track->EMIDI_ProgramChange) - //printf( "Program change on track %d\n", tracknum ); - Track->EMIDI_ProgramChange = TRUE; - break; - - case EMIDI_VOLUME_CHANGE : - if (!Track->EMIDI_VolumeChange) - //printf( "Volume change on track %d\n", tracknum ); - Track->EMIDI_VolumeChange = TRUE; - break; - - case EMIDI_CONTEXT_START : - if ((c2 > 0) && (c2 < EMIDI_NUM_CONTEXTS)) - { - Track->context[ c2 ].pos = Track->pos; - Track->context[ c2 ].loopstart = Track->context[ 0 ].loopstart; - Track->context[ c2 ].loopcount = Track->context[ 0 ].loopcount; - Track->context[ c2 ].RunningStatus = Track->RunningStatus; - Track->context[ c2 ].time = _MIDI_Time; - Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - Track->context[ c2 ].tick = _MIDI_Tick; - Track->context[ c2 ].beat = _MIDI_Beat; - Track->context[ c2 ].measure = _MIDI_Measure; - Track->context[ c2 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - Track->context[ c2 ].TicksPerBeat = _MIDI_TicksPerBeat; - Track->context[ c2 ].TimeBase = _MIDI_TimeBase; - } - break; - - case EMIDI_CONTEXT_END : - break; - } - } - - Track->pos += length; - Track->delay = _MIDI_ReadDelta(Track); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - _MIDI_TotalTime = max(_MIDI_TotalTime, _MIDI_Time); - if (RELATIVE_BEAT(_MIDI_Measure, _MIDI_Beat, _MIDI_Tick) > - RELATIVE_BEAT(_MIDI_TotalMeasures, _MIDI_TotalBeats, _MIDI_TotalTicks)) - { - _MIDI_TotalTicks = _MIDI_Tick; - _MIDI_TotalBeats = _MIDI_Beat; - _MIDI_TotalMeasures = _MIDI_Measure; - } - - Track++; - tracknum++; - } - - _MIDI_ResetTracks(); -} - - -void MIDI_UpdateMusic(void) -{ - if (!_MIDI_SongLoaded || !_MIDI_SongActive) return; - while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); -} - diff --git a/source/duke3d/src/midi.h b/source/duke3d/src/midi.h deleted file mode 100644 index a38fd3503..000000000 --- a/source/duke3d/src/midi.h +++ /dev/null @@ -1,87 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef __MIDI_H -#define __MIDI_H - -enum MIDI_Errors - { - MIDI_Warning = -2, - MIDI_Error = -1, - MIDI_Ok = 0, - MIDI_NullMidiModule, - MIDI_InvalidMidiFile, - MIDI_UnknownMidiFormat, - MIDI_NoTracks, - MIDI_InvalidTrack, - MIDI_NoMemory, - MIDI_DPMI_Error - }; - - -#define MIDI_PASS_THROUGH 1 -#define MIDI_DONT_PLAY 0 - -#define MIDI_MaxVolume 255 - -extern char MIDI_PatchMap[ 128 ]; - -typedef struct -{ - void (*NoteOff)(int32_t channel, int32_t key, int32_t velocity); - void (*NoteOn)(int32_t channel, int32_t key, int32_t velocity); - void (*PolyAftertouch)(int32_t channel, int32_t key, int32_t pressure); - void (*ControlChange)(int32_t channel, int32_t number, int32_t value); - void (*ProgramChange)(int32_t channel, int32_t program); - void (*ChannelAftertouch)(int32_t channel, int32_t pressure); - void (*PitchBend)(int32_t channel, int32_t lsb, int32_t msb); - void (*FinishBuffer)(void); -} midifuncs; - -void MIDI_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) ); -int32_t MIDI_AllNotesOff( void ); -void MIDI_SetUserChannelVolume( int32_t channel, int32_t volume ); -void MIDI_ResetUserChannelVolume( void ); -int32_t MIDI_Reset( void ); -int32_t MIDI_SetVolume( int32_t volume ); -int32_t MIDI_GetVolume( void ); -void MIDI_SetMidiFuncs( midifuncs *funcs ); -void MIDI_SetContext( int32_t context ); -int32_t MIDI_GetContext( void ); -void MIDI_SetLoopFlag( int32_t loopflag ); -void MIDI_ContinueSong( void ); -void MIDI_PauseSong( void ); -int32_t MIDI_SongPlaying( void ); -void MIDI_StopSong( void ); -int32_t MIDI_PlaySong( char *song, int32_t loopflag ); -void MIDI_SetTempo( int32_t tempo ); -int32_t MIDI_GetTempo( void ); -void MIDI_SetSongTick( uint32_t PositionInTicks ); -void MIDI_SetSongTime( uint32_t milliseconds ); -void MIDI_SetSongPosition( int32_t measure, int32_t beat, int32_t tick ); -void MIDI_GetSongPosition( songposition *pos ); -void MIDI_GetSongLength( songposition *pos ); -void MIDI_LoadTimbres( void ); -void MIDI_UpdateMusic(void); -void MIDI_SetDivision( int32_t division ); - -#endif diff --git a/source/duke3d/src/mpu401.cpp b/source/duke3d/src/mpu401.cpp deleted file mode 100644 index 0c7b9b9f2..000000000 --- a/source/duke3d/src/mpu401.cpp +++ /dev/null @@ -1,496 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/********************************************************************** - module: MPU401.C - - author: James R. Dose - date: January 1, 1994 - - Low level routines to support sending of MIDI data to MPU401 - compatible MIDI interfaces. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -// This object is shared by all Build games with MIDI playback! - -#include "mpu401.h" -#include "compat.h" -#include "pragmas.h" - -#define NEED_MMSYSTEM_H -#include "windows_inc.h" - -static HMIDISTRM hmido = (HMIDISTRM)-1; -static MIDIOUTCAPS midicaps; -static DWORD mididevice = -1; - -#define PAD(x) ((((x)+3)&(~3))) - -#define BUFFERLEN (32*4*4) -#define NUMBUFFERS 6 -static char eventbuf[NUMBUFFERS][BUFFERLEN]; -static int32_t eventcnt[NUMBUFFERS]; -static MIDIHDR bufferheaders[NUMBUFFERS]; -int32_t _MPU_CurrentBuffer = 0; -int32_t _MPU_BuffersWaiting = 0; - -extern uint32_t _MIDI_GlobalPositionInTicks; -uint32_t _MPU_LastEvent=0; - -#define MIDI_NOTE_OFF 0x80 -#define MIDI_NOTE_ON 0x90 -#define MIDI_POLY_AFTER_TCH 0xA0 -#define MIDI_CONTROL_CHANGE 0xB0 -#define MIDI_PROGRAM_CHANGE 0xC0 -#define MIDI_AFTER_TOUCH 0xD0 -#define MIDI_PITCH_BEND 0xE0 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_ALL_NOTES_OFF 0x7B - - -/********************************************************************** - - Memory locked functions: - -**********************************************************************/ - - -void MPU_FinishBuffer(int32_t buffer) -{ - if (!eventcnt[buffer]) return; - ZeroMemory(&bufferheaders[buffer], sizeof(MIDIHDR)); - bufferheaders[buffer].lpData = eventbuf[buffer]; - bufferheaders[buffer].dwBufferLength = - bufferheaders[buffer].dwBytesRecorded = eventcnt[buffer]; - midiOutPrepareHeader((HMIDIOUT)hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); - midiStreamOut(hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); -// printf("Sending %d bytes (buffer %d)\n",eventcnt[buffer],buffer); - _MPU_BuffersWaiting++; -} - -void MPU_BeginPlayback(void) -{ - _MPU_LastEvent = _MIDI_GlobalPositionInTicks; - if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); -} - -void MPU_Pause(void) -{ - if (hmido != (HMIDISTRM)-1) midiStreamPause(hmido); -} - -void MPU_Unpause(void) -{ - if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); -} - - -void CALLBACK MPU_MIDICallback(HMIDIOUT handle, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) -{ - int32_t i; - - UNREFERENCED_PARAMETER(dwInstance); - UNREFERENCED_PARAMETER(dwParam2); - - switch (uMsg) - { - case MOM_DONE: - midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR *)dwParam1, sizeof(MIDIHDR)); - for (i=0; i BUFFERLEN) - { - // buffer over-full - nextbuffer = MPU_GetNextBuffer(); - if (nextbuffer < 0) - { -// printf("All buffers full!\n"); - return; - } - MPU_FinishBuffer(_MPU_CurrentBuffer); - _MPU_CurrentBuffer = nextbuffer; - } - - p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; - ((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; - ((int32_t *)p)[1] = 0; - ((int32_t *)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t *)data)) & masks[count-1]); - eventcnt[_MPU_CurrentBuffer] += 12; - } - else - { - padded = PAD(count); - if (eventcnt[_MPU_CurrentBuffer] + 12 + padded > BUFFERLEN) - { - // buffer over-full - nextbuffer = MPU_GetNextBuffer(); - if (nextbuffer < 0) - { -// printf("All buffers full!\n"); - return; - } - MPU_FinishBuffer(_MPU_CurrentBuffer); - _MPU_CurrentBuffer = nextbuffer; - } - - p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; - ((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; - ((int32_t *)p)[1] = 0; - ((int32_t *)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl); - p+=12; eventcnt[_MPU_CurrentBuffer] += 12; - for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++) - *(p++) = *(data++); - for (; padded>0; padded--, eventcnt[_MPU_CurrentBuffer]++) - *(p++) = 0; - } - _MPU_LastEvent = _MIDI_GlobalPositionInTicks; -} - - -/*--------------------------------------------------------------------- - Function: MPU_SendMidiImmediate - - Sends a MIDI message immediately to the the music device. ----------------------------------------------------------------------*/ -void MPU_SendMidiImmediate(char *data, int32_t count) -{ - MIDIHDR mhdr; - static int32_t masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl }; - - if (!count) return; - if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t *)data)) & masks[count-1]); - else - { - ZeroMemory(&mhdr, sizeof(mhdr)); - mhdr.lpData = data; - mhdr.dwBufferLength = count; - midiOutPrepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - midiOutLongMsg((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - while (!(mhdr.dwFlags & MHDR_DONE)) ; - midiOutUnprepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - } -} - - -/*--------------------------------------------------------------------- - Function: MPU_Reset - - Resets the MPU401 card. ----------------------------------------------------------------------*/ - -int32_t MPU_Reset -( - void -) - -{ - midiStreamStop(hmido); - midiStreamClose(hmido); - hmido = (HMIDISTRM)-1; - - return MPU_Ok; -} - - -/*--------------------------------------------------------------------- - Function: MPU_Init - - Detects and initializes the MPU401 card. ----------------------------------------------------------------------*/ - -int32_t MPU_Init -( - int32_t addr -) - -{ - if (hmido != (HMIDISTRM)-1) - return MPU_Ok; - - int32_t i; - - for (i=0; iNoteOff = MPU_NoteOff; - Funcs->NoteOn = MPU_NoteOn; - Funcs->PolyAftertouch = MPU_PolyAftertouch; - Funcs->ControlChange = MPU_ControlChange; - Funcs->ProgramChange = MPU_ProgramChange; - Funcs->ChannelAftertouch = MPU_ChannelAftertouch; - Funcs->PitchBend = MPU_PitchBend; - - MIDI_SetMidiFuncs(Funcs); - - return MIDI_Ok; -} - -void MUSIC_Update(void) { MIDI_UpdateMusic(); } diff --git a/source/duke3d/src/sdlmusic.cpp b/source/duke3d/src/sdlmusic.cpp deleted file mode 100644 index 5fcaa4f3f..000000000 --- a/source/duke3d/src/sdlmusic.cpp +++ /dev/null @@ -1,483 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/* - * A reimplementation of Jim Dose's FX_MAN routines, using SDL_mixer 1.2. - * Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for - * short. How strangely appropriate that seems. - */ - -// This object is shared by all Build games with MIDI playback! - -#define NEED_SDL_MIXER - -#include "compat.h" - -#include "duke3d.h" -#include "cache1d.h" - -#include "sdlayer.h" -#include "music.h" - -#include "vfs.h" - -#if !defined _WIN32 && !defined(GEKKO) -//# define FORK_EXEC_MIDI 1 -#endif - -#if defined FORK_EXEC_MIDI // fork/exec based external midi player -#include -#include -#include -static char **external_midi_argv; -static pid_t external_midi_pid=-1; -static int8_t external_midi_restart=0; -#endif - -#ifdef __ANDROID__ //TODO fix -static char const *external_midi_tempfn = APPBASENAME "-music.mid"; -#else -static char const *external_midi_tempfn = "/tmp/" APPBASENAME "-music.mid"; -#endif - -static int32_t external_midi = 0; - -int32_t MUSIC_ErrorCode = MUSIC_Ok; - -static char warningMessage[80]; -static char errorMessage[80]; - -static int32_t music_initialized = 0; -static int32_t music_context = 0; -static int32_t music_loopflag = MUSIC_PlayOnce; -static Mix_Music *music_musicchunk = NULL; - -static void setErrorMessage(const char *msg) -{ - Bstrncpyz(errorMessage, msg, sizeof(errorMessage)); -} - -// The music functions... - -const char *MUSIC_ErrorString(int32_t ErrorNumber) -{ - switch (ErrorNumber) - { - case MUSIC_Warning: - return warningMessage; - - case MUSIC_Error: - return errorMessage; - - case MUSIC_Ok: - return "OK; no error."; - - case MUSIC_MidiError: - return "MIDI error."; - - default: - return "Unknown error."; - } // switch - - return NULL; -} // MUSIC_ErrorString - -int32_t MUSIC_Init(int32_t SoundCard, int32_t Address) -{ -#ifdef __ANDROID__ - music_initialized = 1; - return MUSIC_Ok; -#endif - // Use an external MIDI player if the user has specified to do so - char *command = getenv("EDUKE32_MUSIC_CMD"); - const SDL_version *linked = Mix_Linked_Version(); - - UNREFERENCED_PARAMETER(SoundCard); - UNREFERENCED_PARAMETER(Address); - - if (music_initialized) - { - setErrorMessage("Music system is already initialized."); - return MUSIC_Error; - } // if - - if (SDL_VERSIONNUM(linked->major,linked->minor,linked->patch) < MIX_REQUIREDVERSION) - { - // reject running with SDL_Mixer versions older than what is stated in sdl_inc.h - initprintf("You need at least v%d.%d.%d of SDL_mixer for music\n",SDL_MIXER_MIN_X,SDL_MIXER_MIN_Y,SDL_MIXER_MIN_Z); - return MUSIC_Error; - } - - external_midi = (command != NULL && command[0] != 0); - - if (external_midi) - { -#if defined FORK_EXEC_MIDI - int32_t ws=1, numargs=0, pagesize=sysconf(_SC_PAGE_SIZE); - char *c, *cmd; - size_t sz; -#endif - - initprintf("Setting music command to \"%s\".\n", command); - -#if !defined FORK_EXEC_MIDI - if (Mix_SetMusicCMD(command)==-1) - { - perror("Mix_SetMusicCMD"); - goto fallback; - } -#else - - if (pagesize==-1) - goto fallback; - - for (c=command; *c; c++) - { - if (isspace(*c)) - ws = 1; - else if (ws) - { - ws = 0; - numargs++; - } - } - - if (numargs==0) - goto fallback; - - sz = (numargs+2)*sizeof(char *) + (c-command+1); - sz = ((sz+pagesize-1)/pagesize)*pagesize; -#if defined(__APPLE__) || defined(__ANDROID__) - external_midi_argv = Xcalloc(1,sz+pagesize); - external_midi_argv = (char **)((intptr_t)external_midi_argv + (pagesize-(((intptr_t)external_midi_argv)&(pagesize-1)))); -#else - if (posix_memalign((void **)&external_midi_argv, pagesize, sz)) - goto fallback; -#endif - cmd = (char *)external_midi_argv + (numargs+2)*sizeof(char *); - Bmemcpy(cmd, command, c-command+1); - - ws = 1; - numargs = 0; - for (c=cmd; *c; c++) - { - if (isspace(*c)) - { - ws = 1; - *c = 0; - } - else if (ws) - { - ws = 0; - external_midi_argv[numargs++] = c; - } - } - external_midi_argv[numargs] = external_midi_tempfn; - external_midi_argv[numargs+1] = NULL; - - if (mprotect(external_midi_argv, sz, PROT_READ)==-1) // make argv and command string read-only - { - perror("MUSIC_Init: mprotect"); - goto fallback; - } -# if 0 - { - int i; - initprintf("----Music argv:\n"); - for (i=0; i=0; i--) - { - fp = buildvfs_fopen_read(s[i]); - if (fp == NULL) - { - if (i == 0) - { - initprintf("Error: couldn't open any of the following files:\n"); - for (i = ARRAY_SIZE(s)-1; i>=0; i--) - initprintf("%s\n",s[i]); - return MUSIC_Error; - } - continue; - } - else break; - } - buildvfs_fclose(fp); - } - - music_initialized = 1; - return MUSIC_Ok; -} // MUSIC_Init - - -int32_t MUSIC_Shutdown(void) -{ - // TODO - make sure this is being called from the menu -- SA -#if !defined FORK_EXEC_MIDI - if (external_midi) - Mix_SetMusicCMD(NULL); -#endif - - MUSIC_StopSong(); - music_context = 0; - music_initialized = 0; - music_loopflag = MUSIC_PlayOnce; - - return MUSIC_Ok; -} // MUSIC_Shutdown - - -void MUSIC_SetMaxFMMidiChannel(int32_t channel) -{ - UNREFERENCED_PARAMETER(channel); -} // MUSIC_SetMaxFMMidiChannel - - -void MUSIC_SetVolume(int32_t volume) -{ - volume = max(0, volume); - volume = min(volume, 255); - - Mix_VolumeMusic(volume >> 1); // convert 0-255 to 0-128. -} // MUSIC_SetVolume - - -int32_t MUSIC_GetVolume(void) -{ - return (Mix_VolumeMusic(-1) << 1); // convert 0-128 to 0-255. -} // MUSIC_GetVolume - - -void MUSIC_SetLoopFlag(int32_t loopflag) -{ - music_loopflag = loopflag; -} // MUSIC_SetLoopFlag - - -void MUSIC_Continue(void) -{ - if (Mix_PausedMusic()) - Mix_ResumeMusic(); -} // MUSIC_Continue - - -void MUSIC_Pause(void) -{ - Mix_PauseMusic(); -} // MUSIC_Pause - -int32_t MUSIC_StopSong(void) -{ -#if defined FORK_EXEC_MIDI - if (external_midi) - { - if (external_midi_pid > 0) - { - int32_t ret; - struct timespec ts; - - external_midi_restart = 0; // make SIGCHLD handler a no-op - - ts.tv_sec = 0; - ts.tv_nsec = 5000000; // sleep 5ms at most - - kill(external_midi_pid, SIGTERM); - nanosleep(&ts, NULL); - ret = waitpid(external_midi_pid, NULL, WNOHANG|WUNTRACED); -// printf("(%d)", ret); - - if (ret != external_midi_pid) - { - if (ret==-1) - perror("waitpid"); - else - { - // we tried to be nice, but no... - kill(external_midi_pid, SIGKILL); - initprintf("%s: wait for SIGTERM timed out.\n", __func__); - if (waitpid(external_midi_pid, NULL, WUNTRACED)==-1) - perror("waitpid (2)"); - } - } - - external_midi_pid = -1; - } - - return MUSIC_Ok; - } -#endif - - //if (!fx_initialized) - if (!Mix_QuerySpec(NULL, NULL, NULL)) - { - setErrorMessage("Need FX system initialized, too. Sorry."); - return MUSIC_Error; - } // if - - if ((Mix_PlayingMusic()) || (Mix_PausedMusic())) - Mix_HaltMusic(); - - if (music_musicchunk) - Mix_FreeMusic(music_musicchunk); - - music_musicchunk = NULL; - - return MUSIC_Ok; -} // MUSIC_StopSong - -#if defined FORK_EXEC_MIDI -static int32_t playmusic() -{ - pid_t pid = vfork(); - - if (pid==-1) // error - { - initprintf("%s: vfork: %s\n", __func__, strerror(errno)); - return MUSIC_Error; - } - else if (pid==0) // child - { - // exec without PATH lookup - if (execv(external_midi_argv[0], external_midi_argv) < 0) - { - perror("execv"); - _exit(1); - } - } - else // parent - { - external_midi_pid = pid; - } - - return MUSIC_Ok; -} - -static void sigchld_handler(int signo) -{ - if (signo==SIGCHLD && external_midi_restart) - { - int status; - - if (external_midi_pid > 0) - { - if (waitpid(external_midi_pid, &status, WUNTRACED)==-1) - perror("waitpid (3)"); - - if (WIFEXITED(status) && WEXITSTATUS(status)==0) - { - // loop ... - playmusic(); - } - } - } -} -#endif - -// Duke3D-specific. --ryan. -// void MUSIC_PlayMusic(char *_filename) -int32_t MUSIC_PlaySong(char *song, int32_t songsize, int32_t loopflag) -{ - if (external_midi) - { - buildvfs_FILE fp; - -#if defined FORK_EXEC_MIDI - static int32_t sigchld_handler_set = 0; - - if (!sigchld_handler_set) - { - struct sigaction sa; - sa.sa_handler=sigchld_handler; - sa.sa_flags=0; - sigemptyset(&sa.sa_mask); - - if (sigaction(SIGCHLD, &sa, NULL)==-1) - initprintf("%s: sigaction: %s\n", __func__, strerror(errno)); - - sigchld_handler_set = 1; - } -#endif - - fp = buildvfs_fopen_write(external_midi_tempfn); - if (fp) - { - buildvfs_fwrite(song, 1, songsize, fp); - buildvfs_fclose(fp); - -#if defined FORK_EXEC_MIDI - external_midi_restart = loopflag; - int32_t retval = playmusic(); - if (retval != MUSIC_Ok) - return retval; -#else - music_musicchunk = Mix_LoadMUS(external_midi_tempfn); - if (!music_musicchunk) - { - initprintf("Mix_LoadMUS: %s\n", Mix_GetError()); - return MUSIC_Error; - } -#endif - } - else - { - initprintf("%s: fopen: %s\n", __func__, strerror(errno)); - return MUSIC_Error; - } - } - else - music_musicchunk = Mix_LoadMUS_RW(SDL_RWFromMem(song, songsize) -#if (SDL_MAJOR_VERSION > 1) - , SDL_FALSE -#endif - ); - - if (music_musicchunk == NULL) - return MUSIC_Error; - - if (Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_LoopSong)?-1:0) == -1) - { - initprintf("Mix_PlayMusic: %s\n", Mix_GetError()); - return MUSIC_Error; - } - - return MUSIC_Ok; -} - - -void MUSIC_Update(void) -{} diff --git a/source/rr/Dependencies.mak b/source/rr/Dependencies.mak index cfda9283c..4c17b7415 100644 --- a/source/rr/Dependencies.mak +++ b/source/rr/Dependencies.mak @@ -88,7 +88,3 @@ $(mact_obj)/control.$o: $(mact_src)/control.cpp $(mact_inc)/control.h $(mact_inc $(mact_obj)/keyboard.$o: $(mact_src)/keyboard.cpp $(mact_inc)/keyboard.h $(engine_inc)/compat.h $(engine_inc)/baselayer.h $(mact_obj)/joystick.$o: $(mact_src)/joystick.cpp $(mact_inc)/joystick.h $(engine_inc)/baselayer.h $(mact_obj)/scriplib.$o: $(mact_src)/scriplib.cpp $(mact_inc)/scriplib.h $(mact_src)/_scrplib.h $(engine_inc)/compat.h - -$(rr_obj)/midi.$o: $(rr_src)/midi.cpp $(rr_src)/_midi.h $(rr_src)/midi.h $(audiolib_inc)/music.h -$(rr_obj)/mpu401.$o: $(rr_src)/mpu401.cpp $(rr_src)/mpu401.h $(audiolib_inc)/music.h -$(rr_obj)/music.$o: $(rr_src)/music.cpp $(rr_src)/midi.h $(rr_src)/mpu401.h $(audiolib_inc)/music.h diff --git a/source/rr/src/_midi.h b/source/rr/src/_midi.h deleted file mode 100644 index fe0e600b4..000000000 --- a/source/rr/src/_midi.h +++ /dev/null @@ -1,147 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef ___MIDI_H -#define ___MIDI_H -#include "compat.h" - -#define RELATIVE_BEAT( measure, beat, tick ) \ - ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) ) - -//Bobby Prince thinks this may be 100 -//#define GENMIDI_DefaultVolume 100 -#define GENMIDI_DefaultVolume 90 - -#define MAX_FORMAT 1 - -#define NUM_MIDI_CHANNELS 16 - -#define TIME_PRECISION 16 - -#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd" -#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk" - -#define MIDI_VOLUME 7 -#define MIDI_PAN 10 -#define MIDI_DETUNE 94 -#define MIDI_RHYTHM_CHANNEL 9 -#define MIDI_RPN_MSB 100 -#define MIDI_RPN_LSB 101 -#define MIDI_DATAENTRY_MSB 6 -#define MIDI_DATAENTRY_LSB 38 -#define MIDI_PITCHBEND_MSB 0 -#define MIDI_PITCHBEND_LSB 0 -#define MIDI_RUNNING_STATUS 0x80 -#define MIDI_NOTE_OFF 0x8 -#define MIDI_NOTE_ON 0x9 -#define MIDI_POLY_AFTER_TCH 0xA -#define MIDI_CONTROL_CHANGE 0xB -#define MIDI_PROGRAM_CHANGE 0xC -#define MIDI_AFTER_TOUCH 0xD -#define MIDI_PITCH_BEND 0xE -#define MIDI_SPECIAL 0xF -#define MIDI_SYSEX 0xF0 -#define MIDI_SYSEX_CONTINUE 0xF7 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_TIME_SIGNATURE 0x58 -#define MIDI_RESET_ALL_CONTROLLERS 0x79 -#define MIDI_ALL_NOTES_OFF 0x7b -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_SYSTEM_RESET 0xFF - -#define GET_NEXT_EVENT( track, data ) do { \ - ( data ) = *( track )->pos; \ - ( track )->pos += 1; \ -} while (0) - -#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf ) -#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 ) - -#define EMIDI_INFINITE -1 -#define EMIDI_END_LOOP_VALUE 127 -#define EMIDI_ALL_CARDS 127 -#define EMIDI_INCLUDE_TRACK 110 -#define EMIDI_EXCLUDE_TRACK 111 -#define EMIDI_PROGRAM_CHANGE 112 -#define EMIDI_VOLUME_CHANGE 113 -#define EMIDI_CONTEXT_START 114 -#define EMIDI_CONTEXT_END 115 -#define EMIDI_LOOP_START 116 -#define EMIDI_LOOP_END 117 -#define EMIDI_SONG_LOOP_START 118 -#define EMIDI_SONG_LOOP_END 119 - -#define EMIDI_GeneralMIDI 0 - -#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; - - int32_t delay; - int16_t active; - int16_t RunningStatus; - - int16_t currentcontext; - songcontext context[EMIDI_NUM_CONTEXTS]; - - char EMIDI_IncludeTrack; - char EMIDI_ProgramChange; - char EMIDI_VolumeChange; -} track; - -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 void _MIDI_InitEMIDI(void); - -#endif diff --git a/source/rr/src/midi.cpp b/source/rr/src/midi.cpp deleted file mode 100644 index f850f7027..000000000 --- a/source/rr/src/midi.cpp +++ /dev/null @@ -1,952 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/********************************************************************** - module: MIDI.C - - author: James R. Dose - date: May 25, 1994 - - Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -// This object is shared by all Build games with MIDI playback! - -#include "compat.h" -#include "music.h" -#include "_midi.h" -#include "midi.h" -#include "mpu401.h" -#include "compat.h" -#include "pragmas.h" - -#include "windows_inc.h" - -extern int32_t MUSIC_SoundDevice; - -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 track *_MIDI_TrackPtr = NULL; -static int32_t _MIDI_TrackMemSize; -static int32_t _MIDI_NumTracks; - -static int32_t _MIDI_SongActive = FALSE; -static int32_t _MIDI_SongLoaded = FALSE; -static int32_t _MIDI_Loop = FALSE; - -static int32_t _MIDI_Division; -static int32_t _MIDI_Tick = 0; -static int32_t _MIDI_Beat = 1; -static int32_t _MIDI_Measure = 1; -static uint32_t _MIDI_Time; -static int32_t _MIDI_BeatsPerMeasure; -static int32_t _MIDI_TicksPerBeat; -static int32_t _MIDI_TimeBase; -static int32_t _MIDI_FPSecondsPerTick; -static uint32_t _MIDI_TotalTime; -static int32_t _MIDI_TotalTicks; -static int32_t _MIDI_TotalBeats; -static int32_t _MIDI_TotalMeasures; - -uint32_t _MIDI_PositionInTicks; -uint32_t _MIDI_GlobalPositionInTicks; - -static int32_t _MIDI_Context; - -static int32_t _MIDI_ActiveTracks; -static int32_t _MIDI_TotalVolume = MIDI_MaxVolume; - -static int32_t _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ]; - -static midifuncs *_MIDI_Funcs = NULL; - -static int32_t Reset = FALSE; - -int32_t MIDI_Tempo = 120; - -static int32_t _MIDI_ReadNumber(void *from, size_t size) -{ - if (size > 4) - size = 4; - - char *FromPtr = (char *)from; - int32_t value = 0; - - while (size--) - { - value <<= 8; - value += *FromPtr++; - } - - return value; -} - -static int32_t _MIDI_ReadDelta(track *ptr) -{ - int32_t value; - - GET_NEXT_EVENT(ptr, value); - - if (value & 0x80) - { - value &= 0x7f; - char c; - - do - { - GET_NEXT_EVENT(ptr, c); - value = (value << 7) + (c & 0x7f); - } - while (c & 0x80); - } - - return value; -} - -static void _MIDI_ResetTracks(void) -{ - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = 0; - - track *ptr = _MIDI_TrackPtr; - for (bssize_t i = 0; i < _MIDI_NumTracks; ++i) - { - ptr->pos = ptr->start; - ptr->delay = _MIDI_ReadDelta(ptr); - ptr->active = ptr->EMIDI_IncludeTrack; - ptr->RunningStatus = 0; - ptr->currentcontext = 0; - ptr->context[ 0 ].loopstart = ptr->start; - ptr->context[ 0 ].loopcount = 0; - - if (ptr->active) - _MIDI_ActiveTracks++; - - ptr++; - } -} - -static void _MIDI_AdvanceTick(void) -{ - _MIDI_PositionInTicks++; - _MIDI_Time += _MIDI_FPSecondsPerTick; - - _MIDI_Tick++; - while (_MIDI_Tick > _MIDI_TicksPerBeat) - { - _MIDI_Tick -= _MIDI_TicksPerBeat; - _MIDI_Beat++; - } - while (_MIDI_Beat > _MIDI_BeatsPerMeasure) - { - _MIDI_Beat -= _MIDI_BeatsPerMeasure; - _MIDI_Measure++; - } -} - -static void _MIDI_SysEx(track *Track) -{ - int32_t length = _MIDI_ReadDelta(Track); - Track->pos += length; -} - - -static void _MIDI_MetaEvent(track *Track) -{ - int32_t command; - int32_t length; - - GET_NEXT_EVENT(Track, command); - GET_NEXT_EVENT(Track, length); - - switch (command) - { - case MIDI_END_OF_TRACK: - Track->active = FALSE; - - _MIDI_ActiveTracks--; - break; - - case MIDI_TEMPO_CHANGE: - { - int32_t tempo = tabledivide32_noinline(60000000L, _MIDI_ReadNumber(Track->pos, 3)); - MIDI_SetTempo(tempo); - break; - } - - case MIDI_TIME_SIGNATURE: - { - 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); - - while (denominator > 0) - { - _MIDI_TimeBase += _MIDI_TimeBase; - denominator--; - } - - _MIDI_TicksPerBeat = tabledivide32_noinline(_MIDI_Division * 4, _MIDI_TimeBase); - break; - } - } - - Track->pos += length; -} - -static int32_t _MIDI_InterpretControllerInfo(track *Track, int32_t TimeSet, int32_t channel, int32_t c1, int32_t c2) -{ - track *trackptr; - int32_t tracknum; - int32_t loopcount; - - 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, 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)) - 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; - - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - loopcount = (c2 == 0) ? EMIDI_INFINITE : 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)) - break; - - if (c1 == EMIDI_SONG_LOOP_END) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - _MIDI_ActiveTracks = 0; - } - else - { - trackptr = Track; - tracknum = 1; - _MIDI_ActiveTracks--; - } - - while (tracknum > 0) - { - if (trackptr->context[ 0 ].loopcount != EMIDI_INFINITE) - { - trackptr->context[ 0 ].loopcount--; - } - - 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; -} - -static void _MIDI_ServiceRoutine(void) -{ - if (!_MIDI_SongActive) - return; - - track *Track = _MIDI_TrackPtr; - int32_t tracknum = 0; - int32_t TimeSet = FALSE; - int32_t c1 = 0; - int32_t c2 = 0; - - while (tracknum < _MIDI_NumTracks) - { - 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; - } - - if (Track->active) - Track->delay = _MIDI_ReadDelta(Track); - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - - int const channel = GET_MIDI_CHANNEL(event); - int const command = GET_MIDI_COMMAND(event); - - if (_MIDI_CommandLengths[ command ] > 0) - { - GET_NEXT_EVENT(Track, c1); - if (_MIDI_CommandLengths[ command ] > 1) - GET_NEXT_EVENT(Track, c2); - } - - switch (command) - { - case MIDI_NOTE_OFF: - if (_MIDI_Funcs->NoteOff) - _MIDI_Funcs->NoteOff(channel, c1, c2); - break; - - case MIDI_NOTE_ON: - if (_MIDI_Funcs->NoteOn) - _MIDI_Funcs->NoteOn(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_PROGRAM_CHANGE: - if ((_MIDI_Funcs->ProgramChange) && (!Track->EMIDI_ProgramChange)) - _MIDI_Funcs->ProgramChange(channel, c1 & 0x7f); - 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; - - default: break; - } - - Track->delay = _MIDI_ReadDelta(Track); - } - - Track->delay--; - Track++; - tracknum++; - - if (_MIDI_ActiveTracks == 0) - { - _MIDI_ResetTracks(); - if (_MIDI_Loop) - { - tracknum = 0; - Track = _MIDI_TrackPtr; - } - else - { - _MIDI_SongActive = FALSE; - break; - } - } - } - - _MIDI_AdvanceTick(); - _MIDI_GlobalPositionInTicks++; -} - -static int32_t _MIDI_SendControlChange(int32_t channel, int32_t c1, int32_t c2) -{ - if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) - return MIDI_Error; - - _MIDI_Funcs->ControlChange(channel, c1, c2); - - return MIDI_Ok; -} - -int32_t MIDI_AllNotesOff(void) -{ - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, 0x40, 0); - _MIDI_SendControlChange(channel, MIDI_ALL_NOTES_OFF, 0); - _MIDI_SendControlChange(channel, 0x78, 0); - } - - return MIDI_Ok; -} - -static void _MIDI_SetChannelVolume(int32_t channel, int32_t volume) -{ - _MIDI_ChannelVolume[ channel ] = volume; - - if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) - return; - - volume *= _MIDI_TotalVolume; - volume = tabledivide32_noinline(volume, MIDI_MaxVolume); - - _MIDI_Funcs->ControlChange(channel, MIDI_VOLUME, volume); -} - -static void _MIDI_SendChannelVolumes(void) -{ - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[channel]); -} - -int32_t MIDI_Reset(void) -{ - MIDI_AllNotesOff(); - - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, MIDI_RESET_ALL_CONTROLLERS, 0); - _MIDI_SendControlChange(channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB); - _MIDI_SendControlChange(channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB); - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_MSB, 2); /* Pitch Bend Sensitivity MSB */ - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_LSB, 0); /* Pitch Bend Sensitivity LSB */ - _MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume; - } - - _MIDI_SendChannelVolumes(); - - Reset = TRUE; - - return MIDI_Ok; -} - -int32_t MIDI_SetVolume(int32_t volume) -{ - if (_MIDI_Funcs == NULL) - return MIDI_NullMidiModule; - - _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; } - -void MIDI_SetLoopFlag(int32_t loopflag) { _MIDI_Loop = loopflag; } - -void MIDI_ContinueSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = TRUE; - MPU_Unpause(); -} - -void MIDI_PauseSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = FALSE; - MIDI_AllNotesOff(); - MPU_Pause(); -} - -void MIDI_SetMidiFuncs(midifuncs *funcs) { _MIDI_Funcs = funcs; } - -void MIDI_StopSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = FALSE; - _MIDI_SongLoaded = FALSE; - - MPU_Reset(); - MPU_Init(MUSIC_SoundDevice); - - 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; - -} - -int32_t MIDI_PlaySong(char *song, int32_t loopflag) -{ - int32_t numtracks; - int32_t format; - int32_t headersize; - int32_t tracklength; - track *CurrentTrack; - char *ptr; - - 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); - int32_t My_MIDI_NumTracks = _MIDI_ReadNumber(song + 2, 2); - int32_t My_MIDI_Division = _MIDI_ReadNumber(song + 4, 2); - if (My_MIDI_Division < 0) - { - // If a SMPTE time division is given, just set to 96 so no errors occur - My_MIDI_Division = 96; - } - - if (format > MAX_FORMAT) - return MIDI_UnknownMidiFormat; - - ptr = song + headersize; - - if (My_MIDI_NumTracks == 0) - return MIDI_NoTracks; - - int32_t My_MIDI_TrackMemSize = My_MIDI_NumTracks * sizeof(track); - track * My_MIDI_TrackPtr = (track *)Xmalloc(My_MIDI_TrackMemSize); - - CurrentTrack = My_MIDI_TrackPtr; - numtracks = My_MIDI_NumTracks; - - while (numtracks--) - { - if (B_UNBUF32(ptr) != MIDI_TRACK_SIGNATURE) - { - DO_FREE_AND_NULL(My_MIDI_TrackPtr); - - My_MIDI_TrackMemSize = 0; - - return MIDI_InvalidTrack; - } - - tracklength = _MIDI_ReadNumber(ptr + 4, 4); - ptr += 8; - CurrentTrack->start = ptr; - ptr += tracklength; - CurrentTrack++; - } - - // at this point we know song load is successful - - if (_MIDI_SongLoaded) - MIDI_StopSong(); - - MPU_Init(MUSIC_SoundDevice); - - _MIDI_Loop = loopflag; - _MIDI_NumTracks = My_MIDI_NumTracks; - _MIDI_Division = My_MIDI_Division; - _MIDI_TrackMemSize = My_MIDI_TrackMemSize; - _MIDI_TrackPtr = My_MIDI_TrackPtr; - - _MIDI_InitEMIDI(); - _MIDI_ResetTracks(); - - if (!Reset) - MIDI_Reset(); - - Reset = FALSE; - - MIDI_SetDivision(_MIDI_Division); - //MIDI_SetTempo( 120 ); - - _MIDI_SongLoaded = TRUE; - _MIDI_SongActive = TRUE; - - while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); - MPU_BeginPlayback(); - - return MIDI_Ok; -} - -void MIDI_SetTempo(int32_t tempo) -{ - int32_t tickspersecond; - - MIDI_Tempo = tempo; - tickspersecond = ((tempo) * _MIDI_Division)/60; - _MIDI_FPSecondsPerTick = tabledivide32_noinline(1 << TIME_PRECISION, tickspersecond); - MPU_SetTempo(tempo); -} - -void MIDI_SetDivision(int32_t division) -{ - MPU_SetDivision(division); -} - -int32_t MIDI_GetTempo(void) { return MIDI_Tempo; } - -static void _MIDI_InitEMIDI(void) -{ - int32_t type = EMIDI_GeneralMIDI; - - _MIDI_ResetTracks(); - - _MIDI_TotalTime = 0; - _MIDI_TotalTicks = 0; - _MIDI_TotalBeats = 0; - _MIDI_TotalMeasures = 0; - - track *Track = _MIDI_TrackPtr; - int32_t tracknum = 0; - - while ((tracknum < _MIDI_NumTracks) && (Track != NULL)) - { - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = -1; - - Track->RunningStatus = 0; - Track->active = TRUE; - - Track->EMIDI_ProgramChange = FALSE; - Track->EMIDI_VolumeChange = FALSE; - Track->EMIDI_IncludeTrack = TRUE; - - memset(Track->context, 0, sizeof(Track->context)); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - - 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; - } - - if (Track->active) - { - Track->delay = _MIDI_ReadDelta(Track); - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - -// channel = GET_MIDI_CHANNEL(event); - 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; - - switch (c1) - { - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - 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; - 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; - - 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; - - case EMIDI_INCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Include track %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = TRUE; - } - else if (!IncludeFound) - { - //printf( "Track excluded %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_EXCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Exclude track %d on card %d\n", tracknum, c2 ); - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_PROGRAM_CHANGE : - if (!Track->EMIDI_ProgramChange) - //printf( "Program change on track %d\n", tracknum ); - Track->EMIDI_ProgramChange = TRUE; - break; - - case EMIDI_VOLUME_CHANGE : - if (!Track->EMIDI_VolumeChange) - //printf( "Volume change on track %d\n", tracknum ); - Track->EMIDI_VolumeChange = TRUE; - break; - - case EMIDI_CONTEXT_START : - if ((c2 > 0) && (c2 < EMIDI_NUM_CONTEXTS)) - { - Track->context[ c2 ].pos = Track->pos; - Track->context[ c2 ].loopstart = Track->context[ 0 ].loopstart; - Track->context[ c2 ].loopcount = Track->context[ 0 ].loopcount; - Track->context[ c2 ].RunningStatus = Track->RunningStatus; - Track->context[ c2 ].time = _MIDI_Time; - Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - Track->context[ c2 ].tick = _MIDI_Tick; - Track->context[ c2 ].beat = _MIDI_Beat; - Track->context[ c2 ].measure = _MIDI_Measure; - Track->context[ c2 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - Track->context[ c2 ].TicksPerBeat = _MIDI_TicksPerBeat; - Track->context[ c2 ].TimeBase = _MIDI_TimeBase; - } - break; - - case EMIDI_CONTEXT_END : - break; - } - } - - Track->pos += length; - Track->delay = _MIDI_ReadDelta(Track); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - _MIDI_TotalTime = max(_MIDI_TotalTime, _MIDI_Time); - if (RELATIVE_BEAT(_MIDI_Measure, _MIDI_Beat, _MIDI_Tick) > - RELATIVE_BEAT(_MIDI_TotalMeasures, _MIDI_TotalBeats, _MIDI_TotalTicks)) - { - _MIDI_TotalTicks = _MIDI_Tick; - _MIDI_TotalBeats = _MIDI_Beat; - _MIDI_TotalMeasures = _MIDI_Measure; - } - - Track++; - tracknum++; - } - - _MIDI_ResetTracks(); -} - - -void MIDI_UpdateMusic(void) -{ - if (!_MIDI_SongLoaded || !_MIDI_SongActive) return; - while (_MPU_BuffersWaiting < 4) _MIDI_ServiceRoutine(); -} - diff --git a/source/rr/src/midi.h b/source/rr/src/midi.h deleted file mode 100644 index a38fd3503..000000000 --- a/source/rr/src/midi.h +++ /dev/null @@ -1,87 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef __MIDI_H -#define __MIDI_H - -enum MIDI_Errors - { - MIDI_Warning = -2, - MIDI_Error = -1, - MIDI_Ok = 0, - MIDI_NullMidiModule, - MIDI_InvalidMidiFile, - MIDI_UnknownMidiFormat, - MIDI_NoTracks, - MIDI_InvalidTrack, - MIDI_NoMemory, - MIDI_DPMI_Error - }; - - -#define MIDI_PASS_THROUGH 1 -#define MIDI_DONT_PLAY 0 - -#define MIDI_MaxVolume 255 - -extern char MIDI_PatchMap[ 128 ]; - -typedef struct -{ - void (*NoteOff)(int32_t channel, int32_t key, int32_t velocity); - void (*NoteOn)(int32_t channel, int32_t key, int32_t velocity); - void (*PolyAftertouch)(int32_t channel, int32_t key, int32_t pressure); - void (*ControlChange)(int32_t channel, int32_t number, int32_t value); - void (*ProgramChange)(int32_t channel, int32_t program); - void (*ChannelAftertouch)(int32_t channel, int32_t pressure); - void (*PitchBend)(int32_t channel, int32_t lsb, int32_t msb); - void (*FinishBuffer)(void); -} midifuncs; - -void MIDI_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) ); -int32_t MIDI_AllNotesOff( void ); -void MIDI_SetUserChannelVolume( int32_t channel, int32_t volume ); -void MIDI_ResetUserChannelVolume( void ); -int32_t MIDI_Reset( void ); -int32_t MIDI_SetVolume( int32_t volume ); -int32_t MIDI_GetVolume( void ); -void MIDI_SetMidiFuncs( midifuncs *funcs ); -void MIDI_SetContext( int32_t context ); -int32_t MIDI_GetContext( void ); -void MIDI_SetLoopFlag( int32_t loopflag ); -void MIDI_ContinueSong( void ); -void MIDI_PauseSong( void ); -int32_t MIDI_SongPlaying( void ); -void MIDI_StopSong( void ); -int32_t MIDI_PlaySong( char *song, int32_t loopflag ); -void MIDI_SetTempo( int32_t tempo ); -int32_t MIDI_GetTempo( void ); -void MIDI_SetSongTick( uint32_t PositionInTicks ); -void MIDI_SetSongTime( uint32_t milliseconds ); -void MIDI_SetSongPosition( int32_t measure, int32_t beat, int32_t tick ); -void MIDI_GetSongPosition( songposition *pos ); -void MIDI_GetSongLength( songposition *pos ); -void MIDI_LoadTimbres( void ); -void MIDI_UpdateMusic(void); -void MIDI_SetDivision( int32_t division ); - -#endif diff --git a/source/rr/src/mpu401.cpp b/source/rr/src/mpu401.cpp deleted file mode 100644 index 0c7b9b9f2..000000000 --- a/source/rr/src/mpu401.cpp +++ /dev/null @@ -1,496 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/********************************************************************** - module: MPU401.C - - author: James R. Dose - date: January 1, 1994 - - Low level routines to support sending of MIDI data to MPU401 - compatible MIDI interfaces. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -// This object is shared by all Build games with MIDI playback! - -#include "mpu401.h" -#include "compat.h" -#include "pragmas.h" - -#define NEED_MMSYSTEM_H -#include "windows_inc.h" - -static HMIDISTRM hmido = (HMIDISTRM)-1; -static MIDIOUTCAPS midicaps; -static DWORD mididevice = -1; - -#define PAD(x) ((((x)+3)&(~3))) - -#define BUFFERLEN (32*4*4) -#define NUMBUFFERS 6 -static char eventbuf[NUMBUFFERS][BUFFERLEN]; -static int32_t eventcnt[NUMBUFFERS]; -static MIDIHDR bufferheaders[NUMBUFFERS]; -int32_t _MPU_CurrentBuffer = 0; -int32_t _MPU_BuffersWaiting = 0; - -extern uint32_t _MIDI_GlobalPositionInTicks; -uint32_t _MPU_LastEvent=0; - -#define MIDI_NOTE_OFF 0x80 -#define MIDI_NOTE_ON 0x90 -#define MIDI_POLY_AFTER_TCH 0xA0 -#define MIDI_CONTROL_CHANGE 0xB0 -#define MIDI_PROGRAM_CHANGE 0xC0 -#define MIDI_AFTER_TOUCH 0xD0 -#define MIDI_PITCH_BEND 0xE0 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_ALL_NOTES_OFF 0x7B - - -/********************************************************************** - - Memory locked functions: - -**********************************************************************/ - - -void MPU_FinishBuffer(int32_t buffer) -{ - if (!eventcnt[buffer]) return; - ZeroMemory(&bufferheaders[buffer], sizeof(MIDIHDR)); - bufferheaders[buffer].lpData = eventbuf[buffer]; - bufferheaders[buffer].dwBufferLength = - bufferheaders[buffer].dwBytesRecorded = eventcnt[buffer]; - midiOutPrepareHeader((HMIDIOUT)hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); - midiStreamOut(hmido, &bufferheaders[buffer], sizeof(MIDIHDR)); -// printf("Sending %d bytes (buffer %d)\n",eventcnt[buffer],buffer); - _MPU_BuffersWaiting++; -} - -void MPU_BeginPlayback(void) -{ - _MPU_LastEvent = _MIDI_GlobalPositionInTicks; - if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); -} - -void MPU_Pause(void) -{ - if (hmido != (HMIDISTRM)-1) midiStreamPause(hmido); -} - -void MPU_Unpause(void) -{ - if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido); -} - - -void CALLBACK MPU_MIDICallback(HMIDIOUT handle, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) -{ - int32_t i; - - UNREFERENCED_PARAMETER(dwInstance); - UNREFERENCED_PARAMETER(dwParam2); - - switch (uMsg) - { - case MOM_DONE: - midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR *)dwParam1, sizeof(MIDIHDR)); - for (i=0; i BUFFERLEN) - { - // buffer over-full - nextbuffer = MPU_GetNextBuffer(); - if (nextbuffer < 0) - { -// printf("All buffers full!\n"); - return; - } - MPU_FinishBuffer(_MPU_CurrentBuffer); - _MPU_CurrentBuffer = nextbuffer; - } - - p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; - ((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; - ((int32_t *)p)[1] = 0; - ((int32_t *)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t *)data)) & masks[count-1]); - eventcnt[_MPU_CurrentBuffer] += 12; - } - else - { - padded = PAD(count); - if (eventcnt[_MPU_CurrentBuffer] + 12 + padded > BUFFERLEN) - { - // buffer over-full - nextbuffer = MPU_GetNextBuffer(); - if (nextbuffer < 0) - { -// printf("All buffers full!\n"); - return; - } - MPU_FinishBuffer(_MPU_CurrentBuffer); - _MPU_CurrentBuffer = nextbuffer; - } - - p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer]; - ((int32_t *)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent; - ((int32_t *)p)[1] = 0; - ((int32_t *)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl); - p+=12; eventcnt[_MPU_CurrentBuffer] += 12; - for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++) - *(p++) = *(data++); - for (; padded>0; padded--, eventcnt[_MPU_CurrentBuffer]++) - *(p++) = 0; - } - _MPU_LastEvent = _MIDI_GlobalPositionInTicks; -} - - -/*--------------------------------------------------------------------- - Function: MPU_SendMidiImmediate - - Sends a MIDI message immediately to the the music device. ----------------------------------------------------------------------*/ -void MPU_SendMidiImmediate(char *data, int32_t count) -{ - MIDIHDR mhdr; - static int32_t masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl }; - - if (!count) return; - if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t *)data)) & masks[count-1]); - else - { - ZeroMemory(&mhdr, sizeof(mhdr)); - mhdr.lpData = data; - mhdr.dwBufferLength = count; - midiOutPrepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - midiOutLongMsg((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - while (!(mhdr.dwFlags & MHDR_DONE)) ; - midiOutUnprepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR)); - } -} - - -/*--------------------------------------------------------------------- - Function: MPU_Reset - - Resets the MPU401 card. ----------------------------------------------------------------------*/ - -int32_t MPU_Reset -( - void -) - -{ - midiStreamStop(hmido); - midiStreamClose(hmido); - hmido = (HMIDISTRM)-1; - - return MPU_Ok; -} - - -/*--------------------------------------------------------------------- - Function: MPU_Init - - Detects and initializes the MPU401 card. ----------------------------------------------------------------------*/ - -int32_t MPU_Init -( - int32_t addr -) - -{ - if (hmido != (HMIDISTRM)-1) - return MPU_Ok; - - int32_t i; - - for (i=0; iNoteOff = MPU_NoteOff; - Funcs->NoteOn = MPU_NoteOn; - Funcs->PolyAftertouch = MPU_PolyAftertouch; - Funcs->ControlChange = MPU_ControlChange; - Funcs->ProgramChange = MPU_ProgramChange; - Funcs->ChannelAftertouch = MPU_ChannelAftertouch; - Funcs->PitchBend = MPU_PitchBend; - - MIDI_SetMidiFuncs(Funcs); - - return MIDI_Ok; -} - -void MUSIC_Update(void) { MIDI_UpdateMusic(); } diff --git a/source/rr/src/sdlmusic.cpp b/source/rr/src/sdlmusic.cpp deleted file mode 100644 index 378367b78..000000000 --- a/source/rr/src/sdlmusic.cpp +++ /dev/null @@ -1,481 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010 EDuke32 developers and contributors - -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 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/* - * A reimplementation of Jim Dose's FX_MAN routines, using SDL_mixer 1.2. - * Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for - * short. How strangely appropriate that seems. - */ - -// This object is shared by all Build games with MIDI playback! - -#define NEED_SDL_MIXER - -#include "compat.h" - -#include "duke3d.h" -#include "cache1d.h" - -#include "sdlayer.h" -#include "music.h" - -#if !defined _WIN32 && !defined(GEKKO) -//# define FORK_EXEC_MIDI 1 -#endif - -#if defined FORK_EXEC_MIDI // fork/exec based external midi player -#include -#include -#include -static char **external_midi_argv; -static pid_t external_midi_pid=-1; -static int8_t external_midi_restart=0; -#endif - -#ifdef __ANDROID__ //TODO fix -static char const *external_midi_tempfn = APPBASENAME "-music.mid"; -#else -static char const *external_midi_tempfn = "/tmp/" APPBASENAME "-music.mid"; -#endif - -static int32_t external_midi = 0; - -int32_t MUSIC_ErrorCode = MUSIC_Ok; - -static char warningMessage[80]; -static char errorMessage[80]; - -static int32_t music_initialized = 0; -static int32_t music_context = 0; -static int32_t music_loopflag = MUSIC_PlayOnce; -static Mix_Music *music_musicchunk = NULL; - -static void setErrorMessage(const char *msg) -{ - Bstrncpyz(errorMessage, msg, sizeof(errorMessage)); -} - -// The music functions... - -const char *MUSIC_ErrorString(int32_t ErrorNumber) -{ - switch (ErrorNumber) - { - case MUSIC_Warning: - return warningMessage; - - case MUSIC_Error: - return errorMessage; - - case MUSIC_Ok: - return "OK; no error."; - - case MUSIC_MidiError: - return "MIDI error."; - - default: - return "Unknown error."; - } // switch - - return NULL; -} // MUSIC_ErrorString - -int32_t MUSIC_Init(int32_t SoundCard, int32_t Address) -{ -#ifdef __ANDROID__ - music_initialized = 1; - return MUSIC_Ok; -#endif - // Use an external MIDI player if the user has specified to do so - char *command = getenv("EDUKE32_MUSIC_CMD"); - const SDL_version *linked = Mix_Linked_Version(); - - UNREFERENCED_PARAMETER(SoundCard); - UNREFERENCED_PARAMETER(Address); - - if (music_initialized) - { - setErrorMessage("Music system is already initialized."); - return MUSIC_Error; - } // if - - if (SDL_VERSIONNUM(linked->major,linked->minor,linked->patch) < MIX_REQUIREDVERSION) - { - // reject running with SDL_Mixer versions older than what is stated in sdl_inc.h - initprintf("You need at least v%d.%d.%d of SDL_mixer for music\n",SDL_MIXER_MIN_X,SDL_MIXER_MIN_Y,SDL_MIXER_MIN_Z); - return MUSIC_Error; - } - - external_midi = (command != NULL && command[0] != 0); - - if (external_midi) - { -#if defined FORK_EXEC_MIDI - int32_t ws=1, numargs=0, pagesize=sysconf(_SC_PAGE_SIZE); - char *c, *cmd; - size_t sz; -#endif - - initprintf("Setting music command to \"%s\".\n", command); - -#if !defined FORK_EXEC_MIDI - if (Mix_SetMusicCMD(command)==-1) - { - perror("Mix_SetMusicCMD"); - goto fallback; - } -#else - - if (pagesize==-1) - goto fallback; - - for (c=command; *c; c++) - { - if (isspace(*c)) - ws = 1; - else if (ws) - { - ws = 0; - numargs++; - } - } - - if (numargs==0) - goto fallback; - - sz = (numargs+2)*sizeof(char *) + (c-command+1); - sz = ((sz+pagesize-1)/pagesize)*pagesize; -#if defined(__APPLE__) || defined(__ANDROID__) - external_midi_argv = Xcalloc(1,sz+pagesize); - external_midi_argv = (char **)((intptr_t)external_midi_argv + (pagesize-(((intptr_t)external_midi_argv)&(pagesize-1)))); -#else - if (posix_memalign((void **)&external_midi_argv, pagesize, sz)) - goto fallback; -#endif - cmd = (char *)external_midi_argv + (numargs+2)*sizeof(char *); - Bmemcpy(cmd, command, c-command+1); - - ws = 1; - numargs = 0; - for (c=cmd; *c; c++) - { - if (isspace(*c)) - { - ws = 1; - *c = 0; - } - else if (ws) - { - ws = 0; - external_midi_argv[numargs++] = c; - } - } - external_midi_argv[numargs] = external_midi_tempfn; - external_midi_argv[numargs+1] = NULL; - - if (mprotect(external_midi_argv, sz, PROT_READ)==-1) // make argv and command string read-only - { - perror("MUSIC_Init: mprotect"); - goto fallback; - } -# if 0 - { - int i; - initprintf("----Music argv:\n"); - for (i=0; i=0; i--) - { - fp = Bfopen(s[i], "r"); - if (fp == NULL) - { - if (i == 0) - { - initprintf("Error: couldn't open any of the following files:\n"); - for (i = ARRAY_SIZE(s)-1; i>=0; i--) - initprintf("%s\n",s[i]); - return MUSIC_Error; - } - continue; - } - else break; - } - Bfclose(fp); - } - - music_initialized = 1; - return MUSIC_Ok; -} // MUSIC_Init - - -int32_t MUSIC_Shutdown(void) -{ - // TODO - make sure this is being called from the menu -- SA -#if !defined FORK_EXEC_MIDI - if (external_midi) - Mix_SetMusicCMD(NULL); -#endif - - MUSIC_StopSong(); - music_context = 0; - music_initialized = 0; - music_loopflag = MUSIC_PlayOnce; - - return MUSIC_Ok; -} // MUSIC_Shutdown - - -void MUSIC_SetMaxFMMidiChannel(int32_t channel) -{ - UNREFERENCED_PARAMETER(channel); -} // MUSIC_SetMaxFMMidiChannel - - -void MUSIC_SetVolume(int32_t volume) -{ - volume = max(0, volume); - volume = min(volume, 255); - - Mix_VolumeMusic(volume >> 1); // convert 0-255 to 0-128. -} // MUSIC_SetVolume - - -int32_t MUSIC_GetVolume(void) -{ - return (Mix_VolumeMusic(-1) << 1); // convert 0-128 to 0-255. -} // MUSIC_GetVolume - - -void MUSIC_SetLoopFlag(int32_t loopflag) -{ - music_loopflag = loopflag; -} // MUSIC_SetLoopFlag - - -void MUSIC_Continue(void) -{ - if (Mix_PausedMusic()) - Mix_ResumeMusic(); -} // MUSIC_Continue - - -void MUSIC_Pause(void) -{ - Mix_PauseMusic(); -} // MUSIC_Pause - -int32_t MUSIC_StopSong(void) -{ -#if defined FORK_EXEC_MIDI - if (external_midi) - { - if (external_midi_pid > 0) - { - int32_t ret; - struct timespec ts; - - external_midi_restart = 0; // make SIGCHLD handler a no-op - - ts.tv_sec = 0; - ts.tv_nsec = 5000000; // sleep 5ms at most - - kill(external_midi_pid, SIGTERM); - nanosleep(&ts, NULL); - ret = waitpid(external_midi_pid, NULL, WNOHANG|WUNTRACED); -// printf("(%d)", ret); - - if (ret != external_midi_pid) - { - if (ret==-1) - perror("waitpid"); - else - { - // we tried to be nice, but no... - kill(external_midi_pid, SIGKILL); - initprintf("%s: wait for SIGTERM timed out.\n", __func__); - if (waitpid(external_midi_pid, NULL, WUNTRACED)==-1) - perror("waitpid (2)"); - } - } - - external_midi_pid = -1; - } - - return MUSIC_Ok; - } -#endif - - //if (!fx_initialized) - if (!Mix_QuerySpec(NULL, NULL, NULL)) - { - setErrorMessage("Need FX system initialized, too. Sorry."); - return MUSIC_Error; - } // if - - if ((Mix_PlayingMusic()) || (Mix_PausedMusic())) - Mix_HaltMusic(); - - if (music_musicchunk) - Mix_FreeMusic(music_musicchunk); - - music_musicchunk = NULL; - - return MUSIC_Ok; -} // MUSIC_StopSong - -#if defined FORK_EXEC_MIDI -static int32_t playmusic() -{ - pid_t pid = vfork(); - - if (pid==-1) // error - { - initprintf("%s: vfork: %s\n", __func__, strerror(errno)); - return MUSIC_Error; - } - else if (pid==0) // child - { - // exec without PATH lookup - if (execv(external_midi_argv[0], external_midi_argv) < 0) - { - perror("execv"); - _exit(1); - } - } - else // parent - { - external_midi_pid = pid; - } - - return MUSIC_Ok; -} - -static void sigchld_handler(int signo) -{ - if (signo==SIGCHLD && external_midi_restart) - { - int status; - - if (external_midi_pid > 0) - { - if (waitpid(external_midi_pid, &status, WUNTRACED)==-1) - perror("waitpid (3)"); - - if (WIFEXITED(status) && WEXITSTATUS(status)==0) - { - // loop ... - playmusic(); - } - } - } -} -#endif - -// Duke3D-specific. --ryan. -// void MUSIC_PlayMusic(char *_filename) -int32_t MUSIC_PlaySong(char *song, int32_t songsize, int32_t loopflag) -{ - if (external_midi) - { - FILE *fp; - -#if defined FORK_EXEC_MIDI - static int32_t sigchld_handler_set = 0; - - if (!sigchld_handler_set) - { - struct sigaction sa; - sa.sa_handler=sigchld_handler; - sa.sa_flags=0; - sigemptyset(&sa.sa_mask); - - if (sigaction(SIGCHLD, &sa, NULL)==-1) - initprintf("%s: sigaction: %s\n", __func__, strerror(errno)); - - sigchld_handler_set = 1; - } -#endif - - fp = Bfopen(external_midi_tempfn, "wb"); - if (fp) - { - fwrite(song, 1, songsize, fp); - Bfclose(fp); - -#if defined FORK_EXEC_MIDI - external_midi_restart = loopflag; - int32_t retval = playmusic(); - if (retval != MUSIC_Ok) - return retval; -#else - music_musicchunk = Mix_LoadMUS(external_midi_tempfn); - if (!music_musicchunk) - { - initprintf("Mix_LoadMUS: %s\n", Mix_GetError()); - return MUSIC_Error; - } -#endif - } - else - { - initprintf("%s: fopen: %s\n", __func__, strerror(errno)); - return MUSIC_Error; - } - } - else - music_musicchunk = Mix_LoadMUS_RW(SDL_RWFromMem(song, songsize) -#if (SDL_MAJOR_VERSION > 1) - , SDL_FALSE -#endif - ); - - if (music_musicchunk == NULL) - return MUSIC_Error; - - if (Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_LoopSong)?-1:0) == -1) - { - initprintf("Mix_PlayMusic: %s\n", Mix_GetError()); - return MUSIC_Error; - } - - return MUSIC_Ok; -} - - -void MUSIC_Update(void) -{}