Skip to content

Commit

Permalink
Went back to using timidity for midi support:
Browse files Browse the repository at this point in the history
Included timidity stuff from final-lgpl-revision tag, along with
updates from SDL2_mixer, excluding the raised DEFAULT_VOICES and
MAX_VOICES limits.

TODO: Use more SDL_stdinc functions in timidity library.
  • Loading branch information
sezero committed Mar 17, 2021
1 parent fd60784 commit 23e0bd9
Show file tree
Hide file tree
Showing 36 changed files with 5,383 additions and 7,366 deletions.
21 changes: 17 additions & 4 deletions CMakeLists.txt
Expand Up @@ -62,6 +62,7 @@ sdlsound_decoder_option(FLAC "Free Lossless Audio Codec" ".FLAC")
sdlsound_decoder_option(VORBIS "Ogg Vorbis" ".OGG")
sdlsound_decoder_option(RAW "raw PCM audio" ".RAW")
sdlsound_decoder_option(SHN "Shorten" ".SHN")
sdlsound_decoder_option(MIDI "Midi" ".MID")
sdlsound_decoder_option(MODPLUG "ModPlug" "various tracker formats")
sdlsound_decoder_option(MP3 "MPEG-1 Layers I-III" ".MP3, .MP2, .MP1")

Expand All @@ -72,11 +73,23 @@ if(APPLE)
endif()
endif()

