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