00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include "input_mod.h"
00016 #include "debug.h"
00017 #include "utility.h"
00018
00019
00020 namespace audiere {
00021
00022 MD_DEVICE MODInputStream::drv_audiere = {
00023 "Audiere Output",
00024 "Internal Audiere Output Driver",
00025 0,
00026 VC_MAXVOICES,
00027
00028 NULL,
00029 NULL,
00030 NULL,
00031
00032
00033 VC_SampleAlloc,
00034 VC_SampleGetPtr,
00035 VC_SampleLoad,
00036 VC_SampleUnload,
00037 VC_SampleSpace,
00038 VC_SampleLength,
00039
00040
00041 ADR_IsThere,
00042 ADR_Init,
00043 ADR_Exit,
00044 ADR_Update,
00045 VC_Preempt,
00046
00047 NULL,
00048 ADR_SetSoftVoices,
00049
00050 ADR_SetMode,
00051 ADR_GetMode,
00052
00053 VC_SetVolume,
00054 VC_GetVolume,
00055
00056
00057 VC_GetActiveVoices,
00058
00059 VC_VoiceSetVolume,
00060 VC_VoiceGetVolume,
00061 VC_VoiceSetFrequency,
00062 VC_VoiceGetFrequency,
00063 VC_VoiceSetPosition,
00064 VC_VoiceGetPosition,
00065 VC_VoiceSetSurround,
00066 VC_VoiceSetResonance,
00067
00068 VC_VoicePlay,
00069 VC_VoiceResume,
00070 VC_VoiceStop,
00071 VC_VoiceStopped,
00072 VC_VoiceReleaseSustain,
00073
00074 VC_VoiceRealVolume
00075 };
00076
00077
00078 MODInputStream::MODInputStream() {
00079 m_file = 0;
00080
00081 m_driver = 0;
00082 m_module = 0;
00083 m_player = 0;
00084
00085 m_samples_left = 0;
00086 m_next_sample = m_sample_buffer;
00087
00088 m_at_eof = false;
00089 }
00090
00091
00092 MODInputStream::~MODInputStream() {
00093 if (m_player) {
00094 Player_Free(m_player);
00095 }
00096 if (m_module) {
00097 Unimod_Free(m_module);
00098 }
00099 if (m_driver) {
00100 Mikmod_Exit(m_driver);
00101 }
00102 }
00103
00104
00105 bool
00106 MODInputStream::initialize(File* file) {
00107 m_file = file;
00108
00109
00110 static bool initialized = false;
00111 if (!initialized) {
00112 ADR_GUARD("Initializing MikMod");
00113
00114 Mikmod_RegisterLoader(load_it);
00115 Mikmod_RegisterLoader(load_xm);
00116 Mikmod_RegisterLoader(load_s3m);
00117 Mikmod_RegisterLoader(load_mod);
00118 Mikmod_RegisterLoader(load_stm);
00119
00120 Mikmod_RegisterDriver(drv_audiere);
00121
00122 initialized = true;
00123 }
00124
00125 m_stream.fp = (FILE*)this;
00126 m_stream.dp = 0;
00127 m_stream.iobase = 0;
00128 m_stream.seekpos = 0;
00129 m_stream.fread = MMRead;
00130 m_stream.fwrite = MMWrite;
00131 m_stream.fgetc = MMGetC;
00132 m_stream.fputc = MMPutC;
00133 m_stream.fseek = MMSeek;
00134 m_stream.ftell = MMTell;
00135 m_stream.feof = MMEof;
00136
00137 m_samples_left = 0;
00138 m_next_sample = m_next_sample;
00139
00140 m_at_eof = false;
00141
00142
00143 m_driver = Mikmod_Init(
00144 44100, 2400, this, MD_STEREO, CPU_AUTODETECT,
00145 DMODE_16BITS | DMODE_INTERP | DMODE_NOCLICK | DMODE_RESONANCE);
00146 if (!m_driver) {
00147 m_file = 0;
00148 return false;
00149 }
00150
00151 ADR_LOG("Mikmod_Init succeeded");
00152
00153
00154 m_module = Unimod_LoadFP(
00155 m_driver,
00156 &m_stream,
00157 &m_stream,
00158 MM_STATIC);
00159 if (!m_module) {
00160 Mikmod_Exit(m_driver);
00161 m_driver = 0;
00162 m_file = 0;
00163 return false;
00164 }
00165
00166 ADR_LOG("Unimod_LoadFP succeeded");
00167
00168
00169 if (SL_LoadSamples(m_driver)) {
00170 Unimod_Free(m_module);
00171 m_module = 0;
00172 Mikmod_Exit(m_driver);
00173 m_driver = 0;
00174 m_file = 0;
00175 return false;
00176 }
00177
00178 ADR_LOG("SL_LoadSamples succeeded");
00179
00180
00181 m_player = Player_InitSong(m_module, NULL, 0, 64);
00182 if (!m_player) {
00183 Unimod_Free(m_module);
00184 m_module = 0;
00185 Mikmod_Exit(m_driver);
00186 m_driver = 0;
00187 m_file = 0;
00188 return false;
00189 }
00190
00191 ADR_LOG("Player_InitSong succeeded");
00192
00193
00194
00195 Player_Start(m_player);
00196
00197 ADR_LOG("Player_Start succeeded");
00198
00199 return true;
00200 }
00201
00202
00203 void
00204 MODInputStream::getFormat(
00205 int& channel_count,
00206 int& sample_rate,
00207 SampleFormat& sample_format)
00208 {
00209 channel_count = 2;
00210 sample_rate = 44100;
00211 sample_format = SF_S16;
00212 }
00213
00214
00215 int
00216 MODInputStream::read(int frame_count, void* buffer) {
00217 ADR_GUARD("MODInputStream::read");
00218
00219 u32* out = static_cast<u32*>(buffer);
00220
00221 int total_written = 0;
00222 while (frame_count > 0) {
00223
00224
00225 if (m_samples_left == 0) {
00226
00227
00228 if (!Player_Active(m_player)) {
00229 break;
00230 }
00231
00232 Mikmod_Update(m_driver);
00233 }
00234
00235
00236 u32 samples_to_read = std::min<u32>(
00237 frame_count,
00238 m_samples_left);
00239 memcpy(out, m_next_sample, samples_to_read * 4);
00240
00241
00242 out += samples_to_read;
00243 m_next_sample += samples_to_read;
00244 m_samples_left -= samples_to_read;
00245 frame_count -= samples_to_read;
00246 total_written += samples_to_read;
00247 }
00248
00249 return total_written;
00250 }
00251
00252
00253 void
00254 MODInputStream::reset() {
00255 ADR_GUARD("MOD_Reset");
00256
00257 m_samples_left = 0;
00258 m_next_sample = m_sample_buffer;
00259
00260 Player_Stop(m_player);
00261 Player_Start(m_player);
00262 }
00263
00264
00265 BOOL
00266 MODInputStream::ADR_IsThere() {
00267 return 1;
00268 }
00269
00270
00271 BOOL
00272 MODInputStream::ADR_Init(MDRIVER* md, uint latency, void* optstr) {
00273 ADR_GUARD("ADR_Init");
00274
00275 md->device.vc = VC_Init();
00276 if (!md->device.vc) {
00277 return 1;
00278 }
00279
00280 md->device.local = optstr;
00281 return 0;
00282 }
00283
00284
00285 void
00286 MODInputStream::ADR_Exit(MDRIVER* md) {
00287 ADR_GUARD("ADR_Exit");
00288
00289 VC_Exit(md->device.vc);
00290 }
00291
00292
00293 void
00294 MODInputStream::ADR_Update(MDRIVER* md) {
00295 ADR_GUARD("ADR_Update");
00296
00297 MODInputStream* stream = reinterpret_cast<MODInputStream*>(md->device.local);
00298
00299
00300 if (stream->m_samples_left != 0) {
00301 return;
00302 }
00303
00304 VC_WriteBytes(
00305 md,
00306 (signed char*)stream->m_sample_buffer,
00307 SAMPLE_BUFFER_SIZE * sizeof(u32));
00308 stream->m_samples_left = SAMPLE_BUFFER_SIZE;
00309 stream->m_next_sample = stream->m_sample_buffer;
00310 }
00311
00312
00313 BOOL
00314 MODInputStream::ADR_SetSoftVoices(MDRIVER* md, uint voices) {
00315 return VC_SetSoftVoices(md->device.vc, voices);
00316 }
00317
00318
00319 BOOL
00320 MODInputStream::ADR_SetMode(
00321 MDRIVER* md, uint mixspeed, uint mode,
00322 uint channels, uint cpumode)
00323 {
00324 return VC_SetMode(md->device.vc, mixspeed, mode, channels, cpumode);
00325 }
00326
00327
00328 void
00329 MODInputStream::ADR_GetMode(
00330 MDRIVER* md, uint* mixspeed, uint* mode,
00331 uint* channels, uint* cpumode)
00332 {
00333 VC_GetMode(md->device.vc, mixspeed, mode, channels, cpumode);
00334 }
00335
00336
00337 int CRT_CALL
00338 MODInputStream::MMRead(
00339 void* buffer, size_t size, size_t count, FILE* stream)
00340 {
00341 MODInputStream* istream = reinterpret_cast<MODInputStream*>(stream);
00342 int result = istream->m_file->read(buffer, size * count) / size;
00343 if (result == 0) {
00344 istream->m_at_eof = true;
00345 }
00346 return result;
00347 }
00348
00349
00350 int CRT_CALL
00351 MODInputStream::MMWrite(
00352 const void* buffer, size_t size, size_t count, FILE* stream)
00353 {
00354
00355 return -1;
00356 }
00357
00358
00359 int CRT_CALL
00360 MODInputStream::MMGetC(FILE* stream) {
00361 unsigned char c;
00362 if (MMRead(&c, 1, 1, stream) == 1) {
00363 return c;
00364 } else {
00365 return EOF;
00366 }
00367 }
00368
00369
00370 int CRT_CALL
00371 MODInputStream::MMPutC(int c, FILE* stream) {
00372 char ch = (char)c;
00373 return MMWrite(&ch, 1, 1, stream);
00374 }
00375
00376
00377 int CRT_CALL
00378 MODInputStream::MMSeek(FILE* stream, long offset, int origin) {
00379 MODInputStream* istream = reinterpret_cast<MODInputStream*>(stream);
00380 File* file = istream->m_file.get();
00381
00382 File::SeekMode seek_mode;
00383 switch (origin) {
00384 case SEEK_SET: seek_mode = File::BEGIN; break;
00385 case SEEK_CUR: seek_mode = File::CURRENT; break;
00386 case SEEK_END: seek_mode = File::END; break;
00387 default: return -1;
00388 }
00389
00390 return file->seek(offset, seek_mode) ? 0 : -1;
00391 }
00392
00393
00394 int CRT_CALL
00395 MODInputStream::MMTell(FILE* stream) {
00396 MODInputStream* istream = reinterpret_cast<MODInputStream*>(stream);
00397 File* file = istream->m_file.get();
00398 return file->tell();
00399 }
00400
00401
00402 int CRT_CALL
00403 MODInputStream::MMEof(FILE* stream) {
00404 MODInputStream* istream = reinterpret_cast<MODInputStream*>(stream);
00405 return istream->m_at_eof ? 1 : 0;
00406 }
00407
00408 }