if(SDLSOUND_DECODER_MIDI)
set(TIMIDITY_SRCS
src/timidity/common.c
src/timidity/instrum.c
src/timidity/mix.c
src/timidity/output.c
src/timidity/playmidi.c
src/timidity/readmidi.c
src/timidity/resample.c
src/timidity/tables.c
src/timidity/timidity.c
)
endif()
if(SDLSOUND_DECODER_MODPLUG)
set(LIBMODPLUG_SRCS
src/libmodplug/fastmix.c
src/libmodplug/load_669.c
src/libmodplug/load_abc.c
src/libmodplug/load_amf.c
src/libmodplug/load_ams.c
src/libmodplug/load_dbm.c
Expand All @@ -86,12 +99,10 @@ if(SDLSOUND_DECODER_MODPLUG)
src/libmodplug/load_it.c
src/libmodplug/load_mdl.c
src/libmodplug/load_med.c
src/libmodplug/load_mid.c
src/libmodplug/load_mod.c
src/libmodplug/load_mt2.c
src/libmodplug/load_mtm.c
src/libmodplug/load_okt.c
src/libmodplug/load_pat.c
src/libmodplug/load_psm.c
src/libmodplug/load_ptm.c
src/libmodplug/load_s3m.c
Expand All @@ -118,13 +129,15 @@ set(SDLSOUND_SRCS
src/SDL_sound_au.c
src/SDL_sound_coreaudio.c
src/SDL_sound_flac.c
src/SDL_sound_midi.c
src/SDL_sound_modplug.c
src/SDL_sound_mp3.c
src/SDL_sound_raw.c
src/SDL_sound_shn.c
src/SDL_sound_voc.c
src/SDL_sound_vorbis.c
src/SDL_sound_wav.c
${TIMIDITY_SRCS}
${LIBMODPLUG_SRCS}
)

Expand Down Expand Up @@ -262,4 +275,4 @@ message_bool_option("Build static library" SDLSOUND_BUILD_STATIC)
message_bool_option("Build shared library" SDLSOUND_BUILD_SHARED)
message_bool_option("Build stdio test program" SDLSOUND_BUILD_TEST)

# end of CMakeLists.txt ...
# end of CMakeLists.txt
27 changes: 19 additions & 8 deletions src/Makefile.os2
Expand Up @@ -15,23 +15,28 @@ VERSION = 2.0.0
LIBFILE = $(LIBNAME).lib
DLLFILE = $(LIBNAME).dll
LNKFILE = $(LIBNAME).lnk

MODPLIB = modplug.lib
TIMILIB = timidity.lib

TITLENAME = $(LIBNAME) $(VERSION)

SRCS = SDL_sound_aiff.c SDL_sound_au.c SDL_sound_raw.c SDL_sound_shn.c &
SDL_sound_voc.c SDL_sound_wav.c SDL_sound_flac.c SDL_sound_modplug.c &
SDL_sound_mp3.c SDL_sound_vorbis.c SDL_sound.c
SRCS = SDL_sound_aiff.c SDL_sound_au.c SDL_sound_raw.c SDL_sound_shn.c &
SDL_sound_voc.c SDL_sound_wav.c SDL_sound_flac.c SDL_sound_mp3.c &
SDL_sound_vorbis.c SDL_sound_midi.c SDL_sound_modplug.c SDL_sound.c

MODPSRCS = modplug.c sndfile.c fastmix.c snd_dsp.c snd_flt.c snd_fx.c sndmix.c &
load_669.c load_amf.c load_ams.c load_dbm.c load_dmf.c load_dsm.c &
load_far.c load_it.c load_mdl.c load_med.c load_mod.c load_mt2.c &
load_mtm.c load_okt.c load_psm.c load_ptm.c load_s3m.c load_stm.c &
load_ult.c load_umx.c load_xm.c &
load_abc.c load_mid.c load_pat.c
load_ult.c load_umx.c load_xm.c

TIMISRCS = common.c instrum.c mix.c output.c playmidi.c readmidi.c resample.c &
tables.c timidity.c

OBJS = $(SRCS:.c=.obj)
MODPOBJS = $(MODPSRCS:.c=.obj)
TIMIOBJS = $(TIMISRCS:.c=.obj)

CFLAGS_BASE = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei -j
CFLAGS_BASE+= -DNDEBUG
Expand All @@ -40,7 +45,7 @@ CFLAGS_BASE+= -wx
# include paths:
CFLAGS_BASE+= -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h"
CFLAGS_BASE+= -I. $(DEPS_INC)
CFLAGS = $(CFLAGS_BASE) -Ilibmodplug
CFLAGS = $(CFLAGS_BASE)
# to build a dll:
CFLAGS+= -bd
# there are _lots_ of lazy declarations:
Expand All @@ -53,6 +58,7 @@ CFLAGS+= -DBUILD_SDL -DSDL_SOUND_DLL_EXPORTS

CFLAGS+= -DSOUND_SUPPORTS_MP3 &
-DSOUND_SUPPORTS_MODPLUG &
-DSOUND_SUPPORTS_MIDI &
-DSOUND_SUPPORTS_WAV &
-DSOUND_SUPPORTS_AIFF &
-DSOUND_SUPPORTS_AU &
Expand All @@ -62,7 +68,7 @@ CFLAGS+= -DSOUND_SUPPORTS_MP3 &
-DSOUND_SUPPORTS_FLAC

LIBSDL = SDL2.lib
LIBS = $(LIBSDL) $(MODPLIB)
LIBS = $(LIBSDL) $(MODPLIB) $(TIMILIB)

.extensions:
.extensions: .lib .dll .obj .c
Expand All @@ -76,7 +82,7 @@ $(LIBFILE): $(DLLFILE)
@echo * Create library: $@...
wlib -b -n -q -c -pa -s -t -zld -ii -io $@ $(DLLFILE)

$(DLLFILE): $(OBJS) $(MODPLIB) $(LNKFILE)
$(DLLFILE): $(OBJS) $(MODPLIB) $(TIMILIB) $(LNKFILE)
@echo * Link: $@
wlink @$(LNKFILE)

Expand Down Expand Up @@ -116,11 +122,16 @@ playsound_simple.exe: $(LIBFILE) playsound_simple.obj
modplug.lib: $(MODPOBJS)
wlib -b -n -q -c -pa -s -t -zld -ii -io $@ $(MODPOBJS)

.c: timidity;
timidity.lib: $(TIMIOBJS)
wlib -b -n -q -c -pa -s -t -zld -ii -io $@ $(TIMIOBJS)

clean: .SYMBOLIC
@echo * Clean: $(TITLENAME)
@if exist *.obj rm *.obj
@if exist *.err rm *.err
@if exist $(MODPLIB) rm $(MODPLIB)
@if exist $(TIMILIB) rm $(TIMILIB)
@if exist $(LNKFILE) rm $(LNKFILE)
distclean: .SYMBOLIC clean
@if exist $(DLLFILE) rm $(DLLFILE)
Expand Down
4 changes: 4 additions & 0 deletions src/SDL_sound.c
Expand Up @@ -19,6 +19,7 @@
/* The various decoder drivers... */

/* All these externs may be missing; we check SOUND_SUPPORTS_xxx before use. */
extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI;
extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MODPLUG;
extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MP3;
extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV;
Expand All @@ -40,6 +41,9 @@ typedef struct

static decoder_element decoders[] =
{
#if SOUND_SUPPORTS_MIDI
{ 0, &__Sound_DecoderFunctions_MIDI },
#endif
#if SOUND_SUPPORTS_MODPLUG
{ 0, &__Sound_DecoderFunctions_MODPLUG },
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/SDL_sound_internal.h
Expand Up @@ -39,6 +39,9 @@
#define SNDDBG(x)
#endif

#ifndef SOUND_SUPPORTS_MIDI
#define SOUND_SUPPORTS_MIDI 1
#endif
#ifndef SOUND_SUPPORTS_MP3
#define SOUND_SUPPORTS_MP3 1
#endif
Expand Down
174 changes: 174 additions & 0 deletions src/SDL_sound_midi.c
@@ -0,0 +1,174 @@
/**
* SDL_sound; An abstract sound format decoding API.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Torbjörn Andersson.
*/

/*
* This driver handles MIDI data through a stripped-down version of TiMidity.
* See the documentation in the timidity subdirectory.
*/

#define __SDL_SOUND_INTERNAL__
#include "SDL_sound_internal.h"

#if SOUND_SUPPORTS_MIDI

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "timidity/timidity.h"


/* Config file should contain any other directory that needs
* to be added to the search path. The library adds the path
* of the config file to its search path, too. */
#if defined(_WIN32) || defined(__OS2__)
# define TIMIDITY_CFG "C:\\TIMIDITY\\TIMIDITY.CFG"
#else /* unix: */
# define TIMIDITY_CFG_ETC "/etc/timidity.cfg"
# define TIMIDITY_CFG_FREEPATS "/etc/timidity/freepats.cfg"
#endif

static int MIDI_init(void)
{
const char *cfg;
int rc = -1;

cfg = SDL_getenv("TIMIDITY_CFG");
if (cfg) {
rc = Timidity_Init(cfg); /* env or user override: no other tries */
}
else {
#if defined(TIMIDITY_CFG)
if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG);
#endif
#if defined(TIMIDITY_CFG_ETC)
if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG_ETC);
#endif
#if defined(TIMIDITY_CFG_FREEPATS)
if (rc < 0) rc = Timidity_Init(TIMIDITY_CFG_FREEPATS);
#endif
if (rc < 0) rc = Timidity_Init(NULL); /* library's default cfg. */
}

BAIL_IF_MACRO(rc < 0, "MIDI: Could not initialise", 0);
return(1);
} /* MIDI_init */


