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