]> icculus.org git repositories - btb/d2x.git/blob - arch/sdl/midi.c
get midi working with sdl_mixer and the hmp2midi from d2x-rebirth
[btb/d2x.git] / arch / sdl / midi.c
1 /*
2  *
3  * SDL midi support
4  *
5  *
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <conf.h>
10 #endif
11
12 #include "SDL.h"
13 #include "SDL_mixer.h"
14
15 #include "mono.h"
16 #include "inferno.h"
17 #include "u_mem.h"
18 #include "physfsrwops.h"
19 #include "hmp.h"
20
21
22 extern int Digi_initialized;
23
24 static int midi_volume = 128 / 2; // Max volume
25 char digi_last_midi_song[16] = "";
26 char digi_last_melodic_bank[16] = "";
27 char digi_last_drum_bank[16] = "";
28
29 // handle for the initialized MIDI song
30 Mix_Music *SongHandle = NULL;
31 ubyte *SongData = NULL;
32 unsigned int SongSize;
33
34
35 void digi_set_midi_volume( int mvolume )
36 {
37         int old_volume = midi_volume;
38
39         if ( mvolume > 127 )
40                 midi_volume = 127;
41         else if ( mvolume < 0 )
42                 midi_volume = 0;
43         else
44                 midi_volume = mvolume;
45
46         if (!Redbook_playing && (old_volume < 1) && ( midi_volume > 1 ) ) {
47                 if (!SongHandle)
48                         digi_play_midi_song( digi_last_midi_song, digi_last_melodic_bank, digi_last_drum_bank, 1 );
49         }
50         Mix_VolumeMusic(midi_volume);
51 }
52
53
54 void digi_play_midi_song( char *filename, char *melodic_bank, char *drum_bank, int loop )
55 {
56         SDL_RWops *rw = NULL;
57
58         if (!Digi_initialized) return;
59
60         digi_stop_current_song();
61
62         if ( filename == NULL ) return;
63
64         strcpy( digi_last_midi_song, filename );
65         strcpy( digi_last_melodic_bank, melodic_bank );
66         strcpy( digi_last_drum_bank, drum_bank );
67
68         if ( midi_volume < 1 )
69                 return; // Don't play song if volume == 0;
70
71         // initialize the song
72         mprintf((0, "Loading %s\n", filename));
73         hmp2mid(filename, &SongData, &SongSize);
74         rw = SDL_RWFromConstMem(SongData, SongSize);
75         SongHandle = Mix_LoadMUS_RW(rw);
76
77         if (!SongHandle) {
78                 char fname[128];
79                 CFILE *fp;
80                 int sl;
81
82                 // load .mid version, if available
83                 sl = (int)strlen( filename );
84                 strcpy( fname, filename );
85                 fname[sl-3] = 'm';
86                 fname[sl-2] = 'i';
87                 fname[sl-1] = 'd';
88
89                 mprintf((0, "Loading %s\n", fname));
90                 fp = cfopen( fname, "rb" );
91
92                 SongSize = cfilelength( fp );
93                 SongData = d_calloc(SongSize, 1);
94                 if (SongData == NULL) {
95                         cfclose(fp);
96                         mprintf( (1, "Error allocating %d bytes for '%s'", SongSize, filename ));
97                         return;
98                 }
99
100                 if ( cfread ( SongData, SongSize, 1, fp ) != 1 ) {
101                         mprintf( (1, "Error reading midi file, '%s'", filename ));
102                         cfclose(fp);
103                         d_free(SongData);
104                         return;
105                 }
106
107                 cfclose(fp);
108
109                 rw = SDL_RWFromConstMem(SongData, SongSize);
110                 SongHandle = Mix_LoadMUS_RW(rw);
111         }
112
113         if (!SongHandle) {
114                 mprintf( (1, "MIDI Error : %s\n", Mix_GetError()));
115                 if (SongData)
116                         d_free(SongData);
117                 return;
118         }
119
120         // start the song playing
121         Mix_PlayMusic(SongHandle, (loop ? -1 : 1));
122         Mix_HookMusicFinished(digi_stop_current_song);
123
124         return;
125 }
126
127
128 void digi_stop_current_song()
129 {
130         if (!Digi_initialized) return;
131
132         // Stop last song...
133         if (SongHandle) {
134                 // stop the last MIDI song from playing
135                 Mix_HaltMusic();
136                 // uninitialize the last MIDI song
137                 Mix_FreeMusic( SongHandle );
138                 SongHandle = NULL;
139         }
140         if (SongData) {
141                 d_free(SongData);
142                 SongData = NULL;
143         }
144 }
145
146
147 void digi_pause_midi()
148 {
149         if (!Digi_initialized) return;
150         
151         Mix_PauseMusic();
152 }
153
154
155 void digi_resume_midi()
156 {
157         if (!Digi_initialized) return;
158         
159         Mix_ResumeMusic();
160 }