static void MIDI_quit(void)
{
Timidity_Exit();
} /* MIDI_quit */


static int MIDI_open(Sound_Sample *sample, const char *ext)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
SDL_RWops *rw = internal->rw;
SDL_AudioSpec spec;
MidiSong *song;

spec.channels = 2;
spec.format = AUDIO_S16SYS;
spec.freq = 44100;
spec.samples = 4096;

song = Timidity_LoadSong(rw, &spec);
BAIL_IF_MACRO(song == NULL, "MIDI: Not a MIDI file.", 0);
Timidity_SetVolume(song, 100);
Timidity_Start(song);

SNDDBG(("MIDI: Accepting data stream.\n"));

internal->decoder_private = (void *) song;
internal->total_time = Timidity_GetSongLength(song);

sample->actual.channels = 2;
sample->actual.rate = 44100;
sample->actual.format = AUDIO_S16SYS;
sample->flags = SOUND_SAMPLEFLAG_CANSEEK;

return(1); /* we'll handle this data. */
} /* MIDI_open */


static void MIDI_close(Sound_Sample *sample)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;

Timidity_FreeSong(song);
} /* MIDI_close */


static Uint32 MIDI_read(Sound_Sample *sample)
{
Uint32 retval;
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;

retval = Timidity_PlaySome(song, internal->buffer, internal->buffer_size);

/* Make sure the read went smoothly... */
if (retval == 0)
sample->flags |= SOUND_SAMPLEFLAG_EOF;

else if (retval == -1)
sample->flags |= SOUND_SAMPLEFLAG_ERROR;

/* (next call this EAGAIN may turn into an EOF or error.) */
else if (retval < internal->buffer_size)
sample->flags |= SOUND_SAMPLEFLAG_EAGAIN;

return(retval);
} /* MIDI_read */


