From 0634205d7f4bd0e9cc507a3e0ff13670d1ac80b6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Dec 2015 18:01:15 +0100 Subject: [PATCH 01/15] - let WildMidi tokenizer handle quoted strings. --- src/wildmidi/wildmidi_lib.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index 26e4965ba..19e290f6b 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -573,13 +573,15 @@ static inline int wm_isdigit(int c) { } #define TOKEN_CNT_INC 8 -static char** WM_LC_Tokenize_Line(char *line_data) { +static char** WM_LC_Tokenize_Line(char *line_data) +{ int line_length = strlen(line_data); int token_data_length = 0; int line_ofs = 0; int token_start = 0; char **token_data = NULL; int token_count = 0; + bool in_quotes = false; if (line_length == 0) return NULL; @@ -589,8 +591,11 @@ static char** WM_LC_Tokenize_Line(char *line_data) { if (line_data[line_ofs] == '#') { break; } - - if ((line_data[line_ofs] == ' ') || (line_data[line_ofs] == '\t')) { + if (line_data[line_ofs] == '"') + { + in_quotes = !in_quotes; + } + else if (!in_quotes && ((line_data[line_ofs] == ' ') || (line_data[line_ofs] == '\t'))) { /* whitespace means we aren't in a token */ if (token_start) { token_start = 0; From fe2dcfd588596d5311b31193f0e70630815a9932 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Dec 2015 20:38:08 +0100 Subject: [PATCH 02/15] - refactored the GUS/Timidity player's path building code so that it can also be used by WildMidi. - fixed crash during sound reset - in this case I_ShutdownMusic should not close the WildMidi player. --- src/CMakeLists.txt | 1 + src/pathexpander.cpp | 134 ++++++++++++++++++++++++++++++++++ src/pathexpander.h | 31 ++++++++ src/sound/i_music.cpp | 11 ++- src/sound/i_music.h | 3 +- src/timidity/common.cpp | 88 ---------------------- src/timidity/instrum.cpp | 4 +- src/timidity/instrum_font.cpp | 2 +- src/timidity/instrum_sf2.cpp | 2 +- src/timidity/timidity.cpp | 32 ++++---- src/timidity/timidity.h | 11 +-- 11 files changed, 198 insertions(+), 121 deletions(-) create mode 100644 src/pathexpander.cpp create mode 100644 src/pathexpander.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 18fdb992c..f1975a8d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -915,6 +915,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE nodebuild_extract.cpp nodebuild_gl.cpp nodebuild_utility.cpp + pathexpander.cpp p_3dfloors.cpp p_3dmidtex.cpp p_acs.cpp diff --git a/src/pathexpander.cpp b/src/pathexpander.cpp new file mode 100644 index 000000000..d8b912b65 --- /dev/null +++ b/src/pathexpander.cpp @@ -0,0 +1,134 @@ +/* +** pathexpander.cpp +** Utility class for expanding a given path with a range of directories +** +**--------------------------------------------------------------------------- +** Copyright 2015 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "pathexpander.h" +#include "cmdlib.h" +#include "w_wad.h" + +//============================================================================ +// +// +// +//============================================================================ + +static FString BuildPath(const FString &base, const char *name) +{ + FString current; + if (base.IsNotEmpty()) + { + current = base; + if (current[current.Len() - 1] != '/') current += '/'; + } + current += name; + return current; +} + +//============================================================================ +// +// This is meant to find and open files for reading. +// +//============================================================================ + +FileReader *PathExpander::openFileReader(const char *name, int *plumpnum) +{ + FileReader *fp; + FString current_filename; + + if (!name || !(*name)) + { + return 0; + } + + /* First try the given name */ + current_filename = name; + FixPathSeperator(current_filename); + + int lumpnum = Wads.CheckNumForFullName(current_filename); + + if (openmode != OM_FILE) + { + if (lumpnum >= 0) + { + fp = Wads.ReopenLumpNum(lumpnum); + if (plumpnum) *plumpnum = lumpnum; + return fp; + } + if (openmode == OM_LUMP) // search the path list when not loading the main config + { + for (unsigned int plp = PathList.Size(); plp-- != 0; ) + { /* Try along the path then */ + current_filename = BuildPath(PathList[plp], name); + lumpnum = Wads.CheckNumForFullName(current_filename); + if (lumpnum >= 0) + { + fp = Wads.ReopenLumpNum(lumpnum); + if (plumpnum) *plumpnum = lumpnum; + return fp; + } + } + return NULL; + } + } + if (plumpnum) *plumpnum = -1; + + + fp = new FileReader; + if (fp->Open(current_filename)) return fp; + + if (name[0] != '/') + { + for (unsigned int plp = PathList.Size(); plp-- != 0; ) + { /* Try along the path then */ + current_filename = BuildPath(PathList[plp], name); + if (fp->Open(current_filename)) return fp; + } + } + delete fp; + + /* Nothing could be opened. */ + return NULL; +} + +/* This adds a directory to the path list */ +void PathExpander::addToPathlist(const char *s) +{ + FString copy = s; + FixPathSeperator(copy); + PathList.Push(copy); +} + +void PathExpander::clearPathlist() +{ + PathList.Clear(); +} diff --git a/src/pathexpander.h b/src/pathexpander.h new file mode 100644 index 000000000..556598071 --- /dev/null +++ b/src/pathexpander.h @@ -0,0 +1,31 @@ +#ifndef __PATHEXPANDER_H +#define __PATHEXPANDER_H + +#include "tarray.h" +#include "zstring.h" +#include "files.h" + +class PathExpander +{ + TArray PathList; + +public: + int openmode; + + enum + { + OM_FILEORLUMP = 0, + OM_LUMP, + OM_FILE + }; + + PathExpander(int om = OM_FILEORLUMP) + { + openmode = om; + } + void addToPathlist(const char *s); + void clearPathlist(); + FileReader *openFileReader(const char *name, int *plumpnum); +}; + +#endif diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 721be5192..121c0b9fb 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -162,7 +162,7 @@ void I_InitMusic (void) if (!setatterm) { setatterm = true; - atterm (I_ShutdownMusic); + atterm (I_ShutdownMusicExit); #ifndef _WIN32 signal (SIGCHLD, ChildSigHandler); @@ -178,7 +178,7 @@ void I_InitMusic (void) // //========================================================================== -void I_ShutdownMusic(void) +void I_ShutdownMusic(bool onexit) { if (MusicDown) return; @@ -189,12 +189,17 @@ void I_ShutdownMusic(void) assert (currSong == NULL); } Timidity::FreeAll(); - WildMidi_Shutdown(); + if (onexit) WildMidi_Shutdown(); #ifdef _WIN32 I_ShutdownMusicWin32(); #endif // _WIN32 } +void I_ShutdownMusicExit() +{ + I_ShutdownMusic(true); +} + //========================================================================== // diff --git a/src/sound/i_music.h b/src/sound/i_music.h index f6a6dbadd..ee05d8caf 100644 --- a/src/sound/i_music.h +++ b/src/sound/i_music.h @@ -43,7 +43,8 @@ struct FOptionValues; // MUSIC I/O // void I_InitMusic (); -void I_ShutdownMusic (); +void I_ShutdownMusic (bool onexit = false); +void I_ShutdownMusicExit (); void I_BuildMIDIMenuList (FOptionValues *); void I_UpdateMusic (); diff --git a/src/timidity/common.cpp b/src/timidity/common.cpp index 92d9b009a..57fd26e0c 100644 --- a/src/timidity/common.cpp +++ b/src/timidity/common.cpp @@ -35,82 +35,6 @@ namespace Timidity { -static TArray PathList; - -FString BuildPath(FString base, const char *name) -{ - FString current; - if (base.IsNotEmpty()) - { - current = base; - if (current[current.Len() - 1] != '/') current += '/'; - } - current += name; - return current; -} - -/* This is meant to find and open files for reading. */ -FileReader *open_filereader(const char *name, int open, int *plumpnum) -{ - FileReader *fp; - FString current_filename; - - if (!name || !(*name)) - { - return 0; - } - - /* First try the given name */ - current_filename = name; - FixPathSeperator(current_filename); - - int lumpnum = Wads.CheckNumForFullName(current_filename); - - if (open != OM_FILE) - { - if (lumpnum >= 0) - { - fp = Wads.ReopenLumpNum(lumpnum); - if (plumpnum) *plumpnum = lumpnum; - return fp; - } - if (open == OM_LUMP) // search the path list when not loading the main config - { - for (unsigned int plp = PathList.Size(); plp-- != 0; ) - { /* Try along the path then */ - current_filename = BuildPath(PathList[plp], name); - lumpnum = Wads.CheckNumForFullName(current_filename); - if (lumpnum >= 0) - { - fp = Wads.ReopenLumpNum(lumpnum); - if (plumpnum) *plumpnum = lumpnum; - return fp; - } - } - return NULL; - } - } - if (plumpnum) *plumpnum = -1; - - - fp = new FileReader; - if (fp->Open(current_filename)) return fp; - - if (name[0] != '/') - { - for (unsigned int plp = PathList.Size(); plp-- != 0; ) - { /* Try along the path then */ - current_filename = BuildPath(PathList[plp], name); - if (fp->Open(current_filename)) return fp; - } - } - delete fp; - - /* Nothing could be opened. */ - current_filename = ""; - return NULL; -} - /* This'll allocate memory or die. */ @@ -132,17 +56,5 @@ void *safe_malloc(size_t count) return 0; // Unreachable. } -/* This adds a directory to the path list */ -void add_to_pathlist(const char *s) -{ - FString copy = s; - FixPathSeperator(copy); - PathList.Push(copy); -} - -void clear_pathlist() -{ - PathList.Clear(); -} } diff --git a/src/timidity/instrum.cpp b/src/timidity/instrum.cpp index 7454ca7a4..a8c7b5f7c 100644 --- a/src/timidity/instrum.cpp +++ b/src/timidity/instrum.cpp @@ -159,12 +159,12 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss if (!name) return 0; /* Open patch file */ - if ((fp = open_filereader(name, openmode, NULL)) == NULL) + if ((fp = pathExpander.openFileReader(name, NULL)) == NULL) { /* Try with various extensions */ FString tmp = name; tmp += ".pat"; - if ((fp = open_filereader(tmp, openmode, NULL)) == NULL) + if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL) { #ifdef __unix__ // Windows isn't case-sensitive. tmp.ToUpper(); diff --git a/src/timidity/instrum_font.cpp b/src/timidity/instrum_font.cpp index 995558bd4..069eb9c84 100644 --- a/src/timidity/instrum_font.cpp +++ b/src/timidity/instrum_font.cpp @@ -54,7 +54,7 @@ void font_add(const char *filename, int load_order) } else { - FileReader *fp = open_filereader(filename, openmode, NULL); + FileReader *fp = pathExpander.openFileReader(filename, NULL); if (fp != NULL) { diff --git a/src/timidity/instrum_sf2.cpp b/src/timidity/instrum_sf2.cpp index dae330644..c4cf0bc81 100644 --- a/src/timidity/instrum_sf2.cpp +++ b/src/timidity/instrum_sf2.cpp @@ -1502,7 +1502,7 @@ void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Rend void SFFile::LoadSample(SFSample *sample) { - FileReader *fp = open_filereader(Filename, openmode, NULL); + FileReader *fp = pathExpander.openFileReader(Filename, NULL); DWORD i; if (fp == NULL) diff --git a/src/timidity/timidity.cpp b/src/timidity/timidity.cpp index 0f0fcdeb5..1d74c5afc 100644 --- a/src/timidity/timidity.cpp +++ b/src/timidity/timidity.cpp @@ -42,10 +42,10 @@ CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) namespace Timidity { +PathExpander pathExpander; ToneBank *tonebank[MAXBANK], *drumset[MAXBANK]; static FString def_instr_name; -int openmode = OM_FILEORLUMP; static int read_config_file(const char *name, bool ismain) { @@ -62,21 +62,21 @@ static int read_config_file(const char *name, bool ismain) return (-1); } - if (ismain) openmode = OM_FILEORLUMP; + if (ismain) pathExpander.openmode = PathExpander::OM_FILEORLUMP; - if (!(fp = open_filereader(name, openmode, &lumpnum))) + if (!(fp = pathExpander.openFileReader(name, &lumpnum))) return -1; if (ismain) { if (lumpnum > 0) { - openmode = OM_LUMP; - clear_pathlist(); // when reading from a PK3 we won't want to use any external path + pathExpander.openmode = PathExpander::OM_LUMP; + pathExpander.clearPathlist(); // when reading from a PK3 we don't want to use any external path } else { - openmode = OM_FILE; + pathExpander.openmode = PathExpander::OM_FILE; } } @@ -288,7 +288,7 @@ static int read_config_file(const char *name, bool ismain) return -2; } for (i = 1; i < words; i++) - add_to_pathlist(w[i]); + pathExpander.addToPathlist(w[i]); } else if (!strcmp(w[0], "source")) { @@ -532,15 +532,15 @@ int LoadConfig(const char *filename) * file itself since that file should contain any other directory * that needs to be added to the search path. */ - clear_pathlist(); + pathExpander.clearPathlist(); #ifdef _WIN32 - add_to_pathlist("C:\\TIMIDITY"); - add_to_pathlist("\\TIMIDITY"); - add_to_pathlist(progdir); + pathExpander.addToPathlist("C:\\TIMIDITY"); + pathExpander.addToPathlist("\\TIMIDITY"); + pathExpander.addToPathlist(progdir); #else - add_to_pathlist("/usr/local/lib/timidity"); - add_to_pathlist("/etc/timidity"); - add_to_pathlist("/etc"); + pathExpander.addToPathlist("/usr/local/lib/timidity"); + pathExpander.addToPathlist("/etc/timidity"); + pathExpander.addToPathlist("/etc"); #endif /* Some functions get aggravated if not even the standard banks are available. */ @@ -579,10 +579,10 @@ int LoadDMXGUS() if (ultradir.IsNotEmpty()) { ultradir += "/midi"; - add_to_pathlist(ultradir.GetChars()); + pathExpander.addToPathlist(ultradir.GetChars()); } // Load DMXGUS lump and patches from gus_patchdir - add_to_pathlist(gus_patchdir); + pathExpander.addToPathlist(gus_patchdir); char readbuffer[1024]; long size = data.GetLength(); diff --git a/src/timidity/timidity.h b/src/timidity/timidity.h index 6c46317dd..0a21a41b9 100644 --- a/src/timidity/timidity.h +++ b/src/timidity/timidity.h @@ -21,6 +21,7 @@ #define TIMIDITY_H #include "doomtype.h" +#include "pathexpander.h" class FileReader; @@ -172,17 +173,8 @@ extern __inline__ double pow_x87_inline(double x,double y) common.h */ -#define OM_FILEORLUMP 0 -#define OM_LUMP 1 -#define OM_FILE 2 - -extern void add_to_pathlist(const char *s); -extern void clear_pathlist(); extern void *safe_malloc(size_t count); -FileReader *open_filereader(const char *name, int open, int *plumpnum); -extern int openmode; - /* controls.h */ @@ -627,6 +619,7 @@ int LoadConfig(const char *filename); int LoadDMXGUS(); extern int LoadConfig(); extern void FreeAll(); +extern PathExpander pathExpander; extern ToneBank *tonebank[MAXBANK]; extern ToneBank *drumset[MAXBANK]; From c3862d910142ac726358f0838aeb5d9e535cefd0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Dec 2015 21:18:46 +0100 Subject: [PATCH 03/15] - use PathExpander class for WildMidi's file access functions so that it can find Timdity's data on its own. --- src/wildmidi/file_io.cpp | 49 +++++++++++++++++++++++++++++++---- src/wildmidi/file_io.h | 2 +- src/wildmidi/wildmidi_lib.cpp | 2 +- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/wildmidi/file_io.cpp b/src/wildmidi/file_io.cpp index c2ef55715..50a2a6b6c 100644 --- a/src/wildmidi/file_io.cpp +++ b/src/wildmidi/file_io.cpp @@ -38,18 +38,56 @@ #include "../files.h" #include "wm_error.h" #include "file_io.h" +#include "pathexpander.h" +#include "cmdlib.h" -unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size) +static PathExpander wmPathExpander; + +unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size, bool ismain) { - FileReader file; + FileReader *fp; + int lumpnum; - if (!file.Open(filename)) + if (ismain) + { + wmPathExpander.openmode = PathExpander::OM_FILEORLUMP; + wmPathExpander.clearPathlist(); +#ifdef _WIN32 + wmPathExpander.addToPathlist("C:\\TIMIDITY"); + wmPathExpander.addToPathlist("\\TIMIDITY"); + wmPathExpander.addToPathlist(progdir); +#else + wmPathExpander.addToPathlist("/usr/local/lib/timidity"); + wmPathExpander.addToPathlist("/etc/timidity"); + wmPathExpander.addToPathlist("/etc"); +#endif + } + + if (!(fp = wmPathExpander.openFileReader(filename, &lumpnum))) + return NULL; + + if (ismain) + { + if (lumpnum > 0) + { + wmPathExpander.openmode = PathExpander::OM_LUMP; + wmPathExpander.clearPathlist(); // when reading from a PK3 we don't want to use any external path + } + else + { + wmPathExpander.openmode = PathExpander::OM_FILE; + } + } + + + + if (fp == NULL) { _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LOAD, filename, errno); return NULL; } - long fsize = file.GetLength(); + long fsize = fp->GetLength(); if (fsize > WM_MAXFILESIZE) { @@ -66,7 +104,8 @@ unsigned char *_WM_BufferFile(const char *filename, unsigned long int *size) return NULL; } - file.Read(data, fsize); + fp->Read(data, fsize); + delete fp; data[fsize] = 0; *size = fsize; return data; diff --git a/src/wildmidi/file_io.h b/src/wildmidi/file_io.h index d38caffbb..550a8a4b2 100644 --- a/src/wildmidi/file_io.h +++ b/src/wildmidi/file_io.h @@ -28,6 +28,6 @@ #define __FILE_IO_H #define WM_MAXFILESIZE 0x1fffffff -extern unsigned char *_WM_BufferFile (const char *filename, unsigned long int *size); +extern unsigned char *_WM_BufferFile (const char *filename, unsigned long int *size, bool mainfile = false); #endif /* __FILE_IO_H */ diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index 19e290f6b..eebd42830 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -645,7 +645,7 @@ static int WM_LoadConfig(const char *config_file) { char **line_tokens = NULL; int token_count = 0; - config_buffer = (char *) _WM_BufferFile(config_file, &config_size); + config_buffer = (char *) _WM_BufferFile(config_file, &config_size, true); if (!config_buffer) { WM_FreePatches(); return -1; From e0f9a59a9ac00291abdbda2c19e602a7e29937dd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Dec 2015 22:14:40 +0100 Subject: [PATCH 04/15] - add WildMidi config file CVAR to menu. --- wadsrc/static/menudef.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index eef2629d3..94de2b96c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1608,6 +1608,9 @@ OptionMenu AdvSoundOptions Option "Reverb", "timidity_reverb", "OnOff" Option "Chorus", "timidity_chorus", "OnOff" Slider "Relative volume", "timidity_mastervolume", 0, 4, 0.2, 1 + StaticText " " + StaticText "WildMidi", 1 + TextField "WildMidi config file", "wildmidi_config" } /*======================================= From 0cc4bd56d189958f1b7652312de634eea49494e2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Dec 2015 23:18:39 +0100 Subject: [PATCH 05/15] - removed the original WildMidi loader and the main playback function because none of those is actually being used anymore. --- src/wildmidi/wildmidi_lib.cpp | 1374 --------------------------------- src/wildmidi/wildmidi_lib.h | 5 - 2 files changed, 1379 deletions(-) diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index eebd42830..4372f8436 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -151,10 +151,6 @@ struct _event_data { struct _mdi { int lock; unsigned long int samples_to_mix; - struct _event *events; - struct _event *current_event; - unsigned long int event_count; - unsigned long int events_size; /* try to stay optimally ahead to prevent reallocs */ unsigned short midi_master_vol; struct _WM_Info info; @@ -173,13 +169,6 @@ struct _mdi { struct _rvb *reverb; }; -struct _event { - void (*do_event)(struct _mdi *mdi, struct _event_data *data); - struct _event_data event_data; - unsigned long int samples_to_next; - unsigned long int samples_to_next_fixed; -}; - #define FPBITS 10 #define FPMASK ((1L<event_count >= mdi->events_size) { - mdi->events_size += MEM_CHUNK; - mdi->events = (struct _event*)realloc(mdi->events, - (mdi->events_size * sizeof(struct _event))); - } -} - static void WM_InitPatches(void) { int i; for (i = 0; i < 128; i++) { @@ -2005,257 +1986,6 @@ static void do_sysex_roland_reset(struct _mdi *mdi, struct _event_data *data) { UNUSED(data); /* NOOP, to please the compiler gods */ } -static void WM_ResetToStart(midi * handle) { - struct _mdi *mdi = (struct _mdi *) handle; - - mdi->current_event = mdi->events; - mdi->samples_to_mix = 0; - mdi->info.current_sample = 0; - - do_sysex_roland_reset(mdi, NULL); -} - -static int midi_setup_noteoff(struct _mdi *mdi, unsigned char channel, - unsigned char note, unsigned char velocity) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_note_off; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = (note << 8) - | velocity; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_note_off; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = (note << 8) | velocity; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - return 0; -} - -static int midi_setup_noteon(struct _mdi *mdi, unsigned char channel, - unsigned char note, unsigned char velocity) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_note_on; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = (note << 8) - | velocity; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_note_on; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = (note << 8) | velocity; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - - if (mdi->channel[channel].isdrum) - load_patch(mdi, ((mdi->channel[channel].bank << 8) | (note | 0x80))); - return 0; -} - -static int midi_setup_aftertouch(struct _mdi *mdi, unsigned char channel, - unsigned char note, unsigned char pressure) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_aftertouch; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = (note << 8) - | pressure; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_aftertouch; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = (note << 8) | pressure; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - return 0; -} - -static int midi_setup_control(struct _mdi *mdi, unsigned char channel, - unsigned char controller, unsigned char setting) { - void (*tmp_event)(struct _mdi *mdi, struct _event_data *data) = NULL; - - switch (controller) { - case 0: - tmp_event = *do_control_bank_select; - mdi->channel[channel].bank = setting; - break; - case 6: - tmp_event = *do_control_data_entry_course; - break; - case 7: - tmp_event = *do_control_channel_volume; - mdi->channel[channel].volume = setting; - break; - case 8: - tmp_event = *do_control_channel_balance; - break; - case 10: - tmp_event = *do_control_channel_pan; - break; - case 11: - tmp_event = *do_control_channel_expression; - break; - case 38: - tmp_event = *do_control_data_entry_fine; - break; - case 64: - tmp_event = *do_control_channel_hold; - break; - case 96: - tmp_event = *do_control_data_increment; - break; - case 97: - tmp_event = *do_control_data_decrement; - break; - case 98: - case 99: - tmp_event = *do_control_non_registered_param; - break; - case 100: - tmp_event = *do_control_registered_param_fine; - break; - case 101: - tmp_event = *do_control_registered_param_course; - break; - case 120: - tmp_event = *do_control_channel_sound_off; - break; - case 121: - tmp_event = *do_control_channel_controllers_off; - break; - case 123: - tmp_event = *do_control_channel_notes_off; - break; - default: - return 0; - } - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = tmp_event; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = setting; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = tmp_event; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = setting; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - return 0; -} - -static int midi_setup_patch(struct _mdi *mdi, unsigned char channel, - unsigned char patch) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_patch; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = patch; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_patch; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = patch; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - if (mdi->channel[channel].isdrum) { - mdi->channel[channel].bank = patch; - } else { - load_patch(mdi, ((mdi->channel[channel].bank << 8) | patch)); - mdi->channel[channel].patch = get_patch_data( - ((mdi->channel[channel].bank << 8) | patch)); - } - return 0; -} - -static int midi_setup_channel_pressure(struct _mdi *mdi, unsigned char channel, - unsigned char pressure) { - - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_channel_pressure; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = pressure; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_channel_pressure; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = pressure; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - - return 0; -} - -static int midi_setup_pitch(struct _mdi *mdi, unsigned char channel, - unsigned short pitch) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_pitch; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = pitch; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_pitch; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = pitch; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - return 0; -} - -static int midi_setup_sysex_roland_drum_track(struct _mdi *mdi, - unsigned char channel, unsigned short setting) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = - *do_sysex_roland_drum_track; - mdi->events[mdi->event_count - 1].event_data.channel = channel; - mdi->events[mdi->event_count - 1].event_data.data = setting; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_sysex_roland_drum_track; - mdi->events[mdi->event_count].event_data.channel = channel; - mdi->events[mdi->event_count].event_data.data = setting; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - - if (setting > 0) { - mdi->channel[channel].isdrum = 1; - } else { - mdi->channel[channel].isdrum = 0; - } - - return 0; -} - -static int midi_setup_sysex_roland_reset(struct _mdi *mdi) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].do_event = *do_sysex_roland_reset; - mdi->events[mdi->event_count - 1].event_data.channel = 0; - mdi->events[mdi->event_count - 1].event_data.data = 0; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = *do_sysex_roland_reset; - mdi->events[mdi->event_count].event_data.channel = 0; - mdi->events[mdi->event_count].event_data.data = 0; - mdi->events[mdi->event_count].samples_to_next = 0; - mdi->event_count++; - } - return 0; -} - static int add_handle(void * handle) { struct _hndl *tmp_handle = NULL; @@ -2299,15 +2029,6 @@ Init_MDI(void) { load_patch(mdi, 0x0000); - mdi->events_size = MEM_CHUNK; - mdi->events = (struct _event*)malloc(mdi->events_size * sizeof(struct _event)); - mdi->events[0].do_event = NULL; - mdi->events[0].event_data.channel = 0; - mdi->events[0].event_data.data = 0; - mdi->events[0].samples_to_next = 0; - mdi->event_count++; - - mdi->current_event = mdi->events; mdi->samples_to_mix = 0; mdi->info.current_sample = 0; mdi->info.total_midi_time = 0; @@ -2341,7 +2062,6 @@ static void freeMDI(struct _mdi *mdi) { free(mdi->patches); } - free(mdi->events); free(mdi->tmp_info); _WM_free_reverb(mdi->reverb); free(mdi->mix_buffer); @@ -2392,807 +2112,6 @@ static unsigned long int get_decay_samples(struct _patch *patch, unsigned char n return decay_samples; } -static struct _mdi * -WM_ParseNewMidi(unsigned char *midi_data, unsigned int midi_size) { - struct _mdi *mdi; - unsigned int tmp_val; - unsigned int midi_type; - unsigned int track_size; - unsigned char **tracks; - unsigned int end_of_tracks = 0; - unsigned int no_tracks; - unsigned int i; - unsigned int divisions = 96; - unsigned int tempo = 500000; - float samples_per_delta_f = 0.0; - float microseconds_per_pulse = 0.0; - float pulses_per_second = 0.0; - - unsigned long int sample_count = 0; - float sample_count_tmp = 0; - float sample_remainder = 0; - unsigned char *sysex_store = NULL; - unsigned long int sysex_store_len = 0; - - unsigned long int *track_delta; - unsigned char *track_end; - unsigned long int smallest_delta = 0; - unsigned long int subtract_delta = 0; - unsigned long int tmp_length = 0; - unsigned char current_event = 0; - unsigned char current_event_ch = 0; - unsigned char *running_event; - unsigned long int decay_samples = 0; - - if (memcmp(midi_data, "RIFF", 4) == 0) { - midi_data += 20; - midi_size -= 20; - } - if (memcmp(midi_data, "MThd", 4)) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_MIDI, NULL, 0); - return NULL; - } - midi_data += 4; - midi_size -= 4; - - if (midi_size < 10) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); - return NULL; - } - - /* - * Get Midi Header Size - must always be 6 - */ - tmp_val = *midi_data++ << 24; - tmp_val |= *midi_data++ << 16; - tmp_val |= *midi_data++ << 8; - tmp_val |= *midi_data++; - midi_size -= 4; - if (tmp_val != 6) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); - return NULL; - } - - /* - * Get Midi Format - we only support 0, 1 & 2 - */ - tmp_val = *midi_data++ << 8; - tmp_val |= *midi_data++; - midi_size -= 2; - if (tmp_val > 2) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); - return NULL; - } - midi_type = tmp_val; - - /* - * Get No. of Tracks - */ - tmp_val = *midi_data++ << 8; - tmp_val |= *midi_data++; - midi_size -= 2; - if (tmp_val < 1) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(no tracks)", 0); - return NULL; - } - no_tracks = tmp_val; - - /* - * Check that type 0 midi file has only 1 track - */ - if ((midi_type == 0) && (no_tracks > 1)) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, "(expected 1 track for type 0 midi file, found more)", 0); - return NULL; - } - - /* - * Get Divisions - */ - divisions = *midi_data++ << 8; - divisions |= *midi_data++; - midi_size -= 2; - if (divisions & 0x00008000) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID, NULL, 0); - return NULL; - } - - if ((WM_MixerOptions & WM_MO_WHOLETEMPO)) { - float bpm_f = (float) (60000000 / tempo); - tempo = 60000000 / (unsigned long int) bpm_f; - } else if ((WM_MixerOptions & WM_MO_ROUNDTEMPO)) { - float bpm_fr = (float) (60000000 / tempo) + 0.5f; - tempo = 60000000 / (unsigned long int) bpm_fr; - } - /* Slow but needed for accuracy */ - microseconds_per_pulse = (float) tempo / (float) divisions; - pulses_per_second = 1000000.0f / microseconds_per_pulse; - samples_per_delta_f = (float) _WM_SampleRate / pulses_per_second; - - mdi = Init_MDI(); - - tracks = (unsigned char**)malloc(sizeof(unsigned char *) * no_tracks); - track_delta = (unsigned long*)malloc(sizeof(unsigned long int) * no_tracks); - track_end = (unsigned char*)malloc(sizeof(unsigned char) * no_tracks); - running_event = (unsigned char*)malloc(sizeof(unsigned char) * no_tracks); - - for (i = 0; i < no_tracks; i++) { - if (midi_size < 8) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); - goto _end; - } - if (memcmp(midi_data, "MTrk", 4) != 0) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing track header)", 0); - goto _end; - } - midi_data += 4; - midi_size -= 4; - - track_size = *midi_data++ << 24; - track_size |= *midi_data++ << 16; - track_size |= *midi_data++ << 8; - track_size |= *midi_data++; - midi_size -= 4; - if (midi_size < track_size) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); - goto _end; - } - if ((midi_data[track_size - 3] != 0xFF) - || (midi_data[track_size - 2] != 0x2F) - || (midi_data[track_size - 1] != 0x00)) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing EOT)", 0); - goto _end; - } - tracks[i] = midi_data; - midi_data += track_size; - midi_size -= track_size; - track_end[i] = 0; - running_event[i] = 0; - track_delta[i] = 0; - decay_samples = 0; - while (*tracks[i] > 0x7F) { - track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - } - track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - } - - /* - * Handle type 0 & 1 the same, but type 2 differently - */ - switch (midi_type) { - case 0: - case 1: - /* Type 0 & 1 can use the same code */ - while (end_of_tracks != no_tracks) { - smallest_delta = 0; - for (i = 0; i < no_tracks; i++) { - if (track_end[i]) - continue; - - if (track_delta[i]) { - track_delta[i] -= subtract_delta; - if (track_delta[i]) { - if ((!smallest_delta) - || (smallest_delta > track_delta[i])) { - smallest_delta = track_delta[i]; - } - continue; - } - } - do { - if (*tracks[i] > 0x7F) { - current_event = *tracks[i]; - tracks[i]++; - } else { - current_event = running_event[i]; - if (running_event[i] < 0x80) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); - goto _end; - } - } - current_event_ch = current_event & 0x0F; - switch (current_event >> 4) { - case 0x8: - NOTEOFF: midi_setup_noteoff(mdi, current_event_ch, - tracks[i][0], tracks[i][1]); - /* To better calculate samples needed after the end of midi, - * we calculate samples for decay for note off */ - { - unsigned long int tmp_decay_samples = 0; - struct _patch *tmp_patch = NULL; - if (mdi->channel[current_event_ch].isdrum) { - tmp_patch = get_patch_data( - ((mdi->channel[current_event_ch].bank << 8) - | tracks[i][0] | 0x80)); - /* if (tmp_patch == NULL) - printf("Drum patch not loaded 0x%02x on channel %i\n",((mdi->channel[current_event_ch].bank << 8) | tracks[i][0] | 0x80),current_event_ch);*/ - } else { - tmp_patch = mdi->channel[current_event_ch].patch; - /* if (tmp_patch == NULL) - printf("Channel %i patch not loaded\n", current_event_ch);*/ - } - tmp_decay_samples = get_decay_samples(tmp_patch, - tracks[i][0]); - /* if the note off decay is more than the decay we currently tracking then - * we set it to new decay. */ - if (tmp_decay_samples > decay_samples) { - decay_samples = tmp_decay_samples; - } - } - - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0x9: - if (tracks[i][1] == 0) { - goto NOTEOFF; - } - midi_setup_noteon(mdi, (current_event & 0x0F), tracks[i][0], - tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xA: - midi_setup_aftertouch(mdi, (current_event & 0x0F), - tracks[i][0], tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xB: - midi_setup_control(mdi, (current_event & 0x0F), - tracks[i][0], tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xC: - midi_setup_patch(mdi, (current_event & 0x0F), *tracks[i]); - tracks[i]++; - running_event[i] = current_event; - break; - case 0xD: - midi_setup_channel_pressure(mdi, (current_event & 0x0F), - *tracks[i]); - tracks[i]++; - running_event[i] = current_event; - break; - case 0xE: - midi_setup_pitch(mdi, (current_event & 0x0F), - ((tracks[i][1] << 7) | (tracks[i][0] & 0x7F))); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xF: /* Meta Event */ - if (current_event == 0xFF) { - if (tracks[i][0] == 0x02) { /* Copyright Event */ - /* Get Length */ - tmp_length = 0; - tracks[i]++; - while (*tracks[i] > 0x7f) { - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i]++; - } - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - /* Copy copyright info in the getinfo struct */ - if (mdi->info.copyright) { - mdi->info.copyright = (char*)realloc( - mdi->info.copyright, - (strlen(mdi->info.copyright) + 1 - + tmp_length + 1)); - strncpy( - &mdi->info.copyright[strlen( - mdi->info.copyright) + 1], - (char *) tracks[i], tmp_length); - mdi->info.copyright[strlen(mdi->info.copyright) - + 1 + tmp_length] = '\0'; - mdi->info.copyright[strlen(mdi->info.copyright)] = '\n'; - - } else { - mdi->info.copyright = (char*)malloc(tmp_length + 1); - strncpy(mdi->info.copyright, (char *) tracks[i], - tmp_length); - mdi->info.copyright[tmp_length] = '\0'; - } - tracks[i] += tmp_length + 1; - } else if ((tracks[i][0] == 0x2F) - && (tracks[i][1] == 0x00)) { - /* End of Track */ - end_of_tracks++; - track_end[i] = 1; - goto NEXT_TRACK; - } else if ((tracks[i][0] == 0x51) - && (tracks[i][1] == 0x03)) { - /* Tempo */ - tempo = (tracks[i][2] << 16) + (tracks[i][3] << 8) - + tracks[i][4]; - tracks[i] += 5; - if (!tempo) - tempo = 500000; - - if ((WM_MixerOptions & WM_MO_WHOLETEMPO)) { - float bpm_f = (float) (60000000 / tempo); - tempo = 60000000 - / (unsigned long int) bpm_f; - } else if ((WM_MixerOptions & WM_MO_ROUNDTEMPO)) { - float bpm_fr = (float) (60000000 / tempo) - + 0.5f; - tempo = 60000000 - / (unsigned long int) bpm_fr; - } - /* Slow but needed for accuracy */ - microseconds_per_pulse = (float) tempo - / (float) divisions; - pulses_per_second = 1000000.0f - / microseconds_per_pulse; - samples_per_delta_f = (float) _WM_SampleRate - / pulses_per_second; - - } else { - tmp_length = 0; - tracks[i]++; - while (*tracks[i] > 0x7f) { - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i]++; - } - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i] += tmp_length + 1; - } - } else if ((current_event == 0xF0) - || (current_event == 0xF7)) { - /* Roland Sysex Events */ - unsigned long int sysex_len = 0; - while (*tracks[i] > 0x7F) { - sysex_len = (sysex_len << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - } - sysex_len = (sysex_len << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - - running_event[i] = 0; - - sysex_store = (unsigned char*)realloc(sysex_store, - sizeof(unsigned char) - * (sysex_store_len + sysex_len)); - memcpy(&sysex_store[sysex_store_len], tracks[i], - sysex_len); - sysex_store_len += sysex_len; - - if (sysex_store[sysex_store_len - 1] == 0xF7) { - unsigned char tmpsysexdata[] = { 0x41, 0x10, 0x42, 0x12 }; - if (memcmp(tmpsysexdata, sysex_store, 4) == 0) { - /* checksum */ - unsigned char sysex_cs = 0; - unsigned int sysex_ofs = 4; - do { - sysex_cs += sysex_store[sysex_ofs]; - if (sysex_cs > 0x7F) { - sysex_cs -= 0x80; - } - sysex_ofs++; - } while (sysex_store[sysex_ofs + 1] != 0xF7); - sysex_cs = 128 - sysex_cs; - /* is roland sysex message valid */ - if (sysex_cs == sysex_store[sysex_ofs]) { - /* process roland sysex event */ - if (sysex_store[4] == 0x40) { - if (((sysex_store[5] & 0xF0) == 0x10) - && (sysex_store[6] == 0x15)) { - /* Roland Drum Track Setting */ - unsigned char sysex_ch = 0x0F - & sysex_store[5]; - if (sysex_ch == 0x00) { - sysex_ch = 0x09; - } else if (sysex_ch <= 0x09) { - sysex_ch -= 1; - } - midi_setup_sysex_roland_drum_track( - mdi, sysex_ch, - sysex_store[7]); - } else if ((sysex_store[5] == 0x00) - && (sysex_store[6] == 0x7F) - && (sysex_store[7] == 0x00)) { - /* Roland GS Reset */ - midi_setup_sysex_roland_reset(mdi); - } - } - } - } - free(sysex_store); - sysex_store = NULL; - sysex_store_len = 0; - } - tracks[i] += sysex_len; - } else { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(unrecognized meta event)", 0); - goto _end; - } - break; - default: - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(unrecognized event)", 0); - goto _end; - } - while (*tracks[i] > 0x7F) { - track_delta[i] = (track_delta[i] << 7) - + (*tracks[i] & 0x7F); - tracks[i]++; - } - track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - } while (!track_delta[i]); - if ((!smallest_delta) || (smallest_delta > track_delta[i])) { - smallest_delta = track_delta[i]; - } - NEXT_TRACK: continue; - } - - subtract_delta = smallest_delta; - sample_count_tmp = (((float) smallest_delta * samples_per_delta_f) - + sample_remainder); - sample_count = (unsigned long int) sample_count_tmp; - sample_remainder = sample_count_tmp - (float) sample_count; - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].samples_to_next += sample_count; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = NULL; - mdi->events[mdi->event_count].event_data.channel = 0; - mdi->events[mdi->event_count].event_data.data = 0; - mdi->events[mdi->event_count].samples_to_next = sample_count; - mdi->event_count++; - } - mdi->info.approx_total_samples += sample_count; - /* printf("Decay Samples = %lu\n",decay_samples);*/ - if (decay_samples > sample_count) { - decay_samples -= sample_count; - } else { - decay_samples = 0; - } - } - break; - - case 2: /* Type 2 has to be handled differently */ - for (i = 0; i < no_tracks; i++) { - sample_remainder = 0.0; - decay_samples = 0; - track_delta[i] = 0; - do { - if(track_delta[i]) { - sample_count_tmp = (((float) track_delta[i] * samples_per_delta_f) - + sample_remainder); - sample_count = (unsigned long int) sample_count_tmp; - sample_remainder = sample_count_tmp - (float) sample_count; - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].samples_to_next += sample_count; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = NULL; - mdi->events[mdi->event_count].event_data.channel = 0; - mdi->events[mdi->event_count].event_data.data = 0; - mdi->events[mdi->event_count].samples_to_next = sample_count; - mdi->event_count++; - } - mdi->info.approx_total_samples += sample_count; - /* printf("Decay Samples = %lu\n",decay_samples);*/ - if (decay_samples > sample_count) { - decay_samples -= sample_count; - } else { - decay_samples = 0; - } - } - if (*tracks[i] > 0x7F) { - current_event = *tracks[i]; - tracks[i]++; - } else { - current_event = running_event[i]; - if (running_event[i] < 0x80) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); - goto _end; - } - } - current_event_ch = current_event & 0x0F; - switch (current_event >> 4) { - case 0x8: - NOTEOFF2: midi_setup_noteoff(mdi, current_event_ch, - tracks[i][0], tracks[i][1]); - /* To better calculate samples needed after the end of midi, - * we calculate samples for decay for note off */ - { - unsigned long int tmp_decay_samples = 0; - struct _patch *tmp_patch = NULL; - - if (mdi->channel[current_event_ch].isdrum) { - tmp_patch = get_patch_data( - ((mdi->channel[current_event_ch].bank << 8) - | tracks[i][0] | 0x80)); - /* if (tmp_patch == NULL) - printf("Drum patch not loaded 0x%02x on channel %i\n",((mdi->channel[current_event_ch].bank << 8) | tracks[i][0] | 0x80),current_event_ch);*/ - } else { - tmp_patch = mdi->channel[current_event_ch].patch; - /* if (tmp_patch == NULL) - printf("Channel %i patch not loaded\n", current_event_ch);*/ - } - tmp_decay_samples = get_decay_samples(tmp_patch, - tracks[i][0]); - /* if the note off decay is more than the decay we currently tracking then - * we set it to new decay. */ - if (tmp_decay_samples > decay_samples) { - decay_samples = tmp_decay_samples; - } - } - - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0x9: - if (tracks[i][1] == 0) { - goto NOTEOFF2; - } - midi_setup_noteon(mdi, (current_event & 0x0F), tracks[i][0], - tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xA: - midi_setup_aftertouch(mdi, (current_event & 0x0F), - tracks[i][0], tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xB: - midi_setup_control(mdi, (current_event & 0x0F), - tracks[i][0], tracks[i][1]); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xC: - midi_setup_patch(mdi, (current_event & 0x0F), *tracks[i]); - tracks[i]++; - running_event[i] = current_event; - break; - case 0xD: - midi_setup_channel_pressure(mdi, (current_event & 0x0F), - *tracks[i]); - tracks[i]++; - running_event[i] = current_event; - break; - case 0xE: - midi_setup_pitch(mdi, (current_event & 0x0F), - ((tracks[i][1] << 7) | (tracks[i][0] & 0x7F))); - tracks[i] += 2; - running_event[i] = current_event; - break; - case 0xF: /* Meta Event */ - if (current_event == 0xFF) { - if (tracks[i][0] == 0x02) { /* Copyright Event */ - /* Get Length */ - tmp_length = 0; - tracks[i]++; - while (*tracks[i] > 0x7f) { - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i]++; - } - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - /* Copy copyright info in the getinfo struct */ - if (mdi->info.copyright) { - mdi->info.copyright = (char*)realloc( - mdi->info.copyright, - (strlen(mdi->info.copyright) + 1 - + tmp_length + 1)); - strncpy( - &mdi->info.copyright[strlen( - mdi->info.copyright) + 1], - (char *) tracks[i], tmp_length); - mdi->info.copyright[strlen(mdi->info.copyright) - + 1 + tmp_length] = '\0'; - mdi->info.copyright[strlen(mdi->info.copyright)] = '\n'; - - } else { - mdi->info.copyright = (char*)malloc(tmp_length + 1); - strncpy(mdi->info.copyright, (char *) tracks[i], - tmp_length); - mdi->info.copyright[tmp_length] = '\0'; - } - tracks[i] += tmp_length + 1; - } else if ((tracks[i][0] == 0x2F) - && (tracks[i][1] == 0x00)) { - /* End of Track */ - end_of_tracks++; - track_end[i] = 1; - goto NEXT_TRACK2; - } else if ((tracks[i][0] == 0x51) - && (tracks[i][1] == 0x03)) { - /* Tempo */ - tempo = (tracks[i][2] << 16) + (tracks[i][3] << 8) - + tracks[i][4]; - tracks[i] += 5; - if (!tempo) - tempo = 500000; - - if ((WM_MixerOptions & WM_MO_WHOLETEMPO)) { - float bpm_f = (float) (60000000 / tempo); - tempo = 60000000 - / (unsigned long int) bpm_f; - } else if ((WM_MixerOptions & WM_MO_ROUNDTEMPO)) { - float bpm_fr = (float) (60000000 / tempo) - + 0.5f; - tempo = 60000000 - / (unsigned long int) bpm_fr; - } - /* Slow but needed for accuracy */ - microseconds_per_pulse = (float) tempo - / (float) divisions; - pulses_per_second = 1000000.0f - / microseconds_per_pulse; - samples_per_delta_f = (float) _WM_SampleRate - / pulses_per_second; - - } else { - tmp_length = 0; - tracks[i]++; - while (*tracks[i] > 0x7f) { - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i]++; - } - tmp_length = (tmp_length << 7) - + (*tracks[i] & 0x7f); - tracks[i] += tmp_length + 1; - } - } else if ((current_event == 0xF0) - || (current_event == 0xF7)) { - /* Roland Sysex Events */ - unsigned long int sysex_len = 0; - while (*tracks[i] > 0x7F) { - sysex_len = (sysex_len << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - } - sysex_len = (sysex_len << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - - running_event[i] = 0; - - sysex_store = (unsigned char*)realloc(sysex_store, - sizeof(unsigned char) - * (sysex_store_len + sysex_len)); - memcpy(&sysex_store[sysex_store_len], tracks[i], - sysex_len); - sysex_store_len += sysex_len; - - if (sysex_store[sysex_store_len - 1] == 0xF7) { - unsigned char tmpsysexdata[] = { 0x41, 0x10, 0x42, 0x12 }; - if (memcmp(tmpsysexdata, sysex_store, 4) == 0) { - /* checksum */ - unsigned char sysex_cs = 0; - unsigned int sysex_ofs = 4; - do { - sysex_cs += sysex_store[sysex_ofs]; - if (sysex_cs > 0x7F) { - sysex_cs -= 0x80; - } - sysex_ofs++; - } while (sysex_store[sysex_ofs + 1] != 0xF7); - sysex_cs = 128 - sysex_cs; - /* is roland sysex message valid */ - if (sysex_cs == sysex_store[sysex_ofs]) { - /* process roland sysex event */ - if (sysex_store[4] == 0x40) { - if (((sysex_store[5] & 0xF0) == 0x10) - && (sysex_store[6] == 0x15)) { - /* Roland Drum Track Setting */ - unsigned char sysex_ch = 0x0F - & sysex_store[5]; - if (sysex_ch == 0x00) { - sysex_ch = 0x09; - } else if (sysex_ch <= 0x09) { - sysex_ch -= 1; - } - midi_setup_sysex_roland_drum_track( - mdi, sysex_ch, - sysex_store[7]); - } else if ((sysex_store[5] == 0x00) - && (sysex_store[6] == 0x7F) - && (sysex_store[7] == 0x00)) { - /* Roland GS Reset */ - midi_setup_sysex_roland_reset(mdi); - } - } - } - } - free(sysex_store); - sysex_store = NULL; - sysex_store_len = 0; - } - tracks[i] += sysex_len; - } else { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(unrecognized meta event)", 0); - goto _end; - } - break; - default: - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(unrecognized event)", 0); - goto _end; - } - track_delta[i] = 0; - while (*tracks[i] > 0x7F) { - track_delta[i] = (track_delta[i] << 7) - + (*tracks[i] & 0x7F); - tracks[i]++; - } - track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); - tracks[i]++; - NEXT_TRACK2: - smallest_delta = track_delta[i]; /* Added just to keep Xcode happy */ - UNUSED(smallest_delta); /* Added to just keep clang happy */ - } while (track_end[i] == 0); - /* - * Add decay at the end of each song - */ - if (decay_samples) { - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->events[mdi->event_count - 1].samples_to_next += decay_samples; - } else { - WM_CheckEventMemoryPool(mdi); - mdi->events[mdi->event_count].do_event = NULL; - mdi->events[mdi->event_count].event_data.channel = 0; - mdi->events[mdi->event_count].event_data.data = 0; - mdi->events[mdi->event_count].samples_to_next = decay_samples; - mdi->event_count++; - } - } - } - break; - - default: break; /* Don't expect to get here, added for completeness */ - } - - if ((mdi->event_count) - && (mdi->events[mdi->event_count - 1].do_event == NULL)) { - mdi->info.approx_total_samples -= - mdi->events[mdi->event_count - 1].samples_to_next; - mdi->event_count--; - } - /* Set total MIDI time to 1/1000's seconds */ - mdi->info.total_midi_time = (mdi->info.approx_total_samples * 1000) - / _WM_SampleRate; - /*mdi->info.approx_total_samples += _WM_SampleRate * 3;*/ - - /* Add additional samples needed for decay */ - mdi->info.approx_total_samples += decay_samples; - /*printf("decay_samples = %lu\n",decay_samples);*/ - - if ((mdi->reverb = _WM_init_reverb(_WM_SampleRate, reverb_room_width, - reverb_room_length, reverb_listen_posx, reverb_listen_posy)) - == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); - goto _end; - } - - mdi->info.current_sample = 0; - mdi->current_event = &mdi->events[0]; - mdi->samples_to_mix = 0; - mdi->note = NULL; - - WM_ResetToStart(mdi); - -_end: free(sysex_store); - free(track_end); - free(track_delta); - free(running_event); - free(tracks); - if (mdi->reverb) return mdi; - freeMDI(mdi); - return NULL; -} - static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count) { struct _mdi *mdi = (struct _mdi *)handle; @@ -3635,107 +2554,6 @@ int *WM_Mix(midi *handle, int *buffer, unsigned long count) } } -static int WM_DoGetOutput(midi * handle, char * buffer, - unsigned long int size) { - unsigned long int buffer_used = 0; - unsigned long int i; - struct _mdi *mdi = (struct _mdi *) handle; - unsigned long int real_samples_to_mix = 0; - struct _event *event = mdi->current_event; - signed int *tmp_buffer; - signed int *out_buffer; - signed int left_mix, right_mix; - - _WM_Lock(&mdi->lock); - - buffer_used = 0; - memset(buffer, 0, size); - if ( (size / 2) > mdi->mix_buffer_size) { - if ( (size / 2) <= ( mdi->mix_buffer_size * 2 )) { - mdi->mix_buffer_size += MEM_CHUNK; - } else { - mdi->mix_buffer_size = size / 2; - } - mdi->mix_buffer = (int*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed int)); - } - tmp_buffer = mdi->mix_buffer; - memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int))); - out_buffer = tmp_buffer; - - do { - if (!mdi->samples_to_mix) { - while ((!mdi->samples_to_mix) && (event->do_event)) { - event->do_event(mdi, &event->event_data); - event++; - mdi->samples_to_mix = event->samples_to_next; - mdi->current_event = event; - } - - if (!mdi->samples_to_mix) { - if (mdi->info.current_sample - >= mdi->info.approx_total_samples) { - break; - } else if ((mdi->info.approx_total_samples - - mdi->info.current_sample) > (size >> 2)) { - mdi->samples_to_mix = size >> 2; - } else { - mdi->samples_to_mix = mdi->info.approx_total_samples - - mdi->info.current_sample; - } - } - } - if (mdi->samples_to_mix > (size >> 2)) { - real_samples_to_mix = size >> 2; - } else { - real_samples_to_mix = mdi->samples_to_mix; - if (real_samples_to_mix == 0) { - continue; - } - } - - /* do mixing here */ - tmp_buffer = WM_Mix(handle, tmp_buffer, real_samples_to_mix); - - buffer_used += real_samples_to_mix * 4; - size -= (real_samples_to_mix << 2); - mdi->info.current_sample += real_samples_to_mix; - mdi->samples_to_mix -= real_samples_to_mix; - } while (size); - - tmp_buffer = out_buffer; - - if (mdi->info.mixer_options & WM_MO_REVERB) { - _WM_do_reverb(mdi->reverb, tmp_buffer, (buffer_used / 2)); - } - - for (i = 0; i < buffer_used; i += 4) { - left_mix = *tmp_buffer++; - right_mix = *tmp_buffer++; - - if (left_mix > 32767) { - left_mix = 32767; - } else if (left_mix < -32768) { - left_mix = -32768; - } - - if (right_mix > 32767) { - right_mix = 32767; - } else if (right_mix < -32768) { - right_mix = -32768; - } - - /* - * =================== - * Write to the buffer - * =================== - */ - ((short *)buffer)[0] = (short)left_mix; - ((short *)buffer)[1] = (short)right_mix; - buffer += 4; - } - _WM_Unlock(&mdi->lock); - return buffer_used; -} /* * ========================= @@ -3874,69 +2692,6 @@ WM_SYMBOL int WildMidi_Close(midi * handle) { return 0; } -WM_SYMBOL midi * -WildMidi_Open(const char *midifile) { - unsigned char *mididata = NULL; - unsigned long int midisize = 0; - midi * ret = NULL; - - if (!WM_Initialized) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); - return NULL; - } - if (midifile == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL filename)", - 0); - return NULL; - } - - if ((mididata = _WM_BufferFile(midifile, &midisize)) == NULL) { - return NULL; - } - - ret = (void *) WM_ParseNewMidi(mididata, midisize); - free(mididata); - - if (ret) { - if (add_handle(ret) != 0) { - WildMidi_Close(ret); - ret = NULL; - } - } - - return ret; -} - -WM_SYMBOL midi * -WildMidi_OpenBuffer(unsigned char *midibuffer, unsigned long int size) { - midi * ret = NULL; - - if (!WM_Initialized) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); - return NULL; - } - if (midibuffer == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, - "(NULL midi data buffer)", 0); - return NULL; - } - if (size > WM_MAXFILESIZE) { - /* don't bother loading suspiciously long files */ - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_LONGFIL, NULL, 0); - return NULL; - } - ret = (void *) WM_ParseNewMidi(midibuffer, size); - - if (ret) { - if (add_handle(ret) != 0) { - WildMidi_Close(ret); - ret = NULL; - } - } - - return ret; -} - midi *WildMidi_NewMidi() { midi * ret = NULL; @@ -3954,135 +2709,6 @@ midi *WildMidi_NewMidi() { return ret; } -WM_SYMBOL int WildMidi_FastSeek(midi * handle, unsigned long int *sample_pos) { - struct _mdi *mdi; - struct _event *event; - struct _note *note_data; - unsigned long int real_samples_to_mix; - unsigned long int count; - - if (!WM_Initialized) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); - return -1; - } - if (handle == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", - 0); - return -1; - } - if (sample_pos == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, - "(NULL seek position pointer)", 0); - return -1; - } - - mdi = (struct _mdi *) handle; - _WM_Lock(&mdi->lock); - event = mdi->current_event; - - /* make sure we havent asked for a positions beyond the end of the song. */ - if (*sample_pos > mdi->info.approx_total_samples) { - /* if so set the position to the end of the song */ - *sample_pos = mdi->info.approx_total_samples; - } - - /* was end of song requested and are we are there? */ - if (*sample_pos == mdi->info.current_sample) { - /* yes */ - _WM_Unlock(&mdi->lock); - return 0; - } - - /* did we want to fast forward? */ - if (mdi->info.current_sample < *sample_pos) { - /* yes */ - count = *sample_pos - mdi->info.current_sample; - } else { - /* no, reset values to start as the beginning */ - count = *sample_pos; - WM_ResetToStart(handle); - event = mdi->current_event; - } - - /* clear the reverb buffers since we not gonna be using them here */ - _WM_reset_reverb(mdi->reverb); - - while (count) { - if (!mdi->samples_to_mix) { - while ((!mdi->samples_to_mix) && (event->do_event)) { - event->do_event(mdi, &event->event_data); - event++; - mdi->samples_to_mix = event->samples_to_next; - mdi->current_event = event; - } - - if (!mdi->samples_to_mix) { - if (event->do_event == NULL) { - mdi->samples_to_mix = mdi->info.approx_total_samples - - *sample_pos; - } else { - mdi->samples_to_mix = count; - } - } - } - - if (mdi->samples_to_mix > count) { - real_samples_to_mix = count; - } else { - real_samples_to_mix = mdi->samples_to_mix; - } - - if (real_samples_to_mix == 0) { - break; - } - - count -= real_samples_to_mix; - mdi->info.current_sample += real_samples_to_mix; - mdi->samples_to_mix -= real_samples_to_mix; - } - - note_data = mdi->note; - if (note_data) { - do { - note_data->active = 0; - if (note_data->replay) { - note_data->replay = NULL; - } - note_data = note_data->next; - } while (note_data); - } - mdi->note = NULL; - - _WM_Unlock(&mdi->lock); - return 0; -} - -WM_SYMBOL int WildMidi_GetOutput(midi * handle, char *buffer, unsigned long int size) { - if (!WM_Initialized) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_INIT, NULL, 0); - return -1; - } - if (handle == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(NULL handle)", - 0); - return -1; - } - if (buffer == NULL) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, - "(NULL buffer pointer)", 0); - return -1; - } - if (size == 0) { - return 0; - } - if (!!(size % 4)) { - _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, - "(size not a multiple of 4)", 0); - return -1; - } - return WM_DoGetOutput(handle, buffer, size); -} - WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options, unsigned short int setting) { struct _mdi *mdi; diff --git a/src/wildmidi/wildmidi_lib.h b/src/wildmidi/wildmidi_lib.h index 46a517d90..ec8dea3c1 100644 --- a/src/wildmidi/wildmidi_lib.h +++ b/src/wildmidi/wildmidi_lib.h @@ -56,12 +56,7 @@ typedef void midi; WM_SYMBOL const char * WildMidi_GetString (unsigned short int info); WM_SYMBOL int WildMidi_Init (const char * config_file, unsigned short int rate, unsigned short int options); WM_SYMBOL int WildMidi_MasterVolume (unsigned char master_volume); -WM_SYMBOL midi * WildMidi_Open (const char *midifile); -WM_SYMBOL midi * WildMidi_OpenBuffer (unsigned char *midibuffer, unsigned long int size); -WM_SYMBOL int WildMidi_GetOutput (midi * handle, char * buffer, unsigned long int size); WM_SYMBOL int WildMidi_SetOption (midi * handle, unsigned short int options, unsigned short int setting); -WM_SYMBOL struct _WM_Info * WildMidi_GetInfo (midi * handle); -WM_SYMBOL int WildMidi_FastSeek (midi * handle, unsigned long int *sample_pos); WM_SYMBOL int WildMidi_Close (midi * handle); WM_SYMBOL int WildMidi_Shutdown (void); WM_SYMBOL int WildMidi_GetSampleRate (void); From 14361d93138e2695d5fc6d7ed83d5e60aae6a09a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 16:04:26 -0600 Subject: [PATCH 06/15] Remove midi_timiditylike - Did anybody actually use this? Use WildMidi instead if you want something that sounds more like Timidity++ without actually being Timidity++, since not even the old Timidity manages that. --- src/timidity/instrum.cpp | 60 ++----------------------------- src/timidity/instrum_dls.cpp | 1 - src/timidity/instrum_sf2.cpp | 1 - src/timidity/mix.cpp | 69 ++++++------------------------------ src/timidity/playmidi.cpp | 23 +++--------- src/timidity/resample.cpp | 6 ++-- src/timidity/timidity.cpp | 14 ++------ src/timidity/timidity.h | 16 ++------- zdoom.vcproj | 8 +++++ 9 files changed, 33 insertions(+), 165 deletions(-) diff --git a/src/timidity/instrum.cpp b/src/timidity/instrum.cpp index a8c7b5f7c..fdfa4fd64 100644 --- a/src/timidity/instrum.cpp +++ b/src/timidity/instrum.cpp @@ -142,7 +142,7 @@ static void reverse_data(sample_t *sp, int ls, int le) TODO: do reverse loops right */ static Instrument *load_instrument(Renderer *song, const char *name, int percussion, - int panning, int amp, int note_to_use, + int panning, int note_to_use, int strip_loop, int strip_envelope, int strip_tail) { @@ -372,7 +372,6 @@ fail: { sp->modes &= ~(PATCH_SUSTAIN | PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD); } - sp->modes |= PATCH_T_NO_LOOP; } if (strip_envelope == 1) @@ -398,37 +397,6 @@ fail: patch_data.EnvelopeOffset[k] = patch_data.EnvelopeOffset[0]; } } - sp->modes |= PATCH_T_NO_ENVELOPE; - } - else if (strip_envelope != 0) - { - /* Have to make a guess. */ - if (!(sp->modes & (PATCH_LOOPEN | PATCH_BIDIR | PATCH_BACKWARD))) - { - /* No loop? Then what's there to sustain? No envelope needed either... */ - sp->modes |= PATCH_T_NO_ENVELOPE; - cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope\n"); - } - else if (memcmp(patch_data.EnvelopeRate, "??????", 6) == 0 || patch_data.EnvelopeOffset[GF1_RELEASEC] >= 100) - { - /* Envelope rates all maxed out? Envelope end at a high "offset"? - That's a weird envelope. Take it out. */ - sp->modes |= PATCH_T_NO_ENVELOPE; - cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope\n"); - } - else if (!(sp->modes & PATCH_SUSTAIN)) - { - /* No sustain? Then no envelope. I don't know if this is - justified, but patches without sustain usually don't need the - envelope either... at least the Gravis ones. They're mostly - drums. I think. */ - sp->modes |= PATCH_T_NO_ENVELOPE; - cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope\n"); - } - } - if (!(sp->modes & PATCH_NO_SRELEASE)) - { // TiMidity thinks that this is an envelope enable flag. - sp->modes |= PATCH_T_NO_ENVELOPE; } for (j = 0; j < 6; j++) @@ -470,29 +438,6 @@ fail: sp->modes |= PATCH_LOOPEN; /* just in case */ } - if (amp != -1) - { - sp->volume = (amp) / 100.f; - } - else - { - /* Try to determine a volume scaling factor for the sample. - This is a very crude adjustment, but things sound more - balanced with it. Still, this should be a runtime option. - (This is ignored unless midi_timiditylike is turned on.) */ - int i; - sample_t maxamp = 0, a; - sample_t *tmp; - for (i = sp->data_length, tmp = sp->data; i; --i) - { - a = fabsf(*tmp++); - if (a > maxamp) - maxamp = a; - } - sp->volume = 1 / maxamp; - cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f\n", sp->volume); - } - /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; @@ -653,7 +598,6 @@ static int fill_bank(Renderer *song, int dr, int b) ip = load_instrument(song, bank->tone[i].name, (dr) ? 1 : 0, bank->tone[i].pan, - bank->tone[i].amp, (bank->tone[i].note != -1) ? bank->tone[i].note : ((dr) ? i : -1), (bank->tone[i].strip_loop != -1) ? bank->tone[i].strip_loop : ((dr) ? 1 : -1), (bank->tone[i].strip_envelope != -1) ? bank->tone[i].strip_envelope : ((dr) ? 1 : -1), @@ -731,7 +675,7 @@ void free_instruments() int Renderer::set_default_instrument(const char *name) { Instrument *ip; - if ((ip = load_instrument(this, name, 0, -1, -1, -1, 0, 0, 0)) == NULL) + if ((ip = load_instrument(this, name, 0, -1, -1, 0, 0, 0)) == NULL) { return -1; } diff --git a/src/timidity/instrum_dls.cpp b/src/timidity/instrum_dls.cpp index fe5e4fdcd..286fcb1a3 100644 --- a/src/timidity/instrum_dls.cpp +++ b/src/timidity/instrum_dls.cpp @@ -1141,7 +1141,6 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, sample->loop_start = rgn->wsmp_loop->ulStart / 2; sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2); } - sample->volume = 1.0f; if (sample->modes & PATCH_SUSTAIN) { diff --git a/src/timidity/instrum_sf2.cpp b/src/timidity/instrum_sf2.cpp index c4cf0bc81..01576e64c 100644 --- a/src/timidity/instrum_sf2.cpp +++ b/src/timidity/instrum_sf2.cpp @@ -1441,7 +1441,6 @@ void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Rend sp->root_freq = note_to_freq(sp->scale_note); sp->sample_rate = sfsamp->SampleRate; sp->key_group = gen->exclusiveClass; - sp->volume = 1; // Set key scaling if (gen->keynum >= 0 && gen->keynum <= 127) diff --git a/src/timidity/mix.cpp b/src/timidity/mix.cpp index b4fc0f818..f97710326 100644 --- a/src/timidity/mix.cpp +++ b/src/timidity/mix.cpp @@ -29,8 +29,6 @@ #include "templates.h" #include "c_cvars.h" -EXTERN_CVAR(Bool, midi_timiditylike) - namespace Timidity { @@ -78,16 +76,7 @@ void GF1Envelope::Init(Renderer *song, Voice *v) void GF1Envelope::Release(Voice *v) { - if (midi_timiditylike) - { - if (!(v->sample->modes & PATCH_T_NO_ENVELOPE)) - { - stage = GF1_RELEASE; - Recompute(v); - } - // else ... loop was already turned off by the caller - } - else if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL)) + if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL)) { /* ramp out to minimum volume with rate from final release stage */ stage = GF1_RELEASEC+1; @@ -119,23 +108,11 @@ bool GF1Envelope::Recompute(Voice *v) bUpdating = false; v->status &= ~(VOICE_SUSTAINING | VOICE_LPE); v->status |= VOICE_RELEASING; - if (midi_timiditylike) - { /* kill the voice ... or not */ - if (volume <= 0) - { - v->status |= VOICE_STOPPING; - } - return 1; - } - else - { /* play sampled release */ - } + /* play sampled release */ return 0; } - if (newstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) && - ((!midi_timiditylike && (v->sample->modes & PATCH_SUSTAIN)) || - (midi_timiditylike && !(v->sample->modes & PATCH_T_NO_ENVELOPE)))) + if (newstage == GF1_RELEASE && !(v->status & VOICE_RELEASING) && (v->sample->modes & PATCH_SUSTAIN)) { v->status |= VOICE_SUSTAINING; /* Freeze envelope until note turns off. Trumpets want this. */ @@ -161,10 +138,6 @@ bool GF1Envelope::Recompute(Voice *v) bool GF1Envelope::Update(Voice *v) { - if (midi_timiditylike && (v->sample->modes & PATCH_T_NO_ENVELOPE)) - { - return 0; - } volume += increment; if (((increment < 0) && (volume <= target)) || ((increment > 0) && (volume >= target))) { @@ -182,36 +155,14 @@ void GF1Envelope::ApplyToAmp(Voice *v) double env_vol = v->attenuation; double final_amp; - if (midi_timiditylike) - { - final_amp = v->sample->volume * FINAL_MIX_TIMIDITY_SCALE; - if (v->tremolo_phase_increment != 0) - { - env_vol *= v->tremolo_volume; - } - if (!(v->sample->modes & PATCH_T_NO_ENVELOPE)) - { - if (stage > GF1_ATTACK) - { - env_vol *= pow(2.0, volume * (6.0 / (1 << 30)) - 6.0); - } - else - { - env_vol *= volume / float(1 << 30); - } - } - } - else - { - final_amp = FINAL_MIX_SCALE; - if (v->tremolo_phase_increment != 0) - { // [RH] FIXME: This is wrong. Tremolo should offset the - // envelope volume, not scale it. - env_vol *= v->tremolo_volume; - } - env_vol *= volume / float(1 << 30); - env_vol = calc_gf1_amp(env_vol); + final_amp = FINAL_MIX_SCALE; + if (v->tremolo_phase_increment != 0) + { // [RH] FIXME: This is wrong. Tremolo should offset the + // envelope volume, not scale it. + env_vol *= v->tremolo_volume; } + env_vol *= volume / float(1 << 30); + env_vol = calc_gf1_amp(env_vol); env_vol *= final_amp; v->left_mix = float(env_vol * v->left_offset); v->right_mix = float(env_vol * v->right_offset); diff --git a/src/timidity/playmidi.cpp b/src/timidity/playmidi.cpp index 5db4f61bc..7d8294384 100644 --- a/src/timidity/playmidi.cpp +++ b/src/timidity/playmidi.cpp @@ -29,8 +29,6 @@ #include "timidity.h" #include "c_cvars.h" -EXTERN_CVAR(Bool, midi_timiditylike) - namespace Timidity { @@ -118,7 +116,7 @@ void Renderer::recompute_freq(int v) voice[v].sample_increment = (int)(a); } -static BYTE vol_table[] = { +static const BYTE vol_table[] = { 000 /* 000 */, 129 /* 001 */, 145 /* 002 */, 155 /* 003 */, 161 /* 004 */, 166 /* 005 */, 171 /* 006 */, 174 /* 007 */, 177 /* 008 */, 180 /* 009 */, 182 /* 010 */, 185 /* 011 */, @@ -161,16 +159,7 @@ void Renderer::recompute_amp(Voice *v) if (v->sample->type == INST_GUS) { - if (midi_timiditylike) - { - v->attenuation = float(timidityxx_perceived_vol(v->velocity / 127.0) * - timidityxx_perceived_vol(chanvol / 127.0) * - timidityxx_perceived_vol(chanexpr / 127.0)); - } - else - { - v->attenuation = (vol_table[(chanvol * chanexpr) / 127] * vol_table[v->velocity]) * ((127 + 64) / 12419775.f); - } + v->attenuation = (vol_table[(chanvol * chanexpr) / 127] * vol_table[v->velocity]) * ((127 + 64) / 12419775.f); } else { @@ -199,7 +188,7 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ } else { - if (type == INST_GUS && !midi_timiditylike) + if (type == INST_GUS) { /* Original amp equation looks like this: * calc_gf1_amp(atten + offset) @@ -218,9 +207,7 @@ void Renderer::compute_pan(double pan, int type, float &left_offset, float &righ } else { - /* I have no idea what equation, if any, will reproduce the sc_pan_table - * that TiMidity++ uses, so midi_timiditylike gets the same Equal Power - * Panning as SF2/DLS. + /* Equal Power Panning for SF2/DLS. */ left_offset = (float)sqrt(1 - pan); right_offset = (float)sqrt(pan); @@ -561,7 +548,7 @@ void Renderer::finish_note(int i) v->status &= ~VOICE_SUSTAINING; v->status |= VOICE_RELEASING; - if (!(v->sample->modes & PATCH_NO_SRELEASE) || midi_timiditylike) + if (!(v->sample->modes & PATCH_NO_SRELEASE)) { v->status &= ~VOICE_LPE; /* sampled release */ } diff --git a/src/timidity/resample.cpp b/src/timidity/resample.cpp index 0ee6aa856..6b9bdb9f5 100644 --- a/src/timidity/resample.cpp +++ b/src/timidity/resample.cpp @@ -28,8 +28,6 @@ #include "timidity.h" #include "c_cvars.h" -EXTERN_CVAR(Bool, midi_timiditylike) - namespace Timidity { @@ -522,7 +520,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr) if (vp->vibrato_control_ratio) { - if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP)) + if (vp->status & VOICE_LPE) { if (modes & PATCH_BIDIR) return rs_vib_bidir(song->resample_buffer, song->rate, vp, *countptr); @@ -536,7 +534,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr) } else { - if (vp->status & VOICE_LPE && !(midi_timiditylike && vp->sample->modes & PATCH_T_NO_LOOP)) + if (vp->status & VOICE_LPE) { if (modes & PATCH_BIDIR) return rs_bidir(song->resample_buffer, vp, *countptr); diff --git a/src/timidity/timidity.cpp b/src/timidity/timidity.cpp index 1d74c5afc..09b5ae7b5 100644 --- a/src/timidity/timidity.cpp +++ b/src/timidity/timidity.cpp @@ -34,7 +34,6 @@ CVAR(String, midi_config, CONFIG_FILE, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, midi_voices, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR(Bool, midi_timiditylike, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(String, gus_patchdir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, midi_dmxgus, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -377,7 +376,7 @@ static int read_config_file(const char *name, bool ismain) delete fp; return -2; } - bank->tone[i].note = bank->tone[i].amp = bank->tone[i].pan = + bank->tone[i].note = bank->tone[i].pan = bank->tone[i].fontbank = bank->tone[i].fontpreset = bank->tone[i].fontnote = bank->tone[i].strip_loop = bank->tone[i].strip_envelope = bank->tone[i].strip_tail = -1; @@ -415,14 +414,7 @@ static int read_config_file(const char *name, bool ismain) *cp++ = 0; if (!strcmp(w[j], "amp")) { - k = atoi(cp); - if ((k < 0 || k > MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9')) - { - Printf("%s: line %d: amplification must be between 0 and %d\n", name, line, MAX_AMPLIFICATION); - delete fp; - return -2; - } - bank->tone[i].amp = k; + /* Ignored */ } else if (!strcmp(w[j], "note")) { @@ -676,7 +668,7 @@ int LoadDMXGUS() continue; int val = k % 128; - bank->tone[val].note = bank->tone[val].amp = bank->tone[val].pan = + bank->tone[val].note = bank->tone[val].pan = bank->tone[val].fontbank = bank->tone[val].fontpreset = bank->tone[val].fontnote = bank->tone[val].strip_loop = bank->tone[val].strip_envelope = bank->tone[val].strip_tail = -1; diff --git a/src/timidity/timidity.h b/src/timidity/timidity.h index 0a21a41b9..59ba5f8ad 100644 --- a/src/timidity/timidity.h +++ b/src/timidity/timidity.h @@ -55,10 +55,6 @@ config.h volume level of FMOD's built-in MIDI player. */ #define FINAL_MIX_SCALE 0.5 -/* This value is used instead when midi_timiditylike is turned on, - because TiMidity++ is louder than a GUS. */ -#define FINAL_MIX_TIMIDITY_SCALE 0.3 - /* How many bits to use for the fractional part of sample positions. This affects tonal accuracy. The entire position counter must fit in 32 bits, so with FRACTION_BITS equal to 12, the maximum size of @@ -211,9 +207,6 @@ enum PATCH_SUSTAIN = (1<<5), PATCH_NO_SRELEASE = (1<<6), PATCH_FAST_REL = (1<<7), - - PATCH_T_NO_ENVELOPE = (1<<8), - PATCH_T_NO_LOOP = (1<<9) }; struct Sample @@ -239,8 +232,6 @@ struct Sample short release_vol; } sf2; } envelope; - float - volume; sample_t *data; SDWORD tremolo_sweep_increment, tremolo_phase_increment, @@ -316,11 +307,12 @@ struct Instrument struct ToneBankElement { ToneBankElement() : - note(0), amp(0), pan(0), strip_loop(0), strip_envelope(0), strip_tail(0) + note(0), pan(0), strip_loop(0), strip_envelope(0), strip_tail(0) {} FString name; - int note, amp, pan, fontbank, fontpreset, fontnote, strip_loop, strip_envelope, strip_tail; + int note, pan, fontbank, fontpreset, fontnote; + SBYTE strip_loop, strip_envelope, strip_tail; }; /* A hack to delay instrument loading until after reading the entire MIDI file. */ @@ -608,8 +600,6 @@ const double log_of_2 = 0.69314718055994529; #define calc_gf1_amp(x) (pow(2.0,((x)*16.0 - 16.0))) // Actual GUS equation #define cb_to_amp(x) (pow(10.0, (x) * (1 / -200.0))) // centibels to amp -#define db_to_amp(x) (pow(10.0, (x) * (1 / -20.0))) // decibels to map -#define timidityxx_perceived_vol(x) (pow((x), 1.66096404744)) /* timidity.h diff --git a/zdoom.vcproj b/zdoom.vcproj index a5d7bfb8e..2e425f5b4 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -942,6 +942,10 @@ RelativePath=".\src\parsecontext.cpp" > + + @@ -1479,6 +1483,10 @@ RelativePath=".\src\parsecontext.h" > + + From 900937929e6e045ea568982741491812d092a1b4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 16:24:16 -0600 Subject: [PATCH 07/15] Use critical sections for WildMidi locking ...because when you're trying to be thread-safe, it's generally a good idea to use mechanisms that work across multiple processor cores. --- src/CMakeLists.txt | 1 - src/wildmidi/lock.cpp | 86 ------------------------------- src/wildmidi/lock.h | 36 ------------- src/wildmidi/wildmidi_lib.cpp | 96 ++++++++++++++++++++--------------- zdoom.vcproj | 8 --- 5 files changed, 54 insertions(+), 173 deletions(-) delete mode 100644 src/wildmidi/lock.cpp delete mode 100644 src/wildmidi/lock.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1975a8d8..8503fabcf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1138,7 +1138,6 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE timidity/timidity.cpp wildmidi/file_io.cpp wildmidi/gus_pat.cpp - wildmidi/lock.cpp wildmidi/reverb.cpp wildmidi/wildmidi_lib.cpp wildmidi/wm_error.cpp diff --git a/src/wildmidi/lock.cpp b/src/wildmidi/lock.cpp deleted file mode 100644 index c5d3fc7da..000000000 --- a/src/wildmidi/lock.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - lock.c - data locking code for lib - - Copyright (C) Chris Ison 2001-2011 - Copyright (C) Bret Curtis 2013-2014 - - This file is part of WildMIDI. - - WildMIDI is free software: you can redistribute and/or modify the player - under the terms of the GNU General Public License and you can redistribute - and/or modify the library under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, either version 3 of - the licenses, or(at your option) any later version. - - WildMIDI 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 and - the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU General Public License and the - GNU Lesser General Public License along with WildMIDI. If not, see - . - */ - -//#include "config.h" - -#ifndef __DJGPP__ - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "lock.h" -#include "common.h" - -/* - _WM_Lock(wmlock) - - wmlock = a pointer to a value - - returns nothing - - Attempts to set a lock on the MDI tree so that - only 1 library command may access it at any time. - If lock fails the process retries until successful. - */ -void _WM_Lock(int * wmlock) { - LOCK_START: - /* Check if lock is clear, if so set it */ - if (*wmlock == 0) { - (*wmlock)++; - /* Now that the lock is set, make sure we - * don't have a race condition. If so, - * decrement the lock by one and retry. */ - if (*wmlock == 1) { - return; /* Lock cleanly set */ - } - (*wmlock)--; - } -#ifdef _WIN32 - Sleep(10); -#else - usleep(500); -#endif - goto LOCK_START; -} - -/* - _WM_Unlock(wmlock) - - wmlock = a pointer to a value - - returns nothing - - Removes a lock previously placed on the MDI tree. - */ -void _WM_Unlock(int *wmlock) { - /* We don't want a -1 lock, so just to make sure */ - if ((*wmlock) != 0) { - (*wmlock)--; - } -} - -#endif /* __DJGPP__ */ diff --git a/src/wildmidi/lock.h b/src/wildmidi/lock.h deleted file mode 100644 index 6504bbecf..000000000 --- a/src/wildmidi/lock.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - lock.h - data locking code for lib - - Copyright (C) Chris Ison 2001-2011 - Copyright (C) Bret Curtis 2013-2014 - - This file is part of WildMIDI. - - WildMIDI is free software: you can redistribute and/or modify the player - under the terms of the GNU General Public License and you can redistribute - and/or modify the library under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation, either version 3 of - the licenses, or(at your option) any later version. - - WildMIDI 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 and - the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU General Public License and the - GNU Lesser General Public License along with WildMIDI. If not, see - . -*/ - -#ifndef __LOCK_H -#define __LOCK_H - -extern void _WM_Lock (int * wmlock); -extern void _WM_Unlock (int *wmlock); - -#ifdef __DJGPP__ -#define _WM_Lock(p) do {} while (0) -#define _WM_Unlock(p) do {} while (0) -#endif - -#endif /* __LOCK_H */ diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index 4372f8436..fe97ad7e8 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -46,10 +46,10 @@ #include "common.h" #include "wm_error.h" #include "file_io.h" -#include "lock.h" #include "reverb.h" #include "gus_pat.h" #include "wildmidi_lib.h" +#include "critsec.h" #define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') #ifdef _WIN32 @@ -88,7 +88,7 @@ static int fix_release = 0; static int auto_amp = 0; static int auto_amp_with_amp = 0; -static int patch_lock; +static FCriticalSection patch_lock; struct _channel { unsigned char bank; @@ -149,7 +149,24 @@ struct _event_data { }; struct _mdi { - int lock; + _mdi() + { + samples_to_mix = 0; + midi_master_vol = 0; + memset(&info, 0, sizeof(info)); + tmp_info = NULL; + memset(&channel, 0, sizeof(channel)); + note = NULL; + memset(note_table, 0, sizeof(note_table)); + patches = NULL; + patch_count = 0; + amp = 0; + mix_buffer = NULL; + mix_buffer_size = NULL; + reverb = NULL; + } + + FCriticalSection lock; unsigned long int samples_to_mix; unsigned short midi_master_vol; @@ -177,7 +194,7 @@ static double newt_coeffs[58][58]; /* for start/end of samples */ #define MAX_GAUSS_ORDER 34 /* 34 is as high as we can go before errors crop up */ static double *gauss_table = NULL; /* *gauss_table[1<first_sample) { @@ -535,7 +552,7 @@ static void WM_FreePatches(void) { patch[i] = tmp_patch; } } - _WM_Unlock(&patch_lock); + patch_lock.Leave(); } /* wm_strdup -- adds extra space for appending up to 4 chars */ @@ -1273,27 +1290,27 @@ static struct _patch * get_patch_data(unsigned short patchid) { struct _patch *search_patch; - _WM_Lock(&patch_lock); + patch_lock.Enter(); search_patch = patch[patchid & 0x007F]; if (search_patch == NULL) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return NULL; } while (search_patch) { if (search_patch->patchid == patchid) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return search_patch; } search_patch = search_patch->next; } if ((patchid >> 8) != 0) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return (get_patch_data(patchid & 0x00FF)); } - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return NULL; } @@ -1312,16 +1329,16 @@ static void load_patch(struct _mdi *mdi, unsigned short patchid) { return; } - _WM_Lock(&patch_lock); + patch_lock.Enter(); if (!tmp_patch->loaded) { if (load_sample(tmp_patch) == -1) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return; } } if (tmp_patch->first_sample == NULL) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return; } @@ -1330,7 +1347,7 @@ static void load_patch(struct _mdi *mdi, unsigned short patchid) { (sizeof(struct _patch*) * mdi->patch_count)); mdi->patches[mdi->patch_count - 1] = tmp_patch; tmp_patch->inuse_count++; - _WM_Unlock(&patch_lock); + patch_lock.Leave(); } static struct _sample * @@ -1338,17 +1355,17 @@ get_sample_data(struct _patch *sample_patch, unsigned long int freq) { struct _sample *last_sample = NULL; struct _sample *return_sample = NULL; - _WM_Lock(&patch_lock); + patch_lock.Enter(); if (sample_patch == NULL) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return NULL; } if (sample_patch->first_sample == NULL) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return NULL; } if (freq == 0) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return sample_patch->first_sample; } @@ -1357,7 +1374,7 @@ get_sample_data(struct _patch *sample_patch, unsigned long int freq) { while (last_sample) { if (freq > last_sample->freq_low) { if (freq < last_sample->freq_high) { - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return last_sample; } else { return_sample = last_sample; @@ -1365,7 +1382,7 @@ get_sample_data(struct _patch *sample_patch, unsigned long int freq) { } last_sample = last_sample->next; } - _WM_Unlock(&patch_lock); + patch_lock.Leave(); return return_sample; } @@ -2021,8 +2038,7 @@ static struct _mdi * Init_MDI(void) { struct _mdi *mdi; - mdi = (struct _mdi*)malloc(sizeof(struct _mdi)); - memset(mdi, 0, (sizeof(struct _mdi))); + mdi = new _mdi; mdi->info.copyright = NULL; mdi->info.mixer_options = WM_MixerOptions; @@ -2044,7 +2060,7 @@ static void freeMDI(struct _mdi *mdi) { unsigned long int i; if (mdi->patch_count != 0) { - _WM_Lock(&patch_lock); + patch_lock.Enter(); for (i = 0; i < mdi->patch_count; i++) { mdi->patches[i]->inuse_count--; if (mdi->patches[i]->inuse_count == 0) { @@ -2058,7 +2074,7 @@ static void freeMDI(struct _mdi *mdi) { mdi->patches[i]->loaded = 0; } } - _WM_Unlock(&patch_lock); + patch_lock.Leave(); free(mdi->patches); } @@ -2554,7 +2570,6 @@ int *WM_Mix(midi *handle, int *buffer, unsigned long count) } } - /* * ========================= * External Functions @@ -2602,9 +2617,6 @@ WM_SYMBOL int WildMidi_Init(const char * config_file, unsigned short int rate, return -1; } _WM_SampleRate = rate; - - gauss_lock = 0; - patch_lock = 0; WM_Initialized = 1; return 0; @@ -2663,7 +2675,7 @@ WM_SYMBOL int WildMidi_Close(midi * handle) { 0); return -1; } - _WM_Lock(&mdi->lock); + mdi->lock.Enter(); if (first_handle->handle == handle) { tmp_handle = first_handle->next; free(first_handle); @@ -2725,17 +2737,17 @@ WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options, } mdi = (struct _mdi *) handle; - _WM_Lock(&mdi->lock); + mdi->lock.Enter(); if ((!(options & 0x0007)) || (options & 0xFFF8)) { _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid option)", 0); - _WM_Unlock(&mdi->lock); + mdi->lock.Leave(); return -1; } if (setting & 0xFFF8) { _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_INVALID_ARG, "(invalid setting)", 0); - _WM_Unlock(&mdi->lock); + mdi->lock.Leave(); return -1; } @@ -2763,7 +2775,7 @@ WM_SYMBOL int WildMidi_SetOption(midi * handle, unsigned short int options, _WM_reset_reverb(mdi->reverb); } - _WM_Unlock(&mdi->lock); + mdi->lock.Leave(); return 0; } @@ -2779,12 +2791,12 @@ WildMidi_GetInfo(midi * handle) { 0); return NULL; } - _WM_Lock(&mdi->lock); + mdi->lock.Enter(); if (mdi->tmp_info == NULL) { mdi->tmp_info = (struct _WM_Info*)malloc(sizeof(struct _WM_Info)); if (mdi->tmp_info == NULL) { _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to set info", 0); - _WM_Unlock(&mdi->lock); + mdi->lock.Leave(); return NULL; } mdi->tmp_info->copyright = NULL; @@ -2799,7 +2811,7 @@ WildMidi_GetInfo(midi * handle) { } else { mdi->tmp_info->copyright = NULL; } - _WM_Unlock(&mdi->lock); + mdi->lock.Leave(); return mdi->tmp_info; } diff --git a/zdoom.vcproj b/zdoom.vcproj index 2e425f5b4..a2587840f 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2819,10 +2819,6 @@ RelativePath=".\src\wildmidi\gus_pat.h" > - - @@ -2847,10 +2843,6 @@ RelativePath=".\src\wildmidi\gus_pat.cpp" > - - From 545e2f7c69a3648680811e27228a845ecac5398f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 16:30:01 -0600 Subject: [PATCH 08/15] Slap WildMidi onto snd_listmididevices's output for Windows --- src/sound/music_midi_base.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/music_midi_base.cpp b/src/sound/music_midi_base.cpp index 048e52e3f..260f635b2 100644 --- a/src/sound/music_midi_base.cpp +++ b/src/sound/music_midi_base.cpp @@ -168,6 +168,7 @@ CCMD (snd_listmididevices) MIDIOUTCAPS caps; MMRESULT res; + PrintMidiDevice (-6, "WildMidi", MOD_SWSYNTH, 0); #ifdef HAVE_FLUIDSYNTH PrintMidiDevice (-5, "FluidSynth", MOD_SWSYNTH, 0); #endif From 6d2e93254fcea18ea37c6eb21f9ba116084172d1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 17:14:13 -0600 Subject: [PATCH 09/15] Fix CreateSMF's SysEx writing - It was wrong before. It might still be wrong, but at least it doesn't look obviously wrong anymore. --- src/sound/music_midistream.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 37616b9a6..064606d0f 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -1196,9 +1196,15 @@ void MIDIStreamer::CreateSMF(TArray &file, int looplimit) len--; file.Push(MIDI_SYSEX); WriteVarLen(file, len); - memcpy(&file[file.Reserve(len - 1)], bytes, len); - running_status = 255; + memcpy(&file[file.Reserve(len)], bytes + 1, len); } + else + { + file.Push(MIDI_SYSEXEND); + WriteVarLen(file, len); + memcpy(&file[file.Reserve(len)], bytes, len); + } + running_status = 255; } else if (MEVT_EVENTTYPE(event[2]) == 0) { From 92e0bbeee9e2440999990f6e21fa0a1312d21d0f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 17:49:43 -0600 Subject: [PATCH 10/15] Handle WildMidi's supported SysEx messages --- src/wildmidi/wildmidi_lib.cpp | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index fe97ad7e8..68ab89933 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -2918,6 +2918,45 @@ void WildMidi_Renderer::ShortEvent(int status, int parm1, int parm2) void WildMidi_Renderer::LongEvent(const char *data, int len) { + // Check for Roland SysEx + if (len >= 11 && // Must be at least 11 bytes + data[len-1] == 0xF7 && // SysEx end + data[0] == 0xF0 && // SysEx + data[1] == 0x41 && // Roland + data[2] == 0x10 && // Device ID, defaults to 0x10 + data[3] == 0x42 && // Model ID, 0x42 indicates a GS synth + data[4] == 0x12 && // The other end is sending data to us + data[5] == 0x40) // We only care about addresses with this first byte + { + // Calculate checksum + int cksum = 0; + for (int i = 5; i < len - 2; ++i) + { + cksum += data[i]; + } + cksum = 128 - (cksum & 0x7F); + if (data[len-2] == cksum) + { // Check destination address + if (((data[6] & 0xF0) == 0x10) && data[7] == 0x15) + { // Roland drum track setting + int sysex_ch = data[6] & 0x0F; + if (sysex_ch == 0) + { + sysex_ch = 9; + } + else if (sysex_ch <= 9) + { + sysex_ch -= 1; + } + _event_data ev = { sysex_ch, data[8] }; + do_sysex_roland_drum_track((_mdi *)handle, &ev); + } + else if (data[6] == 0x00 && data[7] == 0x7F && data[8] == 0x00) + { // Roland GS reset + do_sysex_roland_reset((_mdi *)handle, NULL); + } + } + } } void WildMidi_Renderer::ComputeOutput(float *fbuffer, int len) From 3ec6ad5018941bde5dd0802afc28f70ffc8674ee Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Dec 2015 22:39:38 -0600 Subject: [PATCH 11/15] Add SysEx retrieval to the MIDI file reader --- src/sound/i_musicinterns.h | 2 +- src/sound/music_smf_midiout.cpp | 53 ++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 03282ef37..dd5fd1606 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -566,7 +566,7 @@ protected: struct TrackInfo; void ProcessInitialMetaEvents (); - DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay); + DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); TrackInfo *FindNextDue (); BYTE *MusHeader; diff --git a/src/sound/music_smf_midiout.cpp b/src/sound/music_smf_midiout.cpp index d5d307ec7..49fd12502 100644 --- a/src/sound/music_smf_midiout.cpp +++ b/src/sound/music_smf_midiout.cpp @@ -322,7 +322,12 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) // Play all events for this tick. do { - DWORD *new_events = SendCommand(events, TrackDue, time); + bool sysex_noroom = false; + DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); + if (sysex_noroom) + { + return events; + } TrackDue = FindNextDue(); if (new_events != events) { @@ -366,12 +371,15 @@ void MIDISong2::AdvanceTracks(DWORD time) // //========================================================================== -DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay) +DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom) { DWORD len; BYTE event, data1 = 0, data2 = 0; int i; + sysex_noroom = false; + size_t start_p = track->TrackP; + CHECK_FINISHED event = track->TrackBegin[track->TrackP++]; CHECK_FINISHED @@ -588,13 +596,44 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay) } else { - // Skip SysEx events just because I don't want to bother with them. - // The old MIDI player ignored them too, so this won't break - // anything that played before. + // SysEx events could potentially not have enough room in the buffer... if (event == MIDI_SYSEX || event == MIDI_SYSEXEND) { - len = track->ReadVarLen (); - track->TrackP += len; + len = track->ReadVarLen(); + if (len >= (MAX_EVENTS-1)*3*4) + { // This message will never fit. Throw it away. + track->TrackP += len; + } + else if (len + 12 >= (size_t)room * 4) + { // Not enough room left in this buffer. Backup and wait for the next one. + track->TrackP = start_p; + sysex_noroom = true; + return events; + } + else + { + events[0] = delay; + events[1] = 0; + BYTE *msg = (BYTE *)&events[3]; + if (event == MIDI_SYSEX) + { // Need to add the SysEx marker to the message. + events[2] = (MEVT_LONGMSG << 24) | (len + 1); + *msg++ = MIDI_SYSEX; + } + else + { + events[2] = (MEVT_LONGMSG << 24) | len; + } + memcpy(msg, &track->TrackBegin[track->TrackP], len); + msg += len; + // Must pad with 0 + while ((size_t)msg & 3) + { + *msg++ = 0; + } + events = (DWORD *)msg; + track->TrackP += len; + } } else if (event == MIDI_META) { From 6c13ba40ac57136d63ba617f6e5f48a191a36696 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 30 Dec 2015 01:09:11 -0600 Subject: [PATCH 12/15] Fix for __unix__ compilation -- section not changed with the rest of fe2dcfd588596d53 --- src/timidity/instrum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/timidity/instrum.cpp b/src/timidity/instrum.cpp index fdfa4fd64..fa9360267 100644 --- a/src/timidity/instrum.cpp +++ b/src/timidity/instrum.cpp @@ -168,7 +168,7 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss { #ifdef __unix__ // Windows isn't case-sensitive. tmp.ToUpper(); - if ((fp = open_filereader(tmp, openmode, NULL)) == NULL) + if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL) #endif { noluck = true; From 1def61e3e37e9bd0baf23102e9cc19f915e72859 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 30 Dec 2015 10:14:18 +0100 Subject: [PATCH 13/15] - allow changing the reverb and resampling mode setting for WildMidi. - fixed: WildMidi did not initialize the reverb data structures. - removed the menu option for midi_timiditylike. --- src/sound/i_music.cpp | 4 ++++ src/sound/i_music.h | 1 + src/sound/i_musicinterns.h | 3 +++ src/sound/music_midistream.cpp | 25 ++++++++++++++++++++++ src/sound/music_wildmidi_mididevice.cpp | 28 ++++++++++++++++++++++++- src/wildmidi/wildmidi_lib.cpp | 15 +++++++++++++ src/wildmidi/wildmidi_lib.h | 1 + wadsrc/static/menudef.txt | 2 +- 8 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 121c0b9fb..a46401f3e 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -286,6 +286,10 @@ void MusInfo::FluidSettingStr(const char *, const char *) { } +void MusInfo::WildMidiSetOption(int opt, int set) +{ +} + FString MusInfo::GetStats() { return "No stats available for this song"; diff --git a/src/sound/i_music.h b/src/sound/i_music.h index ee05d8caf..03e0a3212 100644 --- a/src/sound/i_music.h +++ b/src/sound/i_music.h @@ -82,6 +82,7 @@ public: virtual void FluidSettingInt(const char *setting, int value); // FluidSynth settings virtual void FluidSettingNum(const char *setting, double value); // " virtual void FluidSettingStr(const char *setting, const char *value); // " + virtual void WildMidiSetOption(int opt, int set); void Start(bool loop, float rel_vol = -1.f, int subsong = 0); diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index dd5fd1606..275253d84 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -102,6 +102,7 @@ public: virtual void FluidSettingInt(const char *setting, int value); virtual void FluidSettingNum(const char *setting, double value); virtual void FluidSettingStr(const char *setting, const char *value); + virtual void WildMidiSetOption(int opt, int set); virtual bool Preprocess(MIDIStreamer *song, bool looping); virtual FString GetStats(); }; @@ -349,6 +350,7 @@ protected: void HandleEvent(int status, int parm1, int parm2); void HandleLongEvent(const BYTE *data, int len); void ComputeOutput(float *buffer, int len); + void WildMidiSetOption(int opt, int set); }; // FluidSynth implementation of a MIDI device ------------------------------- @@ -447,6 +449,7 @@ public: void FluidSettingInt(const char *setting, int value); void FluidSettingNum(const char *setting, double value); void FluidSettingStr(const char *setting, const char *value); + void WildMidiSetOption(int opt, int set); void CreateSMF(TArray &file, int looplimit=0); protected: diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 064606d0f..a6fb5f4d8 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -626,6 +626,21 @@ void MIDIStreamer::FluidSettingStr(const char *setting, const char *value) } +//========================================================================== +// +// MIDIDeviceStreamer :: WildMidiSetOption +// +//========================================================================== + +void MIDIStreamer::WildMidiSetOption(int opt, int set) +{ + if (MIDI != NULL) + { + MIDI->WildMidiSetOption(opt, set); + } +} + + //========================================================================== // // MIDIStreamer :: OutputVolume @@ -1522,6 +1537,16 @@ void MIDIDevice::FluidSettingStr(const char *setting, const char *value) { } +//========================================================================== +// +// MIDIDevice :: WildMidiSetOption +// +//========================================================================== + +void MIDIDevice::WildMidiSetOption(int opt, int set) +{ +} + //========================================================================== // // MIDIDevice :: GetStats diff --git a/src/sound/music_wildmidi_mididevice.cpp b/src/sound/music_wildmidi_mididevice.cpp index 44c060f26..80bf46e2b 100644 --- a/src/sound/music_wildmidi_mididevice.cpp +++ b/src/sound/music_wildmidi_mididevice.cpp @@ -61,6 +61,17 @@ static FString CurrentConfig; CVAR(String, wildmidi_config, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, wildmidi_frequency, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Bool, wildmidi_reverb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + if (currSong != NULL) + currSong->WildMidiSetOption(WM_MO_REVERB, *self? WM_MO_REVERB:0); +} + +CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + if (currSong != NULL) + currSong->WildMidiSetOption(WM_MO_ENHANCED_RESAMPLING, *self? WM_MO_ENHANCED_RESAMPLING:0); +} // CODE -------------------------------------------------------------------- @@ -90,7 +101,7 @@ WildMIDIDevice::WildMIDIDevice() WildMidi_Shutdown(); CurrentConfig = ""; } - if (!WildMidi_Init(wildmidi_config, SampleRate, WM_MO_ENHANCED_RESAMPLING)) + if (!WildMidi_Init(wildmidi_config, SampleRate, 0)) { CurrentConfig = wildmidi_config; } @@ -98,6 +109,10 @@ WildMIDIDevice::WildMIDIDevice() if (CurrentConfig.IsNotEmpty()) { Renderer = new WildMidi_Renderer(); + int flags = 0; + if (wildmidi_enhanced_resampling) flags |= WM_MO_ENHANCED_RESAMPLING; + if (wildmidi_reverb) flags |= WM_MO_REVERB; + Renderer->SetOption(WM_MO_ENHANCED_RESAMPLING | WM_MO_REVERB, flags); } } @@ -204,3 +219,14 @@ FString WildMIDIDevice::GetStats() out.Format("%3d voices", Renderer->GetVoiceCount()); return out; } + +//========================================================================== +// +// WildMIDIDevice :: GetStats +// +//========================================================================== + +void WildMIDIDevice::WildMidiSetOption(int opt, int set) +{ + Renderer->SetOption(opt, set); +} diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index 68ab89933..40e462b62 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -2718,6 +2718,16 @@ midi *WildMidi_NewMidi() { ret = NULL; } } + + if ((((_mdi*)ret)->reverb = _WM_init_reverb(_WM_SampleRate, reverb_room_width, + reverb_room_length, reverb_listen_posx, reverb_listen_posy)) + == NULL) { + _WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0); + WildMidi_Close(ret); + ret = NULL; + } + + return ret; } @@ -2988,3 +2998,8 @@ int WildMidi_Renderer::GetVoiceCount() } return count; } + +void WildMidi_Renderer::SetOption(int opt, int set) +{ + WildMidi_SetOption((_mdi*)handle, (unsigned short)opt, (unsigned short)set); +} diff --git a/src/wildmidi/wildmidi_lib.h b/src/wildmidi/wildmidi_lib.h index ec8dea3c1..8f021d426 100644 --- a/src/wildmidi/wildmidi_lib.h +++ b/src/wildmidi/wildmidi_lib.h @@ -78,6 +78,7 @@ public: void ComputeOutput(float *buffer, int len); void LoadInstrument(int bank, int percussion, int instr); int GetVoiceCount(); + void SetOption(int opt, int set); private: void *handle; }; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 94de2b96c..244b14691 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1592,7 +1592,6 @@ OptionMenu AdvSoundOptions StaticText "GUS Emulation", 1 TextField "GUS config file", "midi_config" Slider "MIDI voices", "midi_voices", 16, 256, 4, 0 - Option "Emulate TiMidity", "midi_timiditylike", "OnOff" Option "Read DMXGUS lumps", "midi_dmxgus", "OnOff" Option "GUS memory size", "gus_memsize", "GusMemory" StaticText " " @@ -1611,6 +1610,7 @@ OptionMenu AdvSoundOptions StaticText " " StaticText "WildMidi", 1 TextField "WildMidi config file", "wildmidi_config" + Option "Reverb", "wildmidi_reverb", "OnOff" } /*======================================= From aff42a6186073abf7ebf6abbe73c5ecc18cced07 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 30 Dec 2015 10:21:17 +0100 Subject: [PATCH 14/15] - don't look up a lump name in PathExpander if we are only looking for real files. --- src/pathexpander.cpp | 2 +- src/sound/music_wildmidi_mididevice.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pathexpander.cpp b/src/pathexpander.cpp index d8b912b65..bb89a0555 100644 --- a/src/pathexpander.cpp +++ b/src/pathexpander.cpp @@ -74,10 +74,10 @@ FileReader *PathExpander::openFileReader(const char *name, int *plumpnum) current_filename = name; FixPathSeperator(current_filename); - int lumpnum = Wads.CheckNumForFullName(current_filename); if (openmode != OM_FILE) { + int lumpnum = Wads.CheckNumForFullName(current_filename); if (lumpnum >= 0) { fp = Wads.ReopenLumpNum(lumpnum); diff --git a/src/sound/music_wildmidi_mididevice.cpp b/src/sound/music_wildmidi_mididevice.cpp index 80bf46e2b..332a97abe 100644 --- a/src/sound/music_wildmidi_mididevice.cpp +++ b/src/sound/music_wildmidi_mididevice.cpp @@ -226,7 +226,7 @@ FString WildMIDIDevice::GetStats() // //========================================================================== -void WildMIDIDevice::WildMidiSetOption(int opt, int set) -{ - Renderer->SetOption(opt, set); -} +void WildMIDIDevice::WildMidiSetOption(int opt, int set) +{ + Renderer->SetOption(opt, set); +} From a2b377c58039bdf896dea0f79da1d6844b2e135b Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Wed, 30 Dec 2015 10:58:52 +0100 Subject: [PATCH 15/15] - Fixed Clang errors/warnings on wildMIDI code. --- src/sound/music_wildmidi_mididevice.cpp | 2 +- src/wildmidi/wildmidi_lib.cpp | 8 ++++---- src/wildmidi/wildmidi_lib.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sound/music_wildmidi_mididevice.cpp b/src/sound/music_wildmidi_mididevice.cpp index 332a97abe..c3fd674c9 100644 --- a/src/sound/music_wildmidi_mididevice.cpp +++ b/src/sound/music_wildmidi_mididevice.cpp @@ -193,7 +193,7 @@ void WildMIDIDevice::HandleEvent(int status, int parm1, int parm2) void WildMIDIDevice::HandleLongEvent(const BYTE *data, int len) { - Renderer->LongEvent((const char *)data, len); + Renderer->LongEvent(data, len); } //========================================================================== diff --git a/src/wildmidi/wildmidi_lib.cpp b/src/wildmidi/wildmidi_lib.cpp index 40e462b62..94a446e17 100644 --- a/src/wildmidi/wildmidi_lib.cpp +++ b/src/wildmidi/wildmidi_lib.cpp @@ -162,7 +162,7 @@ struct _mdi { patch_count = 0; amp = 0; mix_buffer = NULL; - mix_buffer_size = NULL; + mix_buffer_size = 0; reverb = NULL; } @@ -2926,7 +2926,7 @@ void WildMidi_Renderer::ShortEvent(int status, int parm1, int parm2) } } -void WildMidi_Renderer::LongEvent(const char *data, int len) +void WildMidi_Renderer::LongEvent(const unsigned char *data, int len) { // Check for Roland SysEx if (len >= 11 && // Must be at least 11 bytes @@ -2949,7 +2949,7 @@ void WildMidi_Renderer::LongEvent(const char *data, int len) { // Check destination address if (((data[6] & 0xF0) == 0x10) && data[7] == 0x15) { // Roland drum track setting - int sysex_ch = data[6] & 0x0F; + unsigned char sysex_ch = data[6] & 0x0F; if (sysex_ch == 0) { sysex_ch = 9; @@ -2958,7 +2958,7 @@ void WildMidi_Renderer::LongEvent(const char *data, int len) { sysex_ch -= 1; } - _event_data ev = { sysex_ch, data[8] }; + _event_data ev = { sysex_ch, static_cast(data[8]) }; do_sysex_roland_drum_track((_mdi *)handle, &ev); } else if (data[6] == 0x00 && data[7] == 0x7F && data[8] == 0x00) diff --git a/src/wildmidi/wildmidi_lib.h b/src/wildmidi/wildmidi_lib.h index 8f021d426..b5aa79849 100644 --- a/src/wildmidi/wildmidi_lib.h +++ b/src/wildmidi/wildmidi_lib.h @@ -74,7 +74,7 @@ public: ~WildMidi_Renderer(); void ShortEvent(int status, int parm1, int parm2); - void LongEvent(const char *data, int len); + void LongEvent(const unsigned char *data, int len); void ComputeOutput(float *buffer, int len); void LoadInstrument(int bank, int percussion, int instr); int GetVoiceCount();