Skip to content

Latest commit

 

History

History
176 lines (133 loc) · 4.79 KB

midi.c

File metadata and controls

176 lines (133 loc) · 4.79 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* SDL_sound -- An abstract sound format decoding API.
* Copyright (C) 2001 Ryan C. Gordon.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
Jan 4, 2002
Jan 4, 2002
21
* MIDI decoder for SDL_sound.
22
*
Jan 4, 2002
Jan 4, 2002
23
24
* This driver handles MIDI data through a stripped-down version of TiMidity.
* See the documentation in the timidity subdirectory.
25
*
Dec 26, 2001
Dec 26, 2001
26
* Please see the file COPYING in the source's root directory.
27
28
29
30
31
32
33
34
35
36
37
38
39
*
* This file written by Torbjörn Andersson. (d91tan@Update.UU.SE)
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SOUND_SUPPORTS_MIDI
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Jan 4, 2002
Jan 4, 2002
40
41
42
43
44
45
#include "SDL_sound.h"
#define __SDL_SOUND_INTERNAL__
#include "SDL_sound_internal.h"
Jan 4, 2002
Jan 4, 2002
46
47
#include "timidity.h"
48
49
50
51
52
53
static int MIDI_init(void);
static void MIDI_quit(void);
static int MIDI_open(Sound_Sample *sample, const char *ext);
static void MIDI_close(Sound_Sample *sample);
static Uint32 MIDI_read(Sound_Sample *sample);
Jan 17, 2002
Jan 17, 2002
54
static int MIDI_rewind(Sound_Sample *sample);
Apr 21, 2002
Apr 21, 2002
55
static int MIDI_seek(Sound_Sample *sample, Uint32 ms);
56
Jan 4, 2002
Jan 4, 2002
57
static const char *extensions_midi[] = { "MIDI", "MID", NULL };
58
59
60
const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI =
{
{
Nov 1, 2001
Nov 1, 2001
61
extensions_midi,
Jan 4, 2002
Jan 4, 2002
62
"MIDI decoder, using a subset of TiMidity",
63
"Torbjörn Andersson <d91tan@Update.UU.SE>",
Jan 4, 2002
Jan 4, 2002
64
"http://www.icculus.org/SDL_sound/"
65
66
},
Jan 17, 2002
Jan 17, 2002
67
68
69
70
71
MIDI_init, /* init() method */
MIDI_quit, /* quit() method */
MIDI_open, /* open() method */
MIDI_close, /* close() method */
MIDI_read, /* read() method */
Apr 21, 2002
Apr 21, 2002
72
73
MIDI_rewind, /* rewind() method */
MIDI_seek /* seek() method */
74
75
76
77
78
};
static int MIDI_init(void)
{
Jan 4, 2002
Jan 4, 2002
79
BAIL_IF_MACRO(Timidity_Init() < 0, "MIDI: Could not initialise", 0);
80
81
82
83
84
85
return(1);
} /* MIDI_init */
static void MIDI_quit(void)
{
Jan 4, 2002
Jan 4, 2002
86
Timidity_Exit();
87
88
89
90
91
92
93
} /* MIDI_quit */
static int MIDI_open(Sound_Sample *sample, const char *ext)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
SDL_RWops *rw = internal->rw;
Jan 4, 2002
Jan 4, 2002
94
95
96
97
98
99
100
101
102
103
104
105
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);
106
Jan 4, 2002
Jan 4, 2002
107
SNDDBG(("MIDI: Accepting data stream.\n"));
108
Jan 4, 2002
Jan 4, 2002
109
internal->decoder_private = (void *) song;
May 12, 2004
May 12, 2004
110
internal->total_time = Timidity_GetSongLength(song);
111
Jan 4, 2002
Jan 4, 2002
112
113
114
sample->actual.channels = 2;
sample->actual.rate = 44100;
sample->actual.format = AUDIO_S16SYS;
Apr 24, 2002
Apr 24, 2002
115
sample->flags = SOUND_SAMPLEFLAG_CANSEEK;
May 12, 2004
May 12, 2004
116
117
118
119
120
121
122
123
return(1); /* we'll handle this data. */
} /* MIDI_open */
static void MIDI_close(Sound_Sample *sample)
{
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
Jan 4, 2002
Jan 4, 2002
124
MidiSong *song = (MidiSong *) internal->decoder_private;
125
Jan 4, 2002
Jan 4, 2002
126
Timidity_FreeSong(song);
127
128
129
130
131
} /* MIDI_close */
static Uint32 MIDI_read(Sound_Sample *sample)
{
Jan 4, 2002
Jan 4, 2002
132
Uint32 retval;
133
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
Jan 4, 2002
Jan 4, 2002
134
MidiSong *song = (MidiSong *) internal->decoder_private;
135
Jan 4, 2002
Jan 4, 2002
136
retval = Timidity_PlaySome(song, internal->buffer, internal->buffer_size);
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* 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 */
Jan 17, 2002
Jan 17, 2002
152
153
154
static int MIDI_rewind(Sound_Sample *sample)
{
Jan 19, 2002
Jan 19, 2002
155
156
157
158
159
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;
Timidity_Start(song);
return(1);
Jan 17, 2002
Jan 17, 2002
160
161
} /* MIDI_rewind */
Apr 21, 2002
Apr 21, 2002
162
163
164
static int MIDI_seek(Sound_Sample *sample, Uint32 ms)
{
Apr 24, 2002
Apr 24, 2002
165
166
167
168
169
Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
MidiSong *song = (MidiSong *) internal->decoder_private;
Timidity_Seek(song, ms);
return(1);
Apr 21, 2002
Apr 21, 2002
170
171
} /* MIDI_seek */
172
173
#endif /* SOUND_SUPPORTS_MIDI */
Jan 4, 2002
Jan 4, 2002
174
175
/* end of midi.c ... */