Instead of writing converted MIDI to file, write to buffer so it can be played directly
This commit is contained in:
parent
e57ffac570
commit
ae22f8e037
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
// It's a .hmp. Convert to midi stream and load to current_music
|
||||
if (!stricmp(fptr, ".hmp"))
|
||||
{
|
||||
hmp2mid(filename, ¤t_music_hndlbuf, &bufsize);
|
||||
rw = SDL_RWFromConstMem(current_music_hndlbuf,bufsize*sizeof(char));
|
||||
current_music = Mix_LoadMUS_RW(rw);
|
||||
}
|
||||
|
||||
// try loading music via given filename
|
||||
if (!current_music)
|
||||
current_music = Mix_LoadMUS(filename);
|
||||
|
||||
// no luck. so either it's in an archive or Searchpath
|
||||
// no luck. so it might be in Searchpath. So try to build absolute path
|
||||
if (!current_music)
|
||||
{
|
||||
PHYSFSX_getRealPath(filename, full_path);
|
||||
|
@ -69,7 +68,9 @@ 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)
|
||||
{
|
||||
|
@ -79,6 +80,7 @@ int mix_play_file(char *filename, int loop, void (*hook_finished_track)())
|
|||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
98
misc/hmp.c
98
misc/hmp.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue