Skip to content

Latest commit

 

History

History
264 lines (234 loc) · 7.11 KB

music_modplug.c

File metadata and controls

264 lines (234 loc) · 7.11 KB
 
Jun 9, 2013
Jun 9, 2013
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
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.
*/
Nov 16, 2009
Nov 16, 2009
22
23
#ifdef MODPLUG_MUSIC
Jun 9, 2013
Jun 9, 2013
24
25
#include "SDL_mixer.h"
#include "dynamic_modplug.h"
Nov 16, 2009
Nov 16, 2009
26
27
28
29
30
31
32
33
34
#include "music_modplug.h"
static int current_output_channels=0;
static int music_swap8=0;
static int music_swap16=0;
static ModPlug_Settings settings;
int modplug_init(SDL_AudioSpec *spec)
{
Jun 9, 2013
Jun 9, 2013
35
36
37
38
39
if ( !Mix_Init(MIX_INIT_MODPLUG) ) {
return -1;
}
modplug.ModPlug_GetSettings(&settings);
May 22, 2013
May 22, 2013
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
settings.mFlags=MODPLUG_ENABLE_OVERSAMPLING;
current_output_channels=spec->channels;
settings.mChannels=spec->channels>1?2:1;
settings.mBits=spec->format&0xFF;
music_swap8 = 0;
music_swap16 = 0;
switch(spec->format)
{
case AUDIO_U8:
case AUDIO_S8: {
if ( spec->format == AUDIO_S8 ) {
music_swap8 = 1;
}
settings.mBits=8;
}
break;
case AUDIO_S16LSB:
case AUDIO_S16MSB: {
/* See if we need to correct MikMod mixing */
Nov 16, 2009
Nov 16, 2009
62
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
May 22, 2013
May 22, 2013
63
if ( spec->format == AUDIO_S16MSB ) {
Nov 16, 2009
Nov 16, 2009
64
#else
May 22, 2013
May 22, 2013
65
if ( spec->format == AUDIO_S16LSB ) {
Nov 16, 2009
Nov 16, 2009
66
#endif
May 22, 2013
May 22, 2013
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
music_swap16 = 1;
}
settings.mBits=16;
}
break;
default: {
Mix_SetError("Unknown hardware audio format");
return -1;
}
}
settings.mFrequency=spec->freq; /*TODO: limit to 11025, 22050, or 44100 ? */
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
89
modplug.ModPlug_SetSettings(&settings);
May 22, 2013
May 22, 2013
90
return 0;
Nov 16, 2009
Nov 16, 2009
91
92
93
94
95
96
97
98
99
100
}
/* Uninitialize the music players */
void modplug_exit()
{
}
/* Set the volume for a modplug stream */
void modplug_setvolume(modplug_data *music, int volume)
{
Jun 9, 2013
Jun 9, 2013
101
modplug.ModPlug_SetMasterVolume(music->file, volume*4);
Nov 16, 2009
Nov 16, 2009
102
103
104
}
/* Load a modplug stream from an SDL_RWops object */
Jun 2, 2013
Jun 2, 2013
105
modplug_data *modplug_new_RW(SDL_RWops *src, int freesrc)
Nov 16, 2009
Nov 16, 2009
106
{
Jun 2, 2013
Jun 2, 2013
107
108
109
110
modplug_data *music = NULL;
Sint64 offset;
size_t sz;
char *buf;
May 22, 2013
May 22, 2013
111
Jun 9, 2013
Jun 9, 2013
112
113
114
115
116
/* Make sure the modplug library is loaded */
if ( !Mix_Init(MIX_INIT_MODPLUG) ) {
return NULL;
}
Jun 2, 2013
Jun 2, 2013
117
118
119
120
121
122
123
124
125
126
offset = SDL_RWtell(src);
SDL_RWseek(src, 0, RW_SEEK_END);
sz = (size_t)(SDL_RWtell(src) - offset);
SDL_RWseek(src, offset, RW_SEEK_SET);
buf = (char*)SDL_malloc(sz);
if (buf) {
if (SDL_RWread(src, buf, sz, 1) == 1) {
music = (modplug_data*)SDL_malloc(sizeof(modplug_data));
if (music) {
music->playing = 0;
Jun 9, 2013
Jun 9, 2013
127
music->file = modplug.ModPlug_Load(buf, sz);
Jun 2, 2013
Jun 2, 2013
128
if (!music->file) {
May 22, 2013
May 22, 2013
129
SDL_free(music);
Jun 2, 2013
Jun 2, 2013
130
music = NULL;
May 22, 2013
May 22, 2013
131
}
Jun 2, 2013
Jun 2, 2013
132
} else {
May 22, 2013
May 22, 2013
133
134
135
136
SDL_OutOfMemory();
}
}
SDL_free(buf);
Jun 2, 2013
Jun 2, 2013
137
} else {
May 22, 2013
May 22, 2013
138
139
SDL_OutOfMemory();
}
Jun 2, 2013
Jun 2, 2013
140
141
if (music && freesrc) {
SDL_RWclose(src);
May 22, 2013
May 22, 2013
142
143
}
return music;
Nov 16, 2009
Nov 16, 2009
144
145
146
147
148
}
/* Start playback of a given modplug stream */
void modplug_play(modplug_data *music)
{
Jun 9, 2013
Jun 9, 2013
149
modplug.ModPlug_Seek(music->file,0);
May 22, 2013
May 22, 2013
150
music->playing=1;
Nov 16, 2009
Nov 16, 2009
151
152
153
154
155
}
/* Return non-zero if a stream is currently playing */
int modplug_playing(modplug_data *music)
{
May 22, 2013
May 22, 2013
156
return music && music->playing;
Nov 16, 2009
Nov 16, 2009
157
158
159
160
161
}
/* Play some of a stream previously started with modplug_play() */
int modplug_playAudio(modplug_data *music, Uint8 *stream, int len)
{
May 22, 2013
May 22, 2013
162
163
164
165
166
if (current_output_channels > 2) {
int small_len = 2 * len / current_output_channels;
int i;
Uint8 *src, *dst;
Jun 9, 2013
Jun 9, 2013
167
i=modplug.ModPlug_Read(music->file, stream, small_len);
May 22, 2013
May 22, 2013
168
169
if(i<small_len)
{
Jun 1, 2013
Jun 1, 2013
170
SDL_memset(stream+i,0,small_len-i);
May 22, 2013
May 22, 2013
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
music->playing=0;
}
/* and extend to len by copying channels */
src = stream + small_len;
dst = stream + len;
switch (settings.mBits) {
case 8:
for ( i=small_len/2; i; --i ) {
src -= 2;
dst -= current_output_channels;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = src[1];
if (current_output_channels == 6) {
dst[4] = src[0];
dst[5] = src[1];
}
}
break;
case 16:
for ( i=small_len/4; i; --i ) {
src -= 4;
dst -= 2 * current_output_channels;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[0];
dst[5] = src[1];
dst[6] = src[2];
dst[7] = src[3];
if (current_output_channels == 6) {
dst[8] = src[0];
dst[9] = src[1];
dst[10] = src[2];
dst[11] = src[3];
}
}
break;
}
} else {
Jun 9, 2013
Jun 9, 2013
214
int i=modplug.ModPlug_Read(music->file, stream, len);
May 22, 2013
May 22, 2013
215
216
if(i<len)
{
Jun 1, 2013
Jun 1, 2013
217
SDL_memset(stream+i,0,len-i);
May 22, 2013
May 22, 2013
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
music->playing=0;
}
}
if ( music_swap8 ) {
Uint8 *dst;
int i;
dst = stream;
for ( i=len; i; --i ) {
*dst++ ^= 0x80;
}
} else
if ( music_swap16 ) {
Uint8 *dst, tmp;
int i;
dst = stream;
for ( i=(len/2); i; --i ) {
tmp = dst[0];
dst[0] = dst[1];
dst[1] = tmp;
dst += 2;
}
}
return 0;
Nov 16, 2009
Nov 16, 2009
243
244
245
246
247
}
/* Stop playback of a stream previously started with modplug_play() */
void modplug_stop(modplug_data *music)
{
May 22, 2013
May 22, 2013
248
music->playing=0;
Nov 16, 2009
Nov 16, 2009
249
250
251
252
253
}
/* Close the given modplug stream */
void modplug_delete(modplug_data *music)
{
Jun 9, 2013
Jun 9, 2013
254
modplug.ModPlug_Unload(music->file);
May 22, 2013
May 22, 2013
255
SDL_free(music);
Nov 16, 2009
Nov 16, 2009
256
257
258
259
260
}
/* Jump (seek) to a given position (time is in seconds) */
void modplug_jump_to_time(modplug_data *music, double time)
{
Jun 9, 2013
Jun 9, 2013
261
modplug.ModPlug_Seek(music->file,(int)(time*1000));
Nov 16, 2009
Nov 16, 2009
262
263
}
Jun 9, 2013
Jun 9, 2013
264
#endif /* MODPLUG_MUSIC */