/* midi.c midi file loading for use with libWildMidi Copyright (C) 2003 Chris Ison This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include #include #include "QF/cvar.h" #include "QF/sound.h" #include "QF/sys.h" #include "QF/quakefs.h" #include "snd_render.h" static int midi_intiialized = 0; static cvar_t *wildmidi_volume; static cvar_t *wildmidi_config; static int midi_init ( void ) { wildmidi_volume = Cvar_Get ("wildmidi_volume", "100", CVAR_ARCHIVE, NULL, "Set the Master Volume"); wildmidi_config = Cvar_Get ("wildmidi_config", "/etc/timidity.cfg", CVAR_ROM, NULL, "path/filename of timidity.cfg"); if (WildMidi_Init (wildmidi_config->string, snd_shm->speed, 0) == -1) return 1; midi_intiialized = 1; return 0; } static wavinfo_t midi_get_info (void * handle) { wavinfo_t info; struct _WM_Info *wm_info; memset (&info, 0, sizeof (info)); if ((wm_info = WildMidi_GetInfo (handle)) == NULL) { Sys_Printf ("Could not obtain midi information\n"); return info; } info.rate = snd_shm->speed; info.width = 2; info.channels = 2; info.loopstart = -1; info.samples = wm_info->approx_total_samples; info.dataofs = 0; info.datalen = info.samples * 4; return info; } static int midi_stream_read (void *file, byte *buf, int count, wavinfo_t *info) { return WildMidi_GetOutput (file, (char *)buf, (unsigned long int)count); } static int midi_stream_seek (void *file, int pos, wavinfo_t *info) { unsigned long int new_pos; pos *= info->width * info->channels; pos += info->dataofs; new_pos = pos; return WildMidi_SampledSeek(file, &new_pos); } static void midi_stream_close (sfx_t *sfx) { sfxstream_t *stream = sfx->data.stream; WildMidi_Close (stream->file); free (stream); free (sfx); } /* * Note: we set up only the QF stream here. * The WildMidi stream was setup when SND_OpenMidi was called * so stream->file contains the WildMidi handle for the midi */ static sfx_t * midi_stream_open (sfx_t *sfx) { sfxstream_t *stream = sfx->data.stream; QFile *file; midi *handle; unsigned char *local_buffer; unsigned long int local_buffer_size; QFS_FOpenFile (stream->file, &file); local_buffer_size = Qfilesize (file); local_buffer = malloc (local_buffer_size); Qread (file, local_buffer, local_buffer_size); Qclose (file); handle = WildMidi_OpenBuffer(local_buffer, local_buffer_size); if (handle == NULL) return NULL; return SND_SFX_StreamOpen (sfx, handle, midi_stream_read, midi_stream_seek, midi_stream_close); } int SND_LoadMidi (QFile *file, sfx_t *sfx, char *realname) { wavinfo_t info; midi *handle; unsigned char *local_buffer; unsigned long int local_buffer_size = Qfilesize (file); if (!midi_intiialized) { if (midi_init ()) { return -1; } } local_buffer = malloc (local_buffer_size); Qread (file, local_buffer, local_buffer_size); Qclose (file); // WildMidi takes ownership, so be damned if you touch it handle = WildMidi_OpenBuffer (local_buffer, local_buffer_size); if (handle == NULL) return -1; info = midi_get_info (handle); WildMidi_Close (handle); Sys_DPrintf ("stream %s\n", realname); // we init stream here cause we will only ever stream SND_SFX_Stream (sfx, realname, info, midi_stream_open); return 0; }