Mercurial > audlegacy-plugins
comparison src/modplug/modplugbmp.cxx @ 12:3da1b8942b8b trunk
[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 03:14:20 -0700 |
parents | src/Input/modplug/modplugbmp.cxx@088092a52fea |
children | db47d5ac8f43 |
comparison
equal
deleted
inserted
replaced
11:cff1d04026ae | 12:3da1b8942b8b |
---|---|
1 /* Modplug XMMS Plugin | |
2 * Authors: Kenton Varda <temporal@gauge3d.org> | |
3 * | |
4 * This source code is public domain. | |
5 */ | |
6 | |
7 #include <fstream> | |
8 #include <unistd.h> | |
9 #include <math.h> | |
10 | |
11 #include "modplugbmp.h" | |
12 #include <libmodplug/stdafx.h> | |
13 #include <libmodplug/sndfile.h> | |
14 #include "stddefs.h" | |
15 #include "archive/open.h" | |
16 #include "audacious/configdb.h" | |
17 #include "audacious/vfs.h" | |
18 extern "C" { | |
19 #include "audacious/output.h" | |
20 } | |
21 | |
22 // ModplugXMMS member functions =============================== | |
23 | |
24 // operations ---------------------------------------- | |
25 ModplugXMMS::ModplugXMMS() | |
26 { | |
27 mSoundFile = new CSoundFile; | |
28 } | |
29 ModplugXMMS::~ModplugXMMS() | |
30 { | |
31 delete mSoundFile; | |
32 } | |
33 | |
34 ModplugXMMS::Settings::Settings() | |
35 { | |
36 mSurround = true; | |
37 mOversamp = true; | |
38 mReverb = false; | |
39 mMegabass = false; | |
40 mNoiseReduction = true; | |
41 mVolumeRamp = true; | |
42 mFastinfo = true; | |
43 mUseFilename = false; | |
44 mGrabAmigaMOD = true; | |
45 | |
46 mChannels = 2; | |
47 mFrequency = 44100; | |
48 mBits = 16; | |
49 mResamplingMode = SRCMODE_POLYPHASE; | |
50 | |
51 mReverbDepth = 30; | |
52 mReverbDelay = 100; | |
53 mBassAmount = 40; | |
54 mBassRange = 30; | |
55 mSurroundDepth = 20; | |
56 mSurroundDelay = 20; | |
57 | |
58 mPreamp = false; | |
59 mPreampLevel = 0.0f; | |
60 | |
61 mLoopCount = 0; //don't loop | |
62 } | |
63 | |
64 void ModplugXMMS::Init(void) | |
65 { | |
66 ConfigDb *db; | |
67 | |
68 db = bmp_cfg_db_open(); | |
69 | |
70 bmp_cfg_db_get_bool(db,"modplug","Surround", &mModProps.mSurround); | |
71 bmp_cfg_db_get_bool(db,"modplug","Oversampling", &mModProps.mOversamp); | |
72 bmp_cfg_db_get_bool(db,"modplug","Megabass", &mModProps.mMegabass); | |
73 bmp_cfg_db_get_bool(db,"modplug","NoiseReduction", &mModProps.mNoiseReduction); | |
74 bmp_cfg_db_get_bool(db,"modplug","VolumeRamp", &mModProps.mVolumeRamp); | |
75 bmp_cfg_db_get_bool(db,"modplug","Reverb", &mModProps.mReverb); | |
76 bmp_cfg_db_get_bool(db,"modplug","FastInfo", &mModProps.mFastinfo); | |
77 bmp_cfg_db_get_bool(db,"modplug","UseFileName", &mModProps.mUseFilename); | |
78 bmp_cfg_db_get_bool(db,"modplug","GrabAmigaMOD", &mModProps.mGrabAmigaMOD); | |
79 bmp_cfg_db_get_bool(db,"modplug","PreAmp", &mModProps.mPreamp); | |
80 bmp_cfg_db_get_float(db,"modplug","PreAmpLevel", &mModProps.mPreampLevel); | |
81 bmp_cfg_db_get_int(db,"modplug", "Channels", &mModProps.mChannels); | |
82 bmp_cfg_db_get_int(db,"modplug", "Bits", &mModProps.mBits); | |
83 bmp_cfg_db_get_int(db,"modplug", "Frequency", &mModProps.mFrequency); | |
84 bmp_cfg_db_get_int(db,"modplug", "ResamplineMode", &mModProps.mResamplingMode); | |
85 bmp_cfg_db_get_int(db,"modplug", "ReverbDepth", &mModProps.mReverbDepth); | |
86 bmp_cfg_db_get_int(db,"modplug", "ReverbDelay", &mModProps.mReverbDelay); | |
87 bmp_cfg_db_get_int(db,"modplug", "BassAmount", &mModProps.mBassAmount); | |
88 bmp_cfg_db_get_int(db,"modplug", "BassRange", &mModProps.mBassRange); | |
89 bmp_cfg_db_get_int(db,"modplug", "SurroundDepth", &mModProps.mSurroundDepth); | |
90 bmp_cfg_db_get_int(db,"modplug", "SurroundDelay", &mModProps.mSurroundDelay); | |
91 bmp_cfg_db_get_int(db,"modplug", "LoopCount", &mModProps.mLoopCount); | |
92 | |
93 bmp_cfg_db_close(db); | |
94 } | |
95 | |
96 bool ModplugXMMS::CanPlayFile(const string& aFilename) | |
97 { | |
98 string lExt; | |
99 uint32 lPos; | |
100 | |
101 VFSFile *file; | |
102 gchar magic[4]; | |
103 | |
104 if ((file = vfs_fopen(aFilename.c_str(), "rb"))) { | |
105 vfs_fread(magic, 1, 4, file); | |
106 if (!memcmp(magic, UMX_MAGIC, 4)) { | |
107 vfs_fclose(file); | |
108 return 1; | |
109 } | |
110 if (!memcmp(magic, XM_MAGIC, 4)) { | |
111 vfs_fclose(file); | |
112 return 1; | |
113 } | |
114 if (!memcmp(magic, M669_MAGIC, 4)) { | |
115 vfs_fclose(file); | |
116 return 1; | |
117 } | |
118 if (!memcmp(magic, IT_MAGIC, 4)) { | |
119 vfs_fclose(file); | |
120 return 1; | |
121 } | |
122 if (!memcmp(magic, MTM_MAGIC, 4)) { | |
123 vfs_fclose(file); | |
124 return 1; | |
125 } | |
126 if (!memcmp(magic, PSM_MAGIC, 4)) { | |
127 vfs_fclose(file); | |
128 return 1; | |
129 } | |
130 vfs_fseek(file, 44, SEEK_SET); | |
131 vfs_fread(magic, 1, 4, file); | |
132 if (!memcmp(magic, S3M_MAGIC, 4)) { | |
133 vfs_fclose(file); | |
134 return 1; | |
135 } | |
136 if(mModProps.mGrabAmigaMOD) { | |
137 vfs_fseek(file, 1080, SEEK_SET); | |
138 vfs_fread(magic, 1, 4, file); | |
139 if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4)) { | |
140 vfs_fclose(file); | |
141 return 1; | |
142 } | |
143 if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4)) { | |
144 vfs_fclose(file); | |
145 return 1; | |
146 } | |
147 if (!memcmp(magic, MOD_MAGIC_NOISETRACKER, 4)) { | |
148 vfs_fclose(file); | |
149 return 1; | |
150 } | |
151 if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4)) { | |
152 vfs_fclose(file); | |
153 return 1; | |
154 } | |
155 if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4)) { | |
156 vfs_fclose(file); | |
157 return 1; | |
158 } | |
159 if (!memcmp(magic, MOD_MAGIC_STARTRACKER4X, 4)) { | |
160 vfs_fclose(file); | |
161 return 1; | |
162 } | |
163 if (!memcmp(magic, MOD_MAGIC_STARTRACKER8X, 4)) { | |
164 vfs_fclose(file); | |
165 return 1; | |
166 } | |
167 if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4)) { | |
168 vfs_fclose(file); | |
169 return 1; | |
170 } | |
171 if (!memcmp(magic, MOD_MAGIC_FASTTRACKER6, 4)) { | |
172 vfs_fclose(file); | |
173 return 1; | |
174 } | |
175 if (!memcmp(magic, MOD_MAGIC_FASTTRACKER8, 4)) { | |
176 vfs_fclose(file); | |
177 return 1; | |
178 } | |
179 if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4)) { | |
180 vfs_fclose(file); | |
181 return 1; | |
182 } | |
183 if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4)) { | |
184 vfs_fclose(file); | |
185 return 1; | |
186 } | |
187 if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4)) { | |
188 vfs_fclose(file); | |
189 return 1; | |
190 } | |
191 if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4)) { | |
192 vfs_fclose(file); | |
193 return 1; | |
194 } | |
195 } /* end of if(mModProps.mGrabAmigaMOD) */ | |
196 | |
197 /* We didn't find the magic bytes, fall back to extension check */ | |
198 vfs_fclose(file); | |
199 } /* end of vfs_open main if statement */ | |
200 | |
201 lPos = aFilename.find_last_of('.'); | |
202 if((int)lPos == -1) | |
203 return false; | |
204 lExt = aFilename.substr(lPos); | |
205 for(uint32 i = 0; i < lExt.length(); i++) | |
206 lExt[i] = tolower(lExt[i]); | |
207 | |
208 if (lExt == ".amf") | |
209 return true; | |
210 if (lExt == ".ams") | |
211 return true; | |
212 if (lExt == ".dbm") | |
213 return true; | |
214 if (lExt == ".dbf") | |
215 return true; | |
216 if (lExt == ".dsm") | |
217 return true; | |
218 if (lExt == ".far") | |
219 return true; | |
220 if (lExt == ".mdl") | |
221 return true; | |
222 if (lExt == ".stm") | |
223 return true; | |
224 if (lExt == ".ult") | |
225 return true; | |
226 if (lExt == ".j2b") | |
227 return true; | |
228 if (lExt == ".mt2") | |
229 return true; | |
230 | |
231 if (lExt == ".mdz") | |
232 return true; | |
233 if (lExt == ".mdr") | |
234 return true; | |
235 if (lExt == ".mdgz") | |
236 return true; | |
237 if (lExt == ".mdbz") | |
238 return true; | |
239 if (lExt == ".s3z") | |
240 return true; | |
241 if (lExt == ".s3r") | |
242 return true; | |
243 if (lExt == ".s3gz") | |
244 return true; | |
245 if (lExt == ".xmz") | |
246 return true; | |
247 if (lExt == ".xmr") | |
248 return true; | |
249 if (lExt == ".xmgz") | |
250 return true; | |
251 if (lExt == ".itz") | |
252 return true; | |
253 if (lExt == ".itr") | |
254 return true; | |
255 if (lExt == ".itgz") | |
256 return true; | |
257 if (lExt == ".dmf") | |
258 return true; | |
259 | |
260 if (lExt == ".zip") | |
261 return ContainsMod(aFilename); | |
262 if (lExt == ".gz") | |
263 return ContainsMod(aFilename); | |
264 if (lExt == ".bz2") | |
265 return ContainsMod(aFilename); | |
266 | |
267 return false; | |
268 } | |
269 | |
270 void* ModplugXMMS::PlayThread(void* arg) | |
271 { | |
272 ((ModplugXMMS*)arg)->PlayLoop(); | |
273 return NULL; | |
274 } | |
275 | |
276 void ModplugXMMS::PlayLoop() | |
277 { | |
278 uint32 lLength; | |
279 //the user might change the number of channels while playing. | |
280 // we don't want this to take effect until we are done! | |
281 uint8 lChannels = mModProps.mChannels; | |
282 | |
283 while(!mStopped) | |
284 { | |
285 if(!(lLength = mSoundFile->Read( | |
286 mBuffer, | |
287 mBufSize))) | |
288 { | |
289 //no more to play. Wait for output to finish and then stop. | |
290 while((mOutPlug->buffer_playing()) | |
291 && (!mStopped)) | |
292 usleep(10000); | |
293 break; | |
294 } | |
295 | |
296 if(mModProps.mPreamp) | |
297 { | |
298 //apply preamp | |
299 if(mModProps.mBits == 16) | |
300 { | |
301 uint n = mBufSize >> 1; | |
302 for(uint i = 0; i < n; i++) { | |
303 short old = ((short*)mBuffer)[i]; | |
304 ((short*)mBuffer)[i] *= (short int)mPreampFactor; | |
305 // detect overflow and clip! | |
306 if ((old & 0x8000) != | |
307 (((short*)mBuffer)[i] & 0x8000)) | |
308 ((short*)mBuffer)[i] = old | 0x7FFF; | |
309 | |
310 } | |
311 } | |
312 else | |
313 { | |
314 for(uint i = 0; i < mBufSize; i++) { | |
315 uchar old = ((uchar*)mBuffer)[i]; | |
316 ((uchar*)mBuffer)[i] *= (short int)mPreampFactor; | |
317 // detect overflow and clip! | |
318 if ((old & 0x80) != | |
319 (((uchar*)mBuffer)[i] & 0x80)) | |
320 ((uchar*)mBuffer)[i] = old | 0x7F; | |
321 } | |
322 } | |
323 } | |
324 | |
325 if(mStopped) | |
326 break; | |
327 | |
328 //wait for buffer space to free up. | |
329 while(((mOutPlug->buffer_free() | |
330 < (int)mBufSize)) | |
331 && (!mStopped)) | |
332 usleep(10000); | |
333 | |
334 if(mStopped) | |
335 break; | |
336 | |
337 produce_audio | |
338 ( | |
339 mPlayed, | |
340 mFormat, | |
341 lChannels, | |
342 mBufSize, | |
343 mBuffer, | |
344 NULL | |
345 ); | |
346 | |
347 mPlayed += mBufTime; | |
348 } | |
349 | |
350 // mOutPlug->flush(0); | |
351 mOutPlug->close_audio(); | |
352 | |
353 //Unload the file | |
354 mSoundFile->Destroy(); | |
355 delete mArchive; | |
356 | |
357 if (mBuffer) | |
358 { | |
359 delete [] mBuffer; | |
360 mBuffer = NULL; | |
361 } | |
362 | |
363 mPaused = false; | |
364 mStopped = true; | |
365 | |
366 g_thread_exit(NULL); | |
367 } | |
368 | |
369 void ModplugXMMS::PlayFile(const string& aFilename) | |
370 { | |
371 mStopped = true; | |
372 mPaused = false; | |
373 | |
374 //open and mmap the file | |
375 mArchive = OpenArchive(aFilename); | |
376 if(mArchive->Size() == 0) | |
377 { | |
378 delete mArchive; | |
379 return; | |
380 } | |
381 | |
382 if (mBuffer) | |
383 delete [] mBuffer; | |
384 | |
385 //find buftime to get approx. 512 samples/block | |
386 mBufTime = 512000 / mModProps.mFrequency + 1; | |
387 | |
388 mBufSize = mBufTime; | |
389 mBufSize *= mModProps.mFrequency; | |
390 mBufSize /= 1000; //milliseconds | |
391 mBufSize *= mModProps.mChannels; | |
392 mBufSize *= mModProps.mBits / 8; | |
393 | |
394 mBuffer = new uchar[mBufSize]; | |
395 if(!mBuffer) | |
396 return; //out of memory! | |
397 | |
398 CSoundFile::SetWaveConfig | |
399 ( | |
400 mModProps.mFrequency, | |
401 mModProps.mBits, | |
402 mModProps.mChannels | |
403 ); | |
404 CSoundFile::SetWaveConfigEx | |
405 ( | |
406 mModProps.mSurround, | |
407 !mModProps.mOversamp, | |
408 mModProps.mReverb, | |
409 true, | |
410 mModProps.mMegabass, | |
411 mModProps.mNoiseReduction, | |
412 false | |
413 ); | |
414 | |
415 // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms] | |
416 if(mModProps.mReverb) | |
417 { | |
418 CSoundFile::SetReverbParameters | |
419 ( | |
420 mModProps.mReverbDepth, | |
421 mModProps.mReverbDelay | |
422 ); | |
423 } | |
424 // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100] | |
425 if(mModProps.mMegabass) | |
426 { | |
427 CSoundFile::SetXBassParameters | |
428 ( | |
429 mModProps.mBassAmount, | |
430 mModProps.mBassRange | |
431 ); | |
432 } | |
433 // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms] | |
434 if(mModProps.mSurround) | |
435 { | |
436 CSoundFile::SetSurroundParameters | |
437 ( | |
438 mModProps.mSurroundDepth, | |
439 mModProps.mSurroundDelay | |
440 ); | |
441 } | |
442 CSoundFile::SetResamplingMode(mModProps.mResamplingMode); | |
443 mSoundFile->SetRepeatCount(mModProps.mLoopCount); | |
444 mPreampFactor = exp(mModProps.mPreampLevel); | |
445 | |
446 mPaused = false; | |
447 mStopped = false; | |
448 | |
449 mSoundFile->Create | |
450 ( | |
451 (uchar*)mArchive->Map(), | |
452 mArchive->Size() | |
453 ); | |
454 mPlayed = 0; | |
455 | |
456 bool useFilename = mModProps.mUseFilename; | |
457 | |
458 if(!useFilename) | |
459 { | |
460 strncpy(mModName, mSoundFile->GetTitle(), 100); | |
461 | |
462 for(int i = 0; mModName[i] == ' ' || mModName[i] == 0; i++) | |
463 { | |
464 if(mModName[i] == 0) | |
465 { | |
466 useFilename = true; //mod name is blank -- use filename | |
467 break; | |
468 } | |
469 } | |
470 } | |
471 | |
472 if(useFilename) | |
473 { | |
474 strncpy(mModName, strrchr(aFilename.c_str(), '/') + 1, 100); | |
475 char* ext = strrchr(mModName, '.'); | |
476 if(ext) *ext = '\0'; | |
477 } | |
478 | |
479 mInPlug->set_info | |
480 ( | |
481 mModName, | |
482 mSoundFile->GetSongTime() * 1000, | |
483 mSoundFile->GetNumChannels() * 1000, | |
484 mModProps.mFrequency, | |
485 mModProps.mChannels | |
486 ); | |
487 | |
488 mStopped = mPaused = false; | |
489 | |
490 if(mModProps.mBits == 16) | |
491 mFormat = FMT_S16_NE; | |
492 else | |
493 mFormat = FMT_U8; | |
494 | |
495 mOutPlug->open_audio | |
496 ( | |
497 mFormat, | |
498 mModProps.mFrequency, | |
499 mModProps.mChannels | |
500 ); | |
501 | |
502 mDecodeThread = g_thread_create( | |
503 (GThreadFunc)PlayThread, | |
504 this, | |
505 TRUE, | |
506 NULL | |
507 ); | |
508 } | |
509 | |
510 void ModplugXMMS::Stop(void) | |
511 { | |
512 if(mStopped) | |
513 return; | |
514 | |
515 mStopped = true; | |
516 mPaused = false; | |
517 | |
518 g_thread_join(mDecodeThread); | |
519 } | |
520 | |
521 void ModplugXMMS::Pause(bool aPaused) | |
522 { | |
523 if(aPaused) | |
524 mPaused = true; | |
525 else | |
526 mPaused = false; | |
527 | |
528 mOutPlug->pause(aPaused); | |
529 } | |
530 | |
531 void ModplugXMMS::Seek(float32 aTime) | |
532 { | |
533 uint32 lMax; | |
534 uint32 lMaxtime; | |
535 float32 lPostime; | |
536 | |
537 if(aTime > (lMaxtime = mSoundFile->GetSongTime())) | |
538 aTime = lMaxtime; | |
539 lMax = mSoundFile->GetMaxPosition(); | |
540 lPostime = float(lMax) / lMaxtime; | |
541 | |
542 mSoundFile->SetCurrentPos(int(aTime * lPostime)); | |
543 | |
544 mOutPlug->flush(int(aTime * 1000)); | |
545 mPlayed = uint32(aTime * 1000); | |
546 } | |
547 | |
548 float32 ModplugXMMS::GetTime(void) | |
549 { | |
550 if(mStopped) | |
551 return -1; | |
552 return (float32)mOutPlug->output_time() / 1000; | |
553 } | |
554 | |
555 void ModplugXMMS::GetSongInfo(const string& aFilename, char*& aTitle, int32& aLength) | |
556 { | |
557 aLength = -1; | |
558 fstream lTestFile; | |
559 string lError; | |
560 bool lDone; | |
561 | |
562 lTestFile.open(aFilename.c_str(), ios::in); | |
563 if(!lTestFile) | |
564 { | |
565 lError = "**no such file: "; | |
566 lError += strrchr(aFilename.c_str(), '/') + 1; | |
567 aTitle = new char[lError.length() + 1]; | |
568 strcpy(aTitle, lError.c_str()); | |
569 return; | |
570 } | |
571 | |
572 lTestFile.close(); | |
573 | |
574 if(mModProps.mFastinfo) | |
575 { | |
576 if(mModProps.mUseFilename) | |
577 { | |
578 //Use filename as name | |
579 aTitle = new char[aFilename.length() + 1]; | |
580 strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1); | |
581 *strrchr(aTitle, '.') = '\0'; | |
582 return; | |
583 } | |
584 | |
585 fstream lModFile; | |
586 string lExt; | |
587 uint32 lPos; | |
588 | |
589 lDone = true; | |
590 | |
591 // previously ios::nocreate was used (X Standard C++ Library) | |
592 lModFile.open(aFilename.c_str(), ios::in); | |
593 | |
594 lPos = aFilename.find_last_of('.'); | |
595 if((int)lPos == 0) | |
596 return; | |
597 lExt = aFilename.substr(lPos); | |
598 for(uint32 i = 0; i < lExt.length(); i++) | |
599 lExt[i] = tolower(lExt[i]); | |
600 | |
601 if (lExt == ".mod") | |
602 { | |
603 lModFile.read(mModName, 20); | |
604 mModName[20] = 0; | |
605 } | |
606 else if (lExt == ".s3m") | |
607 { | |
608 lModFile.read(mModName, 28); | |
609 mModName[28] = 0; | |
610 } | |
611 else if (lExt == ".xm") | |
612 { | |
613 lModFile.seekg(17); | |
614 lModFile.read(mModName, 20); | |
615 mModName[20] = 0; | |
616 } | |
617 else if (lExt == ".it") | |
618 { | |
619 lModFile.seekg(4); | |
620 lModFile.read(mModName, 28); | |
621 mModName[28] = 0; | |
622 } | |
623 else | |
624 lDone = false; //fall back to slow info | |
625 | |
626 lModFile.close(); | |
627 | |
628 if(lDone) | |
629 { | |
630 for(int i = 0; mModName[i] != 0; i++) | |
631 { | |
632 if(mModName[i] != ' ') | |
633 { | |
634 aTitle = new char[strlen(mModName) + 1]; | |
635 strcpy(aTitle, mModName); | |
636 | |
637 return; | |
638 } | |
639 } | |
640 | |
641 //mod name is blank. Use filename instead. | |
642 aTitle = new char[aFilename.length() + 1]; | |
643 strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1); | |
644 *strrchr(aTitle, '.') = '\0'; | |
645 return; | |
646 } | |
647 } | |
648 | |
649 Archive* lArchive; | |
650 CSoundFile* lSoundFile; | |
651 const char* lTitle; | |
652 | |
653 //open and mmap the file | |
654 lArchive = OpenArchive(aFilename); | |
655 if(lArchive->Size() == 0) | |
656 { | |
657 lError = "**bad mod file: "; | |
658 lError += strrchr(aFilename.c_str(), '/') + 1; | |
659 aTitle = new char[lError.length() + 1]; | |
660 strcpy(aTitle, lError.c_str()); | |
661 delete lArchive; | |
662 return; | |
663 } | |
664 | |
665 lSoundFile = new CSoundFile; | |
666 lSoundFile->Create((uchar*)lArchive->Map(), lArchive->Size()); | |
667 | |
668 if(!mModProps.mUseFilename) | |
669 { | |
670 lTitle = lSoundFile->GetTitle(); | |
671 | |
672 for(int i = 0; lTitle[i] != 0; i++) | |
673 { | |
674 if(lTitle[i] != ' ') | |
675 { | |
676 aTitle = new char[strlen(lTitle) + 1]; | |
677 strcpy(aTitle, lTitle); | |
678 goto therest; //sorry | |
679 } | |
680 } | |
681 } | |
682 | |
683 //mod name is blank, or user wants the filename to be used as the title. | |
684 aTitle = new char[aFilename.length() + 1]; | |
685 strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1); | |
686 *strrchr(aTitle, '.') = '\0'; | |
687 | |
688 therest: | |
689 aLength = lSoundFile->GetSongTime() * 1000; //It wants milliseconds!?! | |
690 | |
691 //unload the file | |
692 lSoundFile->Destroy(); | |
693 delete lSoundFile; | |
694 delete lArchive; | |
695 } | |
696 | |
697 void ModplugXMMS::SetInputPlugin(InputPlugin& aInPlugin) | |
698 { | |
699 mInPlug = &aInPlugin; | |
700 } | |
701 void ModplugXMMS::SetOutputPlugin(OutputPlugin& aOutPlugin) | |
702 { | |
703 mOutPlug = &aOutPlugin; | |
704 } | |
705 | |
706 const ModplugXMMS::Settings& ModplugXMMS::GetModProps() | |
707 { | |
708 return mModProps; | |
709 } | |
710 | |
711 const char* ModplugXMMS::Bool2OnOff(bool aValue) | |
712 { | |
713 if(aValue) | |
714 return "on"; | |
715 else | |
716 return "off"; | |
717 } | |
718 | |
719 void ModplugXMMS::SetModProps(const Settings& aModProps) | |
720 { | |
721 ConfigDb *db; | |
722 mModProps = aModProps; | |
723 | |
724 // [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms] | |
725 if(mModProps.mReverb) | |
726 { | |
727 CSoundFile::SetReverbParameters | |
728 ( | |
729 mModProps.mReverbDepth, | |
730 mModProps.mReverbDelay | |
731 ); | |
732 } | |
733 // [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100] | |
734 if(mModProps.mMegabass) | |
735 { | |
736 CSoundFile::SetXBassParameters | |
737 ( | |
738 mModProps.mBassAmount, | |
739 mModProps.mBassRange | |
740 ); | |
741 } | |
742 else //modplug seems to ignore the SetWaveConfigEx() setting for bass boost | |
743 { | |
744 CSoundFile::SetXBassParameters | |
745 ( | |
746 0, | |
747 0 | |
748 ); | |
749 } | |
750 // [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms] | |
751 if(mModProps.mSurround) | |
752 { | |
753 CSoundFile::SetSurroundParameters | |
754 ( | |
755 mModProps.mSurroundDepth, | |
756 mModProps.mSurroundDelay | |
757 ); | |
758 } | |
759 CSoundFile::SetWaveConfigEx | |
760 ( | |
761 mModProps.mSurround, | |
762 !mModProps.mOversamp, | |
763 mModProps.mReverb, | |
764 true, | |
765 mModProps.mMegabass, | |
766 mModProps.mNoiseReduction, | |
767 false | |
768 ); | |
769 CSoundFile::SetResamplingMode(mModProps.mResamplingMode); | |
770 mPreampFactor = exp(mModProps.mPreampLevel); | |
771 | |
772 db = bmp_cfg_db_open(); | |
773 | |
774 bmp_cfg_db_set_bool(db,"modplug","Surround", mModProps.mSurround); | |
775 bmp_cfg_db_set_bool(db,"modplug","Oversampling", mModProps.mOversamp); | |
776 bmp_cfg_db_set_bool(db,"modplug","Megabass", mModProps.mMegabass); | |
777 bmp_cfg_db_set_bool(db,"modplug","NoiseReduction", mModProps.mNoiseReduction); | |
778 bmp_cfg_db_set_bool(db,"modplug","VolumeRamp", mModProps.mVolumeRamp); | |
779 bmp_cfg_db_set_bool(db,"modplug","Reverb", mModProps.mReverb); | |
780 bmp_cfg_db_set_bool(db,"modplug","FastInfo", mModProps.mFastinfo); | |
781 bmp_cfg_db_set_bool(db,"modplug","UseFileName", mModProps.mUseFilename); | |
782 bmp_cfg_db_set_bool(db,"modplug","GrabAmigaMOD", mModProps.mGrabAmigaMOD); | |
783 bmp_cfg_db_set_bool(db,"modplug","PreAmp", mModProps.mPreamp); | |
784 bmp_cfg_db_set_float(db,"modplug","PreAmpLevel", mModProps.mPreampLevel); | |
785 bmp_cfg_db_set_int(db,"modplug", "Channels", mModProps.mChannels); | |
786 bmp_cfg_db_set_int(db,"modplug", "Bits", mModProps.mBits); | |
787 bmp_cfg_db_set_int(db,"modplug", "Frequency", mModProps.mFrequency); | |
788 bmp_cfg_db_set_int(db,"modplug", "ResamplineMode", mModProps.mResamplingMode); | |
789 bmp_cfg_db_set_int(db,"modplug", "ReverbDepth", mModProps.mReverbDepth); | |
790 bmp_cfg_db_set_int(db,"modplug", "ReverbDelay", mModProps.mReverbDelay); | |
791 bmp_cfg_db_set_int(db,"modplug", "BassAmount", mModProps.mBassAmount); | |
792 bmp_cfg_db_set_int(db,"modplug", "BassRange", mModProps.mBassRange); | |
793 bmp_cfg_db_set_int(db,"modplug", "SurroundDepth", mModProps.mSurroundDepth); | |
794 bmp_cfg_db_set_int(db,"modplug", "SurroundDelay", mModProps.mSurroundDelay); | |
795 bmp_cfg_db_set_int(db,"modplug", "LoopCount", mModProps.mLoopCount); | |
796 | |
797 bmp_cfg_db_close(db); | |
798 } | |
799 | |
800 ModplugXMMS gModplugXMMS; |