Instead of writing converted MIDI to file, write to buffer so it can be played directly

This commit is contained in:
zicodxx 2010-10-29 17:40:42 +02:00
parent e57ffac570
commit ae22f8e037
4 changed files with 95 additions and 68 deletions

View file

@ -1,5 +1,9 @@
D2X-Rebirth Changelog
20101029
--------
arch/sdl/digi_mixer_music, include/hmp.h, misc/hmp.c: Instead of writing converted MIDI to file, write to buffer so it can be played directly
20101016
--------
D2X.make, arch/sdl/jukebox.c, d2x-rebirth.xcodeproj/project.pbxproj, include/pstypes.h, main/game.c, main/hud.c, main/menu.c, main/newdemo.c, main/titles.c, misc/args.c, misc/physfsx.c: Fix errors for Mac OS 9, Mac OS X 'd2x' target builds again

View file

@ -23,7 +23,8 @@
Mix_Music *current_music = NULL;
char *current_music_hndlbuf = NULL;
static unsigned char *current_music_hndlbuf = NULL;
/*
* Plays a music file from an absolute path or a relative path
@ -33,9 +34,9 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
{
SDL_RWops *rw = NULL;
PHYSFS_file *filehandle = NULL;
char midi_filename[PATH_MAX], full_path[PATH_MAX];
char *basedir = "music", *fptr;
int bufsize = 0;
char full_path[PATH_MAX];
char *fptr;
unsigned int bufsize = 0;
mix_free_music(); // stop and free what we're already playing, if anything
@ -44,23 +45,21 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
if (fptr == NULL)
return 0;
// It's a .hmp. Convertchar *current_music_hndlbuf = NULL; to mid, store in music/ and pass the new filename.
if (!stricmp(fptr, ".hmp"))
{
PHYSFS_mkdir(basedir); // ALWAYS attempt to make 'Music': might exist in some searchpath but not the write directory
snprintf(midi_filename, PATH_MAX, "%s/%s", basedir, filename);
midi_filename[PATH_MAX - 1] = '\0';
change_filename_extension(midi_filename, midi_filename, ".mid");
hmp2mid(filename, midi_filename);
filename = midi_filename; // finished with hmp
}
loop = loop ? -1 : 1; // loop means loop infinitely, otherwise play once
// try loading music via given filename
current_music = Mix_LoadMUS(filename);
// It's a .hmp. Convert to midi stream and load to current_music
if (!stricmp(fptr, ".hmp"))
{
hmp2mid(filename, &current_music_hndlbuf, &bufsize);
rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
current_music = Mix_LoadMUS_RW(rw);
}
// no luck. so either it's in an archive or Searchpath
// try loading music via given filename
if (!current_music)
current_music = Mix_LoadMUS(filename);
// no luck. so it might be in Searchpath. So try to build absolute path
if (!current_music)
{
PHYSFSX_getRealPath(filename, full_path);
@ -69,15 +68,18 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
filename = full_path; // used later for possible error reporting
}
// still nothin'? Let's open via PhysFS in case it's located inside an archive
if (!current_music)
filehandle = PHYSFS_openRead(filename);
if (filehandle != NULL)
{
current_music_hndlbuf = d_realloc(current_music_hndlbuf, sizeof(char *)*PHYSFS_fileLength(filehandle));
bufsize = PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), PHYSFS_fileLength(filehandle));
rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
PHYSFS_close(filehandle);
current_music = Mix_LoadMUS_RW(rw);
filehandle = PHYSFS_openRead(filename);
if (filehandle != NULL)
{
current_music_hndlbuf = d_realloc(current_music_hndlbuf, sizeof(char *)*PHYSFS_fileLength(filehandle));
bufsize = PHYSFS_read(filehandle, current_music_hndlbuf, sizeof(char), PHYSFS_fileLength(filehandle));
rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
PHYSFS_close(filehandle);
current_music = Mix_LoadMUS_RW(rw);
}
}
if (current_music)
@ -89,12 +91,7 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
else
{
con_printf(CON_CRITICAL,"Music %s could not be loaded\n", filename);
Mix_HaltMusic();
if (current_music_hndlbuf)
{
d_free(current_music_hndlbuf);
current_music_hndlbuf = NULL;
}
mix_stop_music();
}
return 0;

View file

@ -54,7 +54,7 @@ typedef struct hmp_file {
hmp_file *hmp_open(const char *filename);
void hmp_close(hmp_file *hmp);
void hmp2mid(char *hmp_name, char *mid_name);
void hmp2mid(char *hmp_name, unsigned char **midbuf, unsigned int *midlen);
#ifdef WIN32
int hmp_play(hmp_file *hmp, int bLoop);
#endif

View file

@ -436,20 +436,21 @@ int hmp_play(hmp_file *hmp, int bLoop)
// CONVERSION FROM HMP TO MIDI
static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid)
static unsigned int hmptrk2mid(ubyte* data, int size, unsigned char **midbuf, unsigned int *midlen)
{
ubyte *dptr = data;
ubyte lc1 = 0,last_com = 0;
uint t = 0, d;
uint d;
int n1, n2;
int offset = cftell(mid);
unsigned int offset = *midlen;
while (data < dptr + size)
{
if (data[0] & 0x80) {
ubyte b = (data[0] & 0x7F);
PHYSFS_write(mid, &b, sizeof (b), 1);
t+=b;
*midbuf = d_realloc(*midbuf, *midlen + 1);
memcpy(&(*midbuf)[*midlen], &b, 1);
*midlen += 1;
}
else {
d = (data[0] & 0x7F);
@ -458,7 +459,6 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid)
n1++;
d += (data[n1] & 0x7F) << (n1 * 7);
}
t += d;
n1 = 1;
while ((data[n1] & 0x80) == 0) {
n1++;
@ -470,13 +470,17 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid)
if (n2 != n1)
b |= 0x80;
PHYSFS_write(mid, &b, sizeof(b), 1);
*midbuf = d_realloc(*midbuf, *midlen + 1);
memcpy(&(*midbuf)[*midlen], &b, 1);
*midlen += 1;
}
data += n1;
}
data++;
if (*data == 0xFF) { //meta?
PHYSFS_write(mid, data, 3 + data [2], 1);
*midbuf = d_realloc(*midbuf, *midlen + 3 + data[2]);
memcpy(&(*midbuf)[*midlen], data, 3 + data[2]);
*midlen += 3 + data[2];
if (data[1] == 0x2F)
break;
}
@ -491,15 +495,27 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid)
case 0xB0:
case 0xE0:
if (lc1 != last_com)
PHYSFS_write(mid, &lc1, sizeof (lc1), 1);
PHYSFS_write(mid, data + 1, 2, 1);
{
*midbuf = d_realloc(*midbuf, *midlen + 1);
memcpy(&(*midbuf)[*midlen], &lc1, 1);
*midlen += 1;
}
*midbuf = d_realloc(*midbuf, *midlen + 2);
memcpy(&(*midbuf)[*midlen], data + 1, 2);
*midlen += 2;
data += 3;
break;
case 0xC0:
case 0xD0:
if (lc1 != last_com)
PHYSFS_write(mid, &lc1, sizeof (lc1), 1);
PHYSFS_write(mid, data + 1, 1, 1);
{
*midbuf = d_realloc(*midbuf, *midlen + 1);
memcpy(&(*midbuf)[*midlen], &lc1, 1);
*midlen += 1;
}
*midbuf = d_realloc(*midbuf, *midlen + 1);
memcpy(&(*midbuf)[*midlen], data + 1, 1);
*midlen += 1;
data += 2;
break;
default:
@ -508,53 +524,63 @@ static int hmptrk2mid(ubyte* data, int size, PHYSFS_file *mid)
last_com = lc1;
}
}
return (cftell(mid) - offset);
return (*midlen - offset);
}
ubyte tempo [19] = {'M','T','r','k',0,0,0,11,0,0xFF,0x51,0x03,0x18,0x80,0x00,0,0xFF,0x2F,0};
void hmp2mid(char *hmp_name, char *mid_name)
void hmp2mid(char *hmp_name, unsigned char **midbuf, unsigned int *midlen)
{
PHYSFS_file *mid=NULL;
int mi, i, loc;
int mi, i;
short ms;
hmp_file *hmp=NULL;
hmp = hmp_open(hmp_name);
if (hmp == NULL)
return;
mid = PHYSFSX_openWriteBuffered(mid_name);
if (mid == NULL)
{
hmp_close(hmp);
return;
}
*midlen = 0;
// write MIDI-header
PHYSFS_write(mid, "MThd", 4, 1);
*midbuf = d_realloc(*midbuf, *midlen + 4);
memcpy(&(*midbuf)[*midlen], "MThd", 4);
*midlen += 4;
mi = MIDIINT(6);
PHYSFS_write(mid, &mi, sizeof(mi), 1);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(mi));
memcpy(&(*midbuf)[*midlen], &mi, sizeof(mi));
*midlen += sizeof(mi);
ms = MIDISHORT(1);
PHYSFS_write(mid, &ms, sizeof(ms), 1);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(ms));
memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms));
*midlen += sizeof(ms);
ms = MIDISHORT(hmp->num_trks);
PHYSFS_write(mid, &ms, sizeof(ms), 1);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(ms));
memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms));
*midlen += sizeof(ms);
ms = MIDISHORT((short) 0xC0);
PHYSFS_write(mid, &ms, sizeof(ms), 1);
PHYSFS_write(mid, tempo, sizeof(tempo), 1);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(ms));
memcpy(&(*midbuf)[*midlen], &ms, sizeof(ms));
*midlen += sizeof(ms);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(tempo));
memcpy(&(*midbuf)[*midlen], &tempo, sizeof(tempo));
*midlen += sizeof(tempo);
// tracks
for (i = 1; i < hmp->num_trks; i++)
{
PHYSFS_write(mid, "MTrk", 4, 1);
loc = cftell(mid);
int midtrklenpos = 0;
*midbuf = d_realloc(*midbuf, *midlen + 4);
memcpy(&(*midbuf)[*midlen], "MTrk", 4);
*midlen += 4;
midtrklenpos = *midlen;
mi = 0;
PHYSFS_write(mid, &mi, sizeof(mi), 1);
mi = hmptrk2mid(hmp->trks[i].data, hmp->trks[i].len, mid);
*midbuf = d_realloc(*midbuf, *midlen + sizeof(mi));
*midlen += sizeof(mi);
mi = hmptrk2mid(hmp->trks[i].data, hmp->trks[i].len, midbuf, midlen);
mi = MIDIINT(mi);
cfseek(mid, loc, SEEK_SET);
PHYSFS_write(mid, &mi, sizeof(mi), 1);
cfseek(mid, 0, SEEK_END);
memcpy(&(*midbuf)[midtrklenpos], &mi, 4);
}
hmp_close(hmp);
cfclose(mid);
}