Skip to content

Latest commit

 

History

History
310 lines (270 loc) · 8.52 KB

music_modplug.c

File metadata and controls

310 lines (270 loc) · 8.52 KB
 
Jun 9, 2013
Jun 9, 2013
1
2
/*
SDL_mixer: An audio mixer library based on the SDL library
Mar 1, 2018
Mar 1, 2018
3
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Jun 9, 2013
Jun 9, 2013
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
Oct 17, 2017
Oct 17, 2017
22
23
24
#ifdef MUSIC_MOD_MODPLUG
#include "SDL_loadso.h"
Nov 16, 2009
Nov 16, 2009
25
26
27
#include "music_modplug.h"
Oct 17, 2017
Oct 17, 2017
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#ifdef MODPLUG_HEADER
#include MODPLUG_HEADER
#else
#include <libmodplug/modplug.h>
#endif
typedef struct {
int loaded;
void *handle;
ModPlugFile* (*ModPlug_Load)(const void* data, int size);
void (*ModPlug_Unload)(ModPlugFile* file);
int (*ModPlug_Read)(ModPlugFile* file, void* buffer, int size);
void (*ModPlug_Seek)(ModPlugFile* file, int millisecond);
void (*ModPlug_GetSettings)(ModPlug_Settings* settings);
void (*ModPlug_SetSettings)(const ModPlug_Settings* settings);
void (*ModPlug_SetMasterVolume)(ModPlugFile* file,unsigned int cvol) ;
} modplug_loader;
static modplug_loader modplug = {
0, NULL
};
Nov 16, 2009
Nov 16, 2009
52
53
static ModPlug_Settings settings;
Oct 17, 2017
Oct 17, 2017
54
#ifdef MODPLUG_DYNAMIC
Oct 21, 2017
Oct 21, 2017
55
56
57
58
59
60
61
#define FUNCTION_LOADER(FUNC, SIG) \
modplug.FUNC = (SIG) SDL_LoadFunction(modplug.handle, #FUNC); \
if (modplug.FUNC == NULL) { SDL_UnloadObject(modplug.handle); return -1; }
#else
#define FUNCTION_LOADER(FUNC, SIG) \
modplug.FUNC = FUNC;
#endif
Oct 17, 2017
Oct 17, 2017
62
63
64
65
static int MODPLUG_Load(void)
{
if (modplug.loaded == 0) {
Oct 21, 2017
Oct 21, 2017
66
#ifdef MODPLUG_DYNAMIC
Oct 17, 2017
Oct 17, 2017
67
68
69
70
modplug.handle = SDL_LoadObject(MODPLUG_DYNAMIC);
if (modplug.handle == NULL) {
return -1;
}
Oct 21, 2017
Oct 21, 2017
71
#elif defined(__MACOSX__)
Oct 17, 2017
Oct 17, 2017
72
73
74
75
76
77
78
extern ModPlugFile* ModPlug_Load(const void* data, int size) __attribute__((weak_import));
if (ModPlug_Load == NULL)
{
/* Missing weakly linked framework */
Mix_SetError("Missing modplug.framework");
return -1;
}
Oct 21, 2017
Oct 21, 2017
79
80
81
82
83
84
85
86
#endif
FUNCTION_LOADER(ModPlug_Load, ModPlugFile* (*)(const void* data, int size))
FUNCTION_LOADER(ModPlug_Unload, void (*)(ModPlugFile* file))
FUNCTION_LOADER(ModPlug_Read, int (*)(ModPlugFile* file, void* buffer, int size))
FUNCTION_LOADER(ModPlug_Seek, void (*)(ModPlugFile* file, int millisecond))
FUNCTION_LOADER(ModPlug_GetSettings, void (*)(ModPlug_Settings* settings))
FUNCTION_LOADER(ModPlug_SetSettings, void (*)(const ModPlug_Settings* settings))
FUNCTION_LOADER(ModPlug_SetMasterVolume, void (*)(ModPlugFile* file,unsigned int cvol))
Oct 17, 2017
Oct 17, 2017
87
88
89
90
91
92
93
}
++modplug.loaded;
return 0;
}
static void MODPLUG_Unload(void)
Nov 16, 2009
Nov 16, 2009
94
{
Oct 17, 2017
Oct 17, 2017
95
96
if (modplug.loaded == 0) {
return;
Jun 9, 2013
Jun 9, 2013
97
}
Oct 17, 2017
Oct 17, 2017
98
if (modplug.loaded == 1) {
Oct 21, 2017
Oct 21, 2017
99
100
101
#ifdef MODPLUG_DYNAMIC
SDL_UnloadObject(modplug.handle);
#endif
Oct 17, 2017
Oct 17, 2017
102
103
104
}
--modplug.loaded;
}
Jun 9, 2013
Jun 9, 2013
105
Oct 17, 2017
Oct 17, 2017
106
Oct 21, 2017
Oct 21, 2017
107
typedef struct
Oct 17, 2017
Oct 17, 2017
108
{
Oct 21, 2017
Oct 21, 2017
109
110
111
112
113
114
int play_count;
ModPlugFile *file;
SDL_AudioStream *stream;
void *buffer;
int buffer_size;
} MODPLUG_Music;
May 22, 2013
May 22, 2013
115
116
Oct 21, 2017
Oct 21, 2017
117
118
static int MODPLUG_Seek(void *context, double position);
static void MODPLUG_Delete(void *context);
May 22, 2013
May 22, 2013
119
Oct 21, 2017
Oct 21, 2017
120
121
122
123
124
125
126
127
128
static int MODPLUG_Open(const SDL_AudioSpec *spec)
{
/* ModPlug supports U8 or S16 audio output */
modplug.ModPlug_GetSettings(&settings);
settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING;
if (spec->channels == 1) {
settings.mChannels = 1;
} else {
settings.mChannels = 2;
May 22, 2013
May 22, 2013
129
}
Oct 21, 2017
Oct 21, 2017
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
if (SDL_AUDIO_BITSIZE(spec->format) == 8) {
settings.mBits = 8;
} else {
settings.mBits = 16;
}
if (spec->freq >= 44100) {
settings.mFrequency = 44100;
} else if (spec->freq >= 22050) {
settings.mFrequency = 22050;
} else {
settings.mFrequency = 11025;
}
settings.mResamplingMode = MODPLUG_RESAMPLE_FIR;
settings.mReverbDepth = 0;
settings.mReverbDelay = 100;
settings.mBassAmount = 0;
settings.mBassRange = 50;
settings.mSurroundDepth = 0;
settings.mSurroundDelay = 10;
settings.mLoopCount = 0;
Jun 9, 2013
Jun 9, 2013
150
modplug.ModPlug_SetSettings(&settings);
May 22, 2013
May 22, 2013
151
return 0;
Nov 16, 2009
Nov 16, 2009
152
153
154
}
/* Load a modplug stream from an SDL_RWops object */
Oct 17, 2017
Oct 17, 2017
155
void *MODPLUG_CreateFromRW(SDL_RWops *src, int freesrc)
Nov 16, 2009
Nov 16, 2009
156
{
Oct 21, 2017
Oct 21, 2017
157
158
159
160
161
162
MODPLUG_Music *music;
void *buffer;
size_t size;
music = (MODPLUG_Music *)SDL_calloc(1, sizeof(*music));
if (!music) {
May 22, 2013
May 22, 2013
163
SDL_OutOfMemory();
Oct 21, 2017
Oct 21, 2017
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
return NULL;
}
music->stream = SDL_NewAudioStream((settings.mBits == 8) ? AUDIO_U8 : AUDIO_S16SYS, settings.mChannels, settings.mFrequency,
music_spec.format, music_spec.channels, music_spec.freq);
if (!music->stream) {
MODPLUG_Delete(music);
return NULL;
}
music->buffer_size = music_spec.samples * (settings.mBits / 8) * settings.mChannels;
music->buffer = SDL_malloc(music->buffer_size);
if (!music->buffer) {
MODPLUG_Delete(music);
return NULL;
May 22, 2013
May 22, 2013
179
}
Oct 21, 2017
Oct 21, 2017
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
buffer = SDL_LoadFile_RW(src, &size, SDL_FALSE);
if (buffer) {
music->file = modplug.ModPlug_Load(buffer, (int)size);
if (!music->file) {
Mix_SetError("ModPlug_Load failed");
}
SDL_free(buffer);
}
if (!music->file) {
MODPLUG_Delete(music);
return NULL;
}
if (freesrc) {
Jun 2, 2013
Jun 2, 2013
196
SDL_RWclose(src);
May 22, 2013
May 22, 2013
197
198
}
return music;
Nov 16, 2009
Nov 16, 2009
199
200
}
Oct 17, 2017
Oct 17, 2017
201
202
/* Set the volume for a modplug stream */
static void MODPLUG_SetVolume(void *context, int volume)
Nov 16, 2009
Nov 16, 2009
203
{
Oct 21, 2017
Oct 21, 2017
204
205
MODPLUG_Music *music = (MODPLUG_Music *)context;
modplug.ModPlug_SetMasterVolume(music->file, volume*4);
Nov 16, 2009
Nov 16, 2009
206
207
}
Oct 17, 2017
Oct 17, 2017
208
/* Start playback of a given modplug stream */
Oct 21, 2017
Oct 21, 2017
209
static int MODPLUG_Play(void *context, int play_count)
Nov 16, 2009
Nov 16, 2009
210
{
Oct 21, 2017
Oct 21, 2017
211
212
213
MODPLUG_Music *music = (MODPLUG_Music *)context;
music->play_count = play_count;
return MODPLUG_Seek(music, 0.0);
Nov 16, 2009
Nov 16, 2009
214
215
216
}
/* Play some of a stream previously started with modplug_play() */
Oct 21, 2017
Oct 21, 2017
217
static int MODPLUG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
Nov 16, 2009
Nov 16, 2009
218
{
Oct 21, 2017
Oct 21, 2017
219
220
221
222
223
224
MODPLUG_Music *music = (MODPLUG_Music *)context;
int filled, amount;
filled = SDL_AudioStreamGet(music->stream, data, bytes);
if (filled != 0) {
return filled;
May 22, 2013
May 22, 2013
225
226
}
Oct 21, 2017
Oct 21, 2017
227
228
229
230
231
232
233
234
235
236
if (!music->play_count) {
/* All done */
*done = SDL_TRUE;
return 0;
}
amount = modplug.ModPlug_Read(music->file, music->buffer, music->buffer_size);
if (amount > 0) {
if (SDL_AudioStreamPut(music->stream, music->buffer, amount) < 0) {
return -1;
May 22, 2013
May 22, 2013
237
}
Oct 21, 2017
Oct 21, 2017
238
239
240
241
242
243
244
245
246
247
248
249
} else {
if (music->play_count == 1) {
music->play_count = 0;
SDL_AudioStreamFlush(music->stream);
} else {
int play_count = -1;
if (music->play_count > 0) {
play_count = (music->play_count - 1);
}
if (MODPLUG_Play(music, play_count) < 0) {
return -1;
}
May 22, 2013
May 22, 2013
250
251
}
}
Oct 21, 2017
Oct 21, 2017
252
253
254
255
256
return 0;
}
static int MODPLUG_GetAudio(void *context, void *data, int bytes)
{
return music_pcm_getaudio(context, data, bytes, MIX_MAX_VOLUME, MODPLUG_GetSome);
Nov 16, 2009
Nov 16, 2009
257
258
}
Oct 17, 2017
Oct 17, 2017
259
260
/* Jump (seek) to a given position */
static int MODPLUG_Seek(void *context, double position)
Nov 16, 2009
Nov 16, 2009
261
{
Oct 21, 2017
Oct 21, 2017
262
263
MODPLUG_Music *music = (MODPLUG_Music *)context;
modplug.ModPlug_Seek(music->file, (int)(position*1000));
Oct 17, 2017
Oct 17, 2017
264
return 0;
Nov 16, 2009
Nov 16, 2009
265
266
267
}
/* Close the given modplug stream */
Oct 17, 2017
Oct 17, 2017
268
static void MODPLUG_Delete(void *context)
Nov 16, 2009
Nov 16, 2009
269
{
Oct 21, 2017
Oct 21, 2017
270
271
272
273
274
275
276
277
278
279
280
MODPLUG_Music *music = (MODPLUG_Music *)context;
if (music->file) {
modplug.ModPlug_Unload(music->file);
}
if (music->stream) {
SDL_FreeAudioStream(music->stream);
}
if (music->buffer) {
SDL_free(music->buffer);
}
SDL_free(music);
Nov 16, 2009
Nov 16, 2009
281
282
}
Oct 17, 2017
Oct 17, 2017
283
Mix_MusicInterface Mix_MusicInterface_MODPLUG =
Nov 16, 2009
Nov 16, 2009
284
{
Oct 17, 2017
Oct 17, 2017
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
"MODPLUG",
MIX_MUSIC_MODPLUG,
MUS_MOD,
SDL_FALSE,
SDL_FALSE,
MODPLUG_Load,
MODPLUG_Open,
MODPLUG_CreateFromRW,
NULL, /* CreateFromFile */
MODPLUG_SetVolume,
MODPLUG_Play,
NULL, /* IsPlaying */
MODPLUG_GetAudio,
MODPLUG_Seek,
NULL, /* Pause */
NULL, /* Resume */
NULL, /* Stop */
MODPLUG_Delete,
NULL, /* Close */
MODPLUG_Unload,
};
#endif /* MUSIC_MOD_MODPLUG */
Nov 16, 2009
Nov 16, 2009
309
Oct 17, 2017
Oct 17, 2017
310
/* vi: set ts=4 sw=4 expandtab: */