music.c
上传用户:nini_0081
上传日期:2022-07-21
资源大小:2628k
文件大小:29k
源码类别:

多媒体编程

开发平台:

DOS

  1. /*
  2.     SDL_mixer:  An audio mixer library based on the SDL library
  3.     Copyright (C) 1997-2009 Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. /* $Id: music.c 5247 2009-11-14 20:44:30Z slouken $ */
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <assert.h>
  23. #include "SDL_endian.h"
  24. #include "SDL_audio.h"
  25. #include "SDL_timer.h"
  26. #include "SDL_mixer.h"
  27. #ifdef CMD_MUSIC
  28. #include "music_cmd.h"
  29. #endif
  30. #ifdef WAV_MUSIC
  31. #include "wavestream.h"
  32. #endif
  33. #ifdef MOD_MUSIC
  34. #include "music_mod.h"
  35. #endif
  36. #ifdef MID_MUSIC
  37. #  ifdef USE_TIMIDITY_MIDI
  38. #    include "timidity.h"
  39. #  endif
  40. #  ifdef USE_NATIVE_MIDI
  41. #    include "native_midi.h"
  42. #  endif
  43. #  if defined(USE_TIMIDITY_MIDI) && defined(USE_NATIVE_MIDI)
  44. #    define MIDI_ELSE else
  45. #  else
  46. #    define MIDI_ELSE
  47. #  endif
  48. #endif
  49. #ifdef OGG_MUSIC
  50. #include "music_ogg.h"
  51. #endif
  52. #ifdef MP3_MUSIC
  53. #include "dynamic_mp3.h"
  54. #endif
  55. #ifdef MP3_MAD_MUSIC
  56. #include "music_mad.h"
  57. #endif
  58. #ifdef FLAC_MUSIC
  59. #include "music_flac.h"
  60. #endif
  61. #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
  62. static SDL_AudioSpec used_mixer;
  63. #endif
  64. int volatile music_active = 1;
  65. static int volatile music_stopped = 0;
  66. static int music_loops = 0;
  67. static char *music_cmd = NULL;
  68. static Mix_Music * volatile music_playing = NULL;
  69. static int music_volume = MIX_MAX_VOLUME;
  70. struct _Mix_Music {
  71. Mix_MusicType type;
  72. union {
  73. #ifdef CMD_MUSIC
  74. MusicCMD *cmd;
  75. #endif
  76. #ifdef WAV_MUSIC
  77. WAVStream *wave;
  78. #endif
  79. #ifdef MOD_MUSIC
  80. struct MODULE *module;
  81. #endif
  82. #ifdef MID_MUSIC
  83. #ifdef USE_TIMIDITY_MIDI
  84. MidiSong *midi;
  85. #endif
  86. #ifdef USE_NATIVE_MIDI
  87. NativeMidiSong *nativemidi;
  88. #endif
  89. #endif
  90. #ifdef OGG_MUSIC
  91. OGG_music *ogg;
  92. #endif
  93. #ifdef MP3_MUSIC
  94. SMPEG *mp3;
  95. #endif
  96. #ifdef MP3_MAD_MUSIC
  97. mad_data *mp3_mad;
  98. #endif
  99. #ifdef FLAC_MUSIC
  100. FLAC_music *flac;
  101. #endif
  102. } data;
  103. Mix_Fading fading;
  104. int fade_step;
  105. int fade_steps;
  106. int error;
  107. };
  108. #ifdef MID_MUSIC
  109. #ifdef USE_TIMIDITY_MIDI
  110. static int timidity_ok;
  111. static int samplesize;
  112. #endif
  113. #ifdef USE_NATIVE_MIDI
  114. static int native_midi_ok;
  115. #endif
  116. #endif
  117. /* Used to calculate fading steps */
  118. static int ms_per_step;
  119. /* rcg06042009 report available decoders at runtime. */
  120. static const char **music_decoders = NULL;
  121. static int num_decoders = 0;
  122. int Mix_GetNumMusicDecoders(void)
  123. {
  124. return(num_decoders);
  125. }
  126. const char *Mix_GetMusicDecoder(int index)
  127. {
  128. if ((index < 0) || (index >= num_decoders)) {
  129. return NULL;
  130. }
  131. return(music_decoders[index]);
  132. }
  133. static void add_music_decoder(const char *decoder)
  134. {
  135. void *ptr = realloc(music_decoders, (num_decoders + 1) * sizeof (const char **));
  136. if (ptr == NULL) {
  137. return;  /* oh well, go on without it. */
  138. }
  139. music_decoders = (const char **) ptr;
  140. music_decoders[num_decoders++] = decoder;
  141. }
  142. /* Local low-level functions prototypes */
  143. static void music_internal_initialize_volume(void);
  144. static void music_internal_volume(int volume);
  145. static int  music_internal_play(Mix_Music *music, double position);
  146. static int  music_internal_position(double position);
  147. static int  music_internal_playing();
  148. static void music_internal_halt(void);
  149. /* Support for hooking when the music has finished */
  150. static void (*music_finished_hook)(void) = NULL;
  151. void Mix_HookMusicFinished(void (*music_finished)(void))
  152. {
  153. SDL_LockAudio();
  154. music_finished_hook = music_finished;
  155. SDL_UnlockAudio();
  156. }
  157. /* If music isn't playing, halt it if no looping is required, restart it */
  158. /* otherwhise. NOP if the music is playing */
  159. static int music_halt_or_loop (void)
  160. {
  161. /* Restart music if it has to loop */
  162. if (!music_internal_playing()) 
  163. {
  164. /* Restart music if it has to loop at a high level */
  165. if (music_loops && --music_loops)
  166. {
  167. Mix_Fading current_fade = music_playing->fading;
  168. music_internal_play(music_playing, 0.0);
  169. music_playing->fading = current_fade;
  170. else 
  171. {
  172. music_internal_halt();
  173. if (music_finished_hook)
  174. music_finished_hook();
  175. return 0;
  176. }
  177. }
  178. return 1;
  179. }
  180. /* Mixing function */
  181. void music_mixer(void *udata, Uint8 *stream, int len)
  182. {
  183. int left = 0;
  184. if ( music_playing && music_active ) {
  185. /* Handle fading */
  186. if ( music_playing->fading != MIX_NO_FADING ) {
  187. if ( music_playing->fade_step++ < music_playing->fade_steps ) {
  188. int volume;
  189. int fade_step = music_playing->fade_step;
  190. int fade_steps = music_playing->fade_steps;
  191. if ( music_playing->fading == MIX_FADING_OUT ) {
  192. volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
  193. } else { /* Fading in */
  194. volume = (music_volume * fade_step) / fade_steps;
  195. }
  196. music_internal_volume(volume);
  197. } else {
  198. if ( music_playing->fading == MIX_FADING_OUT ) {
  199. music_internal_halt();
  200. if ( music_finished_hook ) {
  201. music_finished_hook();
  202. }
  203. return;
  204. }
  205. music_playing->fading = MIX_NO_FADING;
  206. }
  207. }
  208. if (music_halt_or_loop() == 0)
  209. return;
  210. switch (music_playing->type) {
  211. #ifdef CMD_MUSIC
  212. case MUS_CMD:
  213. /* The playing is done externally */
  214. break;
  215. #endif
  216. #ifdef WAV_MUSIC
  217. case MUS_WAV:
  218. left = WAVStream_PlaySome(stream, len);
  219. break;
  220. #endif
  221. #ifdef MOD_MUSIC
  222. case MUS_MOD:
  223. left = MOD_playAudio(music_playing->data.module, stream, len);
  224. break;
  225. #endif
  226. #ifdef MID_MUSIC
  227. #ifdef USE_TIMIDITY_MIDI
  228. case MUS_MID:
  229. if ( timidity_ok ) {
  230. int samples = len / samplesize;
  231.    Timidity_PlaySome(stream, samples);
  232. }
  233. break;
  234. #endif
  235. #endif
  236. #ifdef OGG_MUSIC
  237. case MUS_OGG:
  238. left = OGG_playAudio(music_playing->data.ogg, stream, len);
  239. break;
  240. #endif
  241. #ifdef FLAC_MUSIC
  242. case MUS_FLAC:
  243. left = FLAC_playAudio(music_playing->data.flac, stream, len);
  244. break;
  245. #endif
  246. #ifdef MP3_MUSIC
  247. case MUS_MP3:
  248. left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
  249. break;
  250. #endif
  251. #ifdef MP3_MAD_MUSIC
  252. case MUS_MP3_MAD:
  253. left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
  254. break;
  255. #endif
  256. default:
  257. /* Unknown music type?? */
  258. break;
  259. }
  260. }
  261. /* Handle seamless music looping */
  262. if (left > 0 && left < len && music_halt_or_loop()) {
  263. music_mixer(udata, stream+(len-left), left);
  264. }
  265. }
  266. /* Initialize the music players with a certain desired audio format */
  267. int open_music(SDL_AudioSpec *mixer)
  268. {
  269. #ifdef WAV_MUSIC
  270. if ( WAVStream_Init(mixer) == 0 ) {
  271. add_music_decoder("WAVE");
  272. }
  273. #endif
  274. #ifdef MOD_MUSIC
  275. if ( MOD_init(mixer) == 0 ) {
  276. add_music_decoder("MIKMOD");
  277. }
  278. #endif
  279. #ifdef MID_MUSIC
  280. #ifdef USE_TIMIDITY_MIDI
  281. samplesize = mixer->size / mixer->samples;
  282. if ( Timidity_Init(mixer->freq, mixer->format,
  283.                     mixer->channels, mixer->samples) == 0 ) {
  284. timidity_ok = 1;
  285. add_music_decoder("TIMIDITY");
  286. } else {
  287. timidity_ok = 0;
  288. }
  289. #endif
  290. #ifdef USE_NATIVE_MIDI
  291. #ifdef USE_TIMIDITY_MIDI
  292. native_midi_ok = !timidity_ok;
  293. if ( !native_midi_ok ) {
  294. native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
  295. }
  296. if ( native_midi_ok )
  297. #endif
  298. native_midi_ok = native_midi_detect();
  299. if ( native_midi_ok )
  300. add_music_decoder("NATIVEMIDI");
  301. #endif
  302. #endif
  303. #ifdef OGG_MUSIC
  304. if ( OGG_init(mixer) == 0 ) {
  305. add_music_decoder("OGG");
  306. }
  307. #endif
  308. #ifdef FLAC_MUSIC
  309. if ( FLAC_init(mixer) == 0 ) {
  310. add_music_decoder("FLAC");
  311. }
  312. #endif
  313. #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
  314. /* Keep a copy of the mixer */
  315. used_mixer = *mixer;
  316. add_music_decoder("MP3");
  317. #endif
  318. music_playing = NULL;
  319. music_stopped = 0;
  320. Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
  321. /* Calculate the number of ms for each callback */
  322. ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
  323. return(0);
  324. }
  325. /* Portable case-insensitive string compare function */
  326. int MIX_string_equals(const char *str1, const char *str2)
  327. {
  328. while ( *str1 && *str2 ) {
  329. if ( toupper((unsigned char)*str1) !=
  330.      toupper((unsigned char)*str2) )
  331. break;
  332. ++str1;
  333. ++str2;
  334. }
  335. return (!*str1 && !*str2);
  336. }
  337. /* Load a music file */
  338. Mix_Music *Mix_LoadMUS(const char *file)
  339. {
  340. FILE *fp;
  341. char *ext;
  342. Uint8 magic[5], moremagic[9];
  343. Mix_Music *music;
  344. /* Figure out what kind of file this is */
  345. fp = fopen(file, "rb");
  346. if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
  347. if ( fp != NULL ) {
  348. fclose(fp);
  349. }
  350. Mix_SetError("Couldn't read from '%s'", file);
  351. return(NULL);
  352. }
  353. if (!fread(moremagic, 8, 1, fp)) {
  354. Mix_SetError("Couldn't read from '%s'", file);
  355. return(NULL);
  356. }
  357. magic[4] = '';
  358. moremagic[8] = '';
  359. fclose(fp);
  360. /* Figure out the file extension, so we can determine the type */
  361. ext = strrchr(file, '.');
  362. if ( ext ) ++ext; /* skip the dot in the extension */
  363. /* Allocate memory for the music structure */
  364. music = (Mix_Music *)malloc(sizeof(Mix_Music));
  365. if ( music == NULL ) {
  366. Mix_SetError("Out of memory");
  367. return(NULL);
  368. }
  369. music->error = 0;
  370. #ifdef CMD_MUSIC
  371. if ( music_cmd ) {
  372. music->type = MUS_CMD;
  373. music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
  374. if ( music->data.cmd == NULL ) {
  375. music->error = 1;
  376. }
  377. } else
  378. #endif
  379. #ifdef WAV_MUSIC
  380. /* WAVE files have the magic four bytes "RIFF"
  381.    AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
  382.  */
  383. if ( (ext && MIX_string_equals(ext, "WAV")) ||
  384.      ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
  385.      (strcmp((char *)magic, "FORM") == 0) ) {
  386. music->type = MUS_WAV;
  387. music->data.wave = WAVStream_LoadSong(file, (char *)magic);
  388. if ( music->data.wave == NULL ) {
  389.    Mix_SetError("Unable to load WAV file");
  390. music->error = 1;
  391. }
  392. } else
  393. #endif
  394. #ifdef MID_MUSIC
  395. /* MIDI files have the magic four bytes "MThd" */
  396. if ( (ext && MIX_string_equals(ext, "MID")) ||
  397.      (ext && MIX_string_equals(ext, "MIDI")) ||
  398.      strcmp((char *)magic, "MThd") == 0  ||
  399.      ( strcmp((char *)magic, "RIFF") == 0  &&
  400.    strcmp((char *)(moremagic+4), "RMID") == 0 ) ) {
  401. music->type = MUS_MID;
  402. #ifdef USE_NATIVE_MIDI
  403.    if ( native_midi_ok ) {
  404.    music->data.nativemidi = native_midi_loadsong(file);
  405.    if ( music->data.nativemidi == NULL ) {
  406.    Mix_SetError("%s", native_midi_error());
  407.    music->error = 1;
  408. }
  409.    } MIDI_ELSE
  410. #endif
  411. #ifdef USE_TIMIDITY_MIDI
  412. if ( timidity_ok ) {
  413. music->data.midi = Timidity_LoadSong(file);
  414. if ( music->data.midi == NULL ) {
  415. Mix_SetError("%s", Timidity_Error());
  416. music->error = 1;
  417. }
  418. } else {
  419. Mix_SetError("%s", Timidity_Error());
  420. music->error = 1;
  421. }
  422. #endif
  423. } else
  424. #endif
  425. #ifdef OGG_MUSIC
  426. /* Ogg Vorbis files have the magic four bytes "OggS" */
  427. if ( (ext && MIX_string_equals(ext, "OGG")) ||
  428.      strcmp((char *)magic, "OggS") == 0 ) {
  429. music->type = MUS_OGG;
  430. music->data.ogg = OGG_new(file);
  431. if ( music->data.ogg == NULL ) {
  432. music->error = 1;
  433. }
  434. } else
  435. #endif
  436. #ifdef FLAC_MUSIC
  437. /* FLAC files have the magic four bytes "fLaC" */
  438. if ( (ext && MIX_string_equals(ext, "FLAC")) ||
  439.  strcmp((char *)magic, "fLaC") == 0 ) {
  440. music->type = MUS_FLAC;
  441. music->data.flac = FLAC_new(file);
  442. if ( music->data.flac == NULL ) {
  443. music->error = 1;
  444. }
  445. } else
  446. #endif
  447. #ifdef MP3_MUSIC
  448. if ( (ext && MIX_string_equals(ext, "MPG")) ||
  449.      (ext && MIX_string_equals(ext, "MP3")) ||
  450.      (ext && MIX_string_equals(ext, "MPEG")) ||
  451.      (magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
  452.      (strncmp((char *)magic, "ID3", 3) == 0) ) {
  453. if ( Mix_Init(MIX_INIT_MP3) ) {
  454. SMPEG_Info info;
  455. music->type = MUS_MP3;
  456. music->data.mp3 = smpeg.SMPEG_new(file, &info, 0);
  457. if ( !info.has_audio ) {
  458. Mix_SetError("MPEG file does not have any audio stream.");
  459. music->error = 1;
  460. } else {
  461. smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
  462. }
  463. } else {
  464. music->error = 1;
  465. }
  466. } else
  467. #endif
  468. #ifdef MP3_MAD_MUSIC
  469. if ( (ext && MIX_string_equals(ext, "MPG")) ||
  470.      (ext && MIX_string_equals(ext, "MP3")) ||
  471.      (ext && MIX_string_equals(ext, "MPEG")) ||
  472.      (ext && MIX_string_equals(ext, "MAD")) ||
  473.      (magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
  474.      (strncmp((char *)magic, "ID3", 3) == 0) ) {
  475. music->type = MUS_MP3_MAD;
  476. music->data.mp3_mad = mad_openFile(file, &used_mixer);
  477. if (music->data.mp3_mad == 0) {
  478.     Mix_SetError("Could not initialize MPEG stream.");
  479. music->error = 1;
  480. }
  481. } else
  482. #endif
  483. #ifdef MOD_MUSIC
  484. if ( 1 ) {
  485. music->type = MUS_MOD;
  486. music->data.module = MOD_new(file);
  487. if ( music->data.module == NULL ) {
  488. music->error = 1;
  489. }
  490. } else
  491. #endif
  492. {
  493. Mix_SetError("Unrecognized music format");
  494. music->error = 1;
  495. }
  496. if ( music->error ) {
  497. free(music);
  498. music = NULL;
  499. }
  500. return(music);
  501. }
  502. /* Free a music chunk previously loaded */
  503. void Mix_FreeMusic(Mix_Music *music)
  504. {
  505. if ( music ) {
  506. /* Stop the music if it's currently playing */
  507. SDL_LockAudio();
  508. if ( music == music_playing ) {
  509. /* Wait for any fade out to finish */
  510. while ( music->fading == MIX_FADING_OUT ) {
  511. SDL_UnlockAudio();
  512. SDL_Delay(100);
  513. SDL_LockAudio();
  514. }
  515. if ( music == music_playing ) {
  516. music_internal_halt();
  517. }
  518. }
  519. SDL_UnlockAudio();
  520. switch (music->type) {
  521. #ifdef CMD_MUSIC
  522. case MUS_CMD:
  523. MusicCMD_FreeSong(music->data.cmd);
  524. break;
  525. #endif
  526. #ifdef WAV_MUSIC
  527. case MUS_WAV:
  528. WAVStream_FreeSong(music->data.wave);
  529. break;
  530. #endif
  531. #ifdef MOD_MUSIC
  532. case MUS_MOD:
  533. MOD_delete(music->data.module);
  534. break;
  535. #endif
  536. #ifdef MID_MUSIC
  537. case MUS_MID:
  538. #ifdef USE_NATIVE_MIDI
  539.    if ( native_midi_ok ) {
  540. native_midi_freesong(music->data.nativemidi);
  541. } MIDI_ELSE
  542. #endif
  543. #ifdef USE_TIMIDITY_MIDI
  544. if ( timidity_ok ) {
  545. Timidity_FreeSong(music->data.midi);
  546. }
  547. #endif
  548. break;
  549. #endif
  550. #ifdef OGG_MUSIC
  551. case MUS_OGG:
  552. OGG_delete(music->data.ogg);
  553. break;
  554. #endif
  555. #ifdef FLAC_MUSIC
  556. case MUS_FLAC:
  557. FLAC_delete(music->data.flac);
  558. break;
  559. #endif
  560. #ifdef MP3_MUSIC
  561. case MUS_MP3:
  562. smpeg.SMPEG_delete(music->data.mp3);
  563. break;
  564. #endif
  565. #ifdef MP3_MAD_MUSIC
  566. case MUS_MP3_MAD:
  567. mad_closeFile(music->data.mp3_mad);
  568. break;
  569. #endif
  570. default:
  571. /* Unknown music type?? */
  572. break;
  573. }
  574. free(music);
  575. }
  576. }
  577. /* Find out the music format of a mixer music, or the currently playing
  578.    music, if 'music' is NULL.
  579. */
  580. Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
  581. {
  582. Mix_MusicType type = MUS_NONE;
  583. if ( music ) {
  584. type = music->type;
  585. } else {
  586. SDL_LockAudio();
  587. if ( music_playing ) {
  588. type = music_playing->type;
  589. }
  590. SDL_UnlockAudio();
  591. }
  592. return(type);
  593. }
  594. /* Play a music chunk.  Returns 0, or -1 if there was an error.
  595.  */
  596. static int music_internal_play(Mix_Music *music, double position)
  597. {
  598. int retval = 0;
  599. /* Note the music we're playing */
  600. if ( music_playing ) {
  601. music_internal_halt();
  602. }
  603. music_playing = music;
  604. /* Set the initial volume */
  605. if ( music->type != MUS_MOD ) {
  606. music_internal_initialize_volume();
  607. }
  608. /* Set up for playback */
  609. switch (music->type) {
  610. #ifdef CMD_MUSIC
  611.     case MUS_CMD:
  612. MusicCMD_Start(music->data.cmd);
  613. break;
  614. #endif
  615. #ifdef WAV_MUSIC
  616.     case MUS_WAV:
  617. WAVStream_Start(music->data.wave);
  618. break;
  619. #endif
  620. #ifdef MOD_MUSIC
  621.     case MUS_MOD:
  622. MOD_play(music->data.module);
  623. /* Player_SetVolume() does nothing before Player_Start() */
  624. music_internal_initialize_volume();
  625. break;
  626. #endif
  627. #ifdef MID_MUSIC
  628.     case MUS_MID:
  629. #ifdef USE_NATIVE_MIDI
  630. if ( native_midi_ok ) {
  631. native_midi_start(music->data.nativemidi);
  632. } MIDI_ELSE
  633. #endif
  634. #ifdef USE_TIMIDITY_MIDI
  635. if ( timidity_ok ) {
  636. Timidity_Start(music->data.midi);
  637. }
  638. #endif
  639. break;
  640. #endif
  641. #ifdef OGG_MUSIC
  642.     case MUS_OGG:
  643. OGG_play(music->data.ogg);
  644. break;
  645. #endif
  646. #ifdef FLAC_MUSIC
  647.     case MUS_FLAC:
  648. FLAC_play(music->data.flac);
  649. break;
  650. #endif
  651. #ifdef MP3_MUSIC
  652.     case MUS_MP3:
  653. smpeg.SMPEG_enableaudio(music->data.mp3,1);
  654. smpeg.SMPEG_enablevideo(music->data.mp3,0);
  655. smpeg.SMPEG_play(music_playing->data.mp3);
  656. break;
  657. #endif
  658. #ifdef MP3_MAD_MUSIC
  659.     case MUS_MP3_MAD:
  660. mad_start(music->data.mp3_mad);
  661. break;
  662. #endif
  663.     default:
  664. Mix_SetError("Can't play unknown music type");
  665. retval = -1;
  666. break;
  667. }
  668. /* Set the playback position, note any errors if an offset is used */
  669. if ( retval == 0 ) {
  670. if ( position > 0.0 ) {
  671. if ( music_internal_position(position) < 0 ) {
  672. Mix_SetError("Position not implemented for music type");
  673. retval = -1;
  674. }
  675. } else {
  676. music_internal_position(0.0);
  677. }
  678. }
  679. /* If the setup failed, we're not playing any music anymore */
  680. if ( retval < 0 ) {
  681. music_playing = NULL;
  682. }
  683. return(retval);
  684. }
  685. int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
  686. {
  687. int retval;
  688. /* Don't play null pointers :-) */
  689. if ( music == NULL ) {
  690. Mix_SetError("music parameter was NULL");
  691. return(-1);
  692. }
  693. /* Setup the data */
  694. if ( ms ) {
  695. music->fading = MIX_FADING_IN;
  696. } else {
  697. music->fading = MIX_NO_FADING;
  698. }
  699. music->fade_step = 0;
  700. music->fade_steps = ms/ms_per_step;
  701. /* Play the puppy */
  702. SDL_LockAudio();
  703. /* If the current music is fading out, wait for the fade to complete */
  704. while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
  705. SDL_UnlockAudio();
  706. SDL_Delay(100);
  707. SDL_LockAudio();
  708. }
  709. music_active = 1;
  710. music_loops = loops;
  711. retval = music_internal_play(music, position);
  712. SDL_UnlockAudio();
  713. return(retval);
  714. }
  715. int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
  716. {
  717. return Mix_FadeInMusicPos(music, loops, ms, 0.0);
  718. }
  719. int Mix_PlayMusic(Mix_Music *music, int loops)
  720. {
  721. return Mix_FadeInMusicPos(music, loops, 0, 0.0);
  722. }
  723. /* Set the playing music position */
  724. int music_internal_position(double position)
  725. {
  726. int retval = 0;
  727. switch (music_playing->type) {
  728. #ifdef MOD_MUSIC
  729.     case MUS_MOD:
  730. MOD_jump_to_time(music_playing->data.module, position);
  731. break;
  732. #endif
  733. #ifdef OGG_MUSIC
  734.     case MUS_OGG:
  735. OGG_jump_to_time(music_playing->data.ogg, position);
  736. break;
  737. #endif
  738. #ifdef FLAC_MUSIC
  739.     case MUS_FLAC:
  740. FLAC_jump_to_time(music_playing->data.flac, position);
  741. break;
  742. #endif
  743. #ifdef MP3_MUSIC
  744.     case MUS_MP3:
  745. if ( position > 0.0 ) {
  746. smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
  747. } else {
  748. smpeg.SMPEG_rewind(music_playing->data.mp3);
  749. smpeg.SMPEG_play(music_playing->data.mp3);
  750. }
  751. break;
  752. #endif
  753. #ifdef MP3_MAD_MUSIC
  754.     case MUS_MP3_MAD:
  755. mad_seek(music_playing->data.mp3_mad, position);
  756. break;
  757. #endif
  758.     default:
  759. /* TODO: Implement this for other music backends */
  760. retval = -1;
  761. break;
  762. }
  763. return(retval);
  764. }
  765. int Mix_SetMusicPosition(double position)
  766. {
  767. int retval;
  768. SDL_LockAudio();
  769. if ( music_playing ) {
  770. retval = music_internal_position(position);
  771. if ( retval < 0 ) {
  772. Mix_SetError("Position not implemented for music type");
  773. }
  774. } else {
  775. Mix_SetError("Music isn't playing");
  776. retval = -1;
  777. }
  778. SDL_UnlockAudio();
  779. return(retval);
  780. }
  781. /* Set the music's initial volume */
  782. static void music_internal_initialize_volume(void)
  783. {
  784. if ( music_playing->fading == MIX_FADING_IN ) {
  785. music_internal_volume(0);
  786. } else {
  787. music_internal_volume(music_volume);
  788. }
  789. }
  790. /* Set the music volume */
  791. static void music_internal_volume(int volume)
  792. {
  793. switch (music_playing->type) {
  794. #ifdef CMD_MUSIC
  795.     case MUS_CMD:
  796. MusicCMD_SetVolume(volume);
  797. break;
  798. #endif
  799. #ifdef WAV_MUSIC
  800.     case MUS_WAV:
  801. WAVStream_SetVolume(volume);
  802. break;
  803. #endif
  804. #ifdef MOD_MUSIC
  805.     case MUS_MOD:
  806. MOD_setvolume(music_playing->data.module, volume);
  807. break;
  808. #endif
  809. #ifdef MID_MUSIC
  810.     case MUS_MID:
  811. #ifdef USE_NATIVE_MIDI
  812. if ( native_midi_ok ) {
  813. native_midi_setvolume(volume);
  814. } MIDI_ELSE
  815. #endif
  816. #ifdef USE_TIMIDITY_MIDI
  817. if ( timidity_ok ) {
  818. Timidity_SetVolume(volume);
  819. }
  820. #endif
  821. break;
  822. #endif
  823. #ifdef OGG_MUSIC
  824.     case MUS_OGG:
  825. OGG_setvolume(music_playing->data.ogg, volume);
  826. break;
  827. #endif
  828. #ifdef FLAC_MUSIC
  829.     case MUS_FLAC:
  830. FLAC_setvolume(music_playing->data.flac, volume);
  831. break;
  832. #endif
  833. #ifdef MP3_MUSIC
  834.     case MUS_MP3:
  835. smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
  836. break;
  837. #endif
  838. #ifdef MP3_MAD_MUSIC
  839.     case MUS_MP3_MAD:
  840. mad_setVolume(music_playing->data.mp3_mad, volume);
  841. break;
  842. #endif
  843.     default:
  844. /* Unknown music type?? */
  845. break;
  846. }
  847. }
  848. int Mix_VolumeMusic(int volume)
  849. {
  850. int prev_volume;
  851. prev_volume = music_volume;
  852. if ( volume < 0 ) {
  853. return prev_volume;
  854. }
  855. if ( volume > SDL_MIX_MAXVOLUME ) {
  856. volume = SDL_MIX_MAXVOLUME;
  857. }
  858. music_volume = volume;
  859. SDL_LockAudio();
  860. if ( music_playing ) {
  861. music_internal_volume(music_volume);
  862. }
  863. SDL_UnlockAudio();
  864. return(prev_volume);
  865. }
  866. /* Halt playing of music */
  867. static void music_internal_halt(void)
  868. {
  869. switch (music_playing->type) {
  870. #ifdef CMD_MUSIC
  871.     case MUS_CMD:
  872. MusicCMD_Stop(music_playing->data.cmd);
  873. break;
  874. #endif
  875. #ifdef WAV_MUSIC
  876.     case MUS_WAV:
  877. WAVStream_Stop();
  878. break;
  879. #endif
  880. #ifdef MOD_MUSIC
  881.     case MUS_MOD:
  882. MOD_stop(music_playing->data.module);
  883. break;
  884. #endif
  885. #ifdef MID_MUSIC
  886.     case MUS_MID:
  887. #ifdef USE_NATIVE_MIDI
  888. if ( native_midi_ok ) {
  889. native_midi_stop();
  890. } MIDI_ELSE
  891. #endif
  892. #ifdef USE_TIMIDITY_MIDI
  893. if ( timidity_ok ) {
  894. Timidity_Stop();
  895. }
  896. #endif
  897. break;
  898. #endif
  899. #ifdef OGG_MUSIC
  900.     case MUS_OGG:
  901. OGG_stop(music_playing->data.ogg);
  902. break;
  903. #endif
  904. #ifdef FLAC_MUSIC
  905.     case MUS_FLAC:
  906. FLAC_stop(music_playing->data.flac);
  907. break;
  908. #endif
  909. #ifdef MP3_MUSIC
  910.     case MUS_MP3:
  911. smpeg.SMPEG_stop(music_playing->data.mp3);
  912. break;
  913. #endif
  914. #ifdef MP3_MAD_MUSIC
  915.     case MUS_MP3_MAD:
  916. mad_stop(music_playing->data.mp3_mad);
  917. break;
  918. #endif
  919.     default:
  920. /* Unknown music type?? */
  921. return;
  922. }
  923. music_playing->fading = MIX_NO_FADING;
  924. music_playing = NULL;
  925. }
  926. int Mix_HaltMusic(void)
  927. {
  928. SDL_LockAudio();
  929. if ( music_playing ) {
  930. music_internal_halt();
  931. }
  932. SDL_UnlockAudio();
  933. return(0);
  934. }
  935. /* Progressively stop the music */
  936. int Mix_FadeOutMusic(int ms)
  937. {
  938. int retval = 0;
  939. if (ms <= 0) {  /* just halt immediately. */
  940. Mix_HaltMusic();
  941. return 1;
  942. }
  943. SDL_LockAudio();
  944. if ( music_playing) {
  945.                 int fade_steps = (ms + ms_per_step - 1)/ms_per_step;
  946.                 if ( music_playing->fading == MIX_NO_FADING ) {
  947.          music_playing->fade_step = 0;
  948.                 } else {
  949.                         int step;
  950.                         int old_fade_steps = music_playing->fade_steps;
  951.                         if ( music_playing->fading == MIX_FADING_OUT ) {
  952.                                 step = music_playing->fade_step;
  953.                         } else {
  954.                                 step = old_fade_steps
  955.                                         - music_playing->fade_step + 1;
  956.                         }
  957.                         music_playing->fade_step = (step * fade_steps)
  958.                                 / old_fade_steps;
  959.                 }
  960. music_playing->fading = MIX_FADING_OUT;
  961. music_playing->fade_steps = fade_steps;
  962. retval = 1;
  963. }
  964. SDL_UnlockAudio();
  965. return(retval);
  966. }
  967. Mix_Fading Mix_FadingMusic(void)
  968. {
  969. Mix_Fading fading = MIX_NO_FADING;
  970. SDL_LockAudio();
  971. if ( music_playing ) {
  972. fading = music_playing->fading;
  973. }
  974. SDL_UnlockAudio();
  975. return(fading);
  976. }
  977. /* Pause/Resume the music stream */
  978. void Mix_PauseMusic(void)
  979. {
  980. music_active = 0;
  981. }
  982. void Mix_ResumeMusic(void)
  983. {
  984. music_active = 1;
  985. }
  986. void Mix_RewindMusic(void)
  987. {
  988. Mix_SetMusicPosition(0.0);
  989. }
  990. int Mix_PausedMusic(void)
  991. {
  992. return (music_active == 0);
  993. }
  994. /* Check the status of the music */
  995. static int music_internal_playing()
  996. {
  997. int playing = 1;
  998. switch (music_playing->type) {
  999. #ifdef CMD_MUSIC
  1000.     case MUS_CMD:
  1001. if (!MusicCMD_Active(music_playing->data.cmd)) {
  1002. playing = 0;
  1003. }
  1004. break;
  1005. #endif
  1006. #ifdef WAV_MUSIC
  1007.     case MUS_WAV:
  1008. if ( ! WAVStream_Active() ) {
  1009. playing = 0;
  1010. }
  1011. break;
  1012. #endif
  1013. #ifdef MOD_MUSIC
  1014.     case MUS_MOD:
  1015. if ( ! MOD_playing(music_playing->data.module) ) {
  1016. playing = 0;
  1017. }
  1018. break;
  1019. #endif
  1020. #ifdef MID_MUSIC
  1021.     case MUS_MID:
  1022. #ifdef USE_NATIVE_MIDI
  1023. if ( native_midi_ok ) {
  1024. if ( ! native_midi_active() )
  1025. playing = 0;
  1026. } MIDI_ELSE
  1027. #endif
  1028. #ifdef USE_TIMIDITY_MIDI
  1029. if ( timidity_ok ) {
  1030. if ( ! Timidity_Active() )
  1031. playing = 0;
  1032. }
  1033. #endif
  1034. break;
  1035. #endif
  1036. #ifdef OGG_MUSIC
  1037.     case MUS_OGG:
  1038. if ( ! OGG_playing(music_playing->data.ogg) ) {
  1039. playing = 0;
  1040. }
  1041. break;
  1042. #endif
  1043. #ifdef FLAC_MUSIC
  1044.     case MUS_FLAC:
  1045. if ( ! FLAC_playing(music_playing->data.flac) ) {
  1046. playing = 0;
  1047. }
  1048. break;
  1049. #endif
  1050. #ifdef MP3_MUSIC
  1051.     case MUS_MP3:
  1052. if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
  1053. playing = 0;
  1054. break;
  1055. #endif
  1056. #ifdef MP3_MAD_MUSIC
  1057.     case MUS_MP3_MAD:
  1058. if (!mad_isPlaying(music_playing->data.mp3_mad)) {
  1059. playing = 0;
  1060. }
  1061. break;
  1062. #endif
  1063.     default:
  1064. playing = 0;
  1065. break;
  1066. }
  1067. return(playing);
  1068. }
  1069. int Mix_PlayingMusic(void)
  1070. {
  1071. int playing = 0;
  1072. SDL_LockAudio();
  1073. if ( music_playing ) {
  1074. playing = music_internal_playing();
  1075. }
  1076. SDL_UnlockAudio();
  1077. return(playing);
  1078. }
  1079. /* Set the external music playback command */
  1080. int Mix_SetMusicCMD(const char *command)
  1081. {
  1082. Mix_HaltMusic();
  1083. if ( music_cmd ) {
  1084. free(music_cmd);
  1085. music_cmd = NULL;
  1086. }
  1087. if ( command ) {
  1088. music_cmd = (char *)malloc(strlen(command)+1);
  1089. if ( music_cmd == NULL ) {
  1090. return(-1);
  1091. }
  1092. strcpy(music_cmd, command);
  1093. }
  1094. return(0);
  1095. }
  1096. int Mix_SetSynchroValue(int i)
  1097. {
  1098. /* Not supported by any players at this time */
  1099. return(-1);
  1100. }
  1101. int Mix_GetSynchroValue(void)
  1102. {
  1103. /* Not supported by any players at this time */
  1104. return(-1);
  1105. }
  1106. /* Uninitialize the music players */
  1107. void close_music(void)
  1108. {
  1109. Mix_HaltMusic();
  1110. #ifdef CMD_MUSIC
  1111. Mix_SetMusicCMD(NULL);
  1112. #endif
  1113. #ifdef MOD_MUSIC
  1114. MOD_exit();
  1115. #endif
  1116. #ifdef MID_MUSIC
  1117. # ifdef USE_TIMIDITY_MIDI
  1118. Timidity_Close();
  1119. # endif
  1120. #endif
  1121. /* rcg06042009 report available decoders at runtime. */
  1122. free(music_decoders);
  1123. music_decoders = NULL;
  1124. num_decoders = 0;
  1125. }
  1126. Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
  1127. {
  1128. Uint8 magic[5];   /*Apparently there is no way to check if the file is really a MOD,*/
  1129. /*     or there are too many formats supported by MikMod or MikMod does */
  1130. /*     this check by itself. If someone implements other formats (e.g. MP3) */
  1131. /*     the check can be uncommented */
  1132. Uint8 moremagic[9];
  1133. Mix_Music *music;
  1134. int start;
  1135. if (!rw) {
  1136. Mix_SetError("RWops pointer is NULL");
  1137. return NULL;
  1138. }
  1139. /* Figure out what kind of file this is */
  1140. start = SDL_RWtell(rw);
  1141. if ( SDL_RWread(rw,magic,1,4) != 4 ||
  1142.      SDL_RWread(rw,moremagic,1,8) != 8 ) {
  1143. Mix_SetError("Couldn't read from RWops");
  1144. return NULL;
  1145. }
  1146. SDL_RWseek(rw, start, RW_SEEK_SET);
  1147. magic[4]='';
  1148. moremagic[8] = '';
  1149. /* Allocate memory for the music structure */
  1150. music=(Mix_Music *)malloc(sizeof(Mix_Music));
  1151. if (music==NULL ) {
  1152. Mix_SetError("Out of memory");
  1153. return(NULL);
  1154. }
  1155. music->error = 0;
  1156. #ifdef WAV_MUSIC
  1157. /* WAVE files have the magic four bytes "RIFF"
  1158.    AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
  1159.  */
  1160. if ( ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
  1161.      (strcmp((char *)magic, "FORM") == 0) ) {
  1162. music->type = MUS_WAV;
  1163. music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic);
  1164. if ( music->data.wave == NULL ) {
  1165. music->error = 1;
  1166. }
  1167. } else
  1168. #endif
  1169. #ifdef OGG_MUSIC
  1170. /* Ogg Vorbis files have the magic four bytes "OggS" */
  1171. if ( strcmp((char *)magic, "OggS") == 0 ) {
  1172. music->type = MUS_OGG;
  1173. music->data.ogg = OGG_new_RW(rw);
  1174. if ( music->data.ogg == NULL ) {
  1175. music->error = 1;
  1176. }
  1177. } else
  1178. #endif
  1179. #ifdef FLAC_MUSIC
  1180. /* FLAC files have the magic four bytes "fLaC" */
  1181. if ( strcmp((char *)magic, "fLaC") == 0 ) {
  1182. music->type = MUS_FLAC;
  1183. music->data.flac = FLAC_new_RW(rw);
  1184. if ( music->data.flac == NULL ) {
  1185. music->error = 1;
  1186. }
  1187. } else
  1188. #endif
  1189. #ifdef MP3_MUSIC
  1190. if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
  1191. if ( Mix_Init(MIX_INIT_MP3) ) {
  1192. SMPEG_Info info;
  1193. music->type = MUS_MP3;
  1194. music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
  1195. if ( !info.has_audio ) {
  1196. Mix_SetError("MPEG file does not have any audio stream.");
  1197. music->error = 1;
  1198. } else {
  1199. smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
  1200. }
  1201. } else {
  1202. music->error = 1;
  1203. }
  1204. } else
  1205. #endif
  1206. #ifdef MP3_MAD_MUSIC
  1207. if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
  1208. music->type = MUS_MP3_MAD;
  1209. music->data.mp3_mad = mad_openFileRW(rw, &used_mixer);
  1210. if (music->data.mp3_mad == 0) {
  1211. Mix_SetError("Could not initialize MPEG stream.");
  1212. music->error = 1;
  1213. }
  1214. } else
  1215. #endif
  1216. #ifdef MID_MUSIC
  1217. /* MIDI files have the magic four bytes "MThd" */
  1218. if ( strcmp((char *)magic, "MThd") == 0 ) {
  1219. music->type = MUS_MID;
  1220. #ifdef USE_NATIVE_MIDI
  1221. if ( native_midi_ok ) {
  1222. music->data.nativemidi = native_midi_loadsong_RW(rw);
  1223.    if ( music->data.nativemidi == NULL ) {
  1224.    Mix_SetError("%s", native_midi_error());
  1225.    music->error = 1;
  1226. }
  1227. } MIDI_ELSE
  1228. #endif
  1229. #ifdef USE_TIMIDITY_MIDI
  1230. if ( timidity_ok ) {
  1231. music->data.midi = Timidity_LoadSong_RW(rw);
  1232. if ( music->data.midi == NULL ) {
  1233. Mix_SetError("%s", Timidity_Error());
  1234. music->error = 1;
  1235. }
  1236. } else {
  1237. Mix_SetError("%s", Timidity_Error());
  1238. music->error = 1;
  1239. }
  1240. #endif
  1241. } else
  1242. #endif
  1243. #ifdef MOD_MUSIC
  1244. if (1) {
  1245. music->type=MUS_MOD;
  1246. music->data.module = MOD_new_RW(rw);
  1247. if ( music->data.module == NULL ) {
  1248. music->error = 1;
  1249. }
  1250. } else
  1251. #endif
  1252. {
  1253. Mix_SetError("Unrecognized music format");
  1254. music->error=1;
  1255. }
  1256. if (music->error) {
  1257. free(music);
  1258. music=NULL;
  1259. }
  1260. return(music);
  1261. }