static int MIDI_rewind(Sound_Sample *sample)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;

Timidity_Start(song);
return(1);
} /* MIDI_rewind */


static int MIDI_seek(Sound_Sample *sample, Uint32 ms)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;

Timidity_Seek(song, ms);
return(1);
} /* MIDI_seek */


static const char *extensions_midi[] = { "MIDI", "MID", NULL };
const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI =
{
{
extensions_midi,
"MIDI decoder, using a subset of TiMidity",
"Torbjörn Andersson <d91tan@Update.UU.SE>",
"http://www.icculus.org/SDL_sound/"
},

MIDI_init, /* init() method */
MIDI_quit, /* quit() method */
MIDI_open, /* open() method */
MIDI_close, /* close() method */
MIDI_read, /* read() method */
MIDI_rewind, /* rewind() method */
MIDI_seek /* seek() method */
};

#endif /* SOUND_SUPPORTS_MIDI */

/* end of SDL_sound_midi.c ... */

3 changes: 0 additions & 3 deletions src/SDL_sound_modplug.c
Expand Up @@ -50,9 +50,6 @@ static const char *extensions_modplug[] =
"ULT",
"UMX",
"XM", /* FastTracker II */
"ABC",
"MID",
"MIDI",
NULL
};

Expand Down
6 changes: 0 additions & 6 deletions src/libmodplug/libmodplug.h
Expand Up @@ -165,16 +165,13 @@ typedef const BYTE * LPCBYTE;
#define MOD_TYPE_DSM 0x2000
#define MOD_TYPE_MDL 0x4000
#define MOD_TYPE_OKT 0x8000
#define MOD_TYPE_MID 0x10000
#define MOD_TYPE_DMF 0x20000
#define MOD_TYPE_PTM 0x40000
#define MOD_TYPE_DBM 0x80000
#define MOD_TYPE_MT2 0x100000
#define MOD_TYPE_AMF0 0x200000
#define MOD_TYPE_PSM 0x400000
#define MOD_TYPE_J2B 0x800000
#define MOD_TYPE_ABC 0x1000000
#define MOD_TYPE_PAT 0x2000000
#define MOD_TYPE_UMX 0x80000000 // Fake type
#define MAX_MODTYPE 24

Expand Down Expand Up @@ -737,9 +734,6 @@ void delete_CSoundFile(CSoundFile *_this);
BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);
BOOL CSoundFile_ReadPSM(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);
BOOL CSoundFile_ReadUMX(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);
BOOL CSoundFile_ReadABC(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);
BOOL CSoundFile_ReadMID(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);
BOOL CSoundFile_ReadPAT(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength);

// MOD Convert function
void CSoundFile_ConvertModCommand(CSoundFile *_this, MODCOMMAND *);
Expand Down

0 comments on commit 23e0bd9

Please sign in to comment.