Return of the MP3 CD patch ... use CBR 22 kHz

svn-id: r3981
This commit is contained in:
Nicolas Bacca 2002-04-17 20:23:45 +00:00
parent fd6a44e7c5
commit bb06400d00
9 changed files with 310 additions and 149 deletions

View file

@ -32,7 +32,6 @@
#include "scumm.h" #include "scumm.h"
#include "gui.h" #include "gui.h"
#include "cdmusic.h" #include "cdmusic.h"
#include "mp3_cd.h"
#include "gameDetector.h" #include "gameDetector.h"
#define SRC_WIDTH 320 #define SRC_WIDTH 320

View file

@ -2672,8 +2672,14 @@ void Scumm::decodeParseString()
else else
offset = 0; offset = 0;
delay = (int)((getVarOrDirectWord(0x40) & 0xffff) * 7.5); delay = (int)((getVarOrDirectWord(0x40) & 0xffff) * 7.5);
if (_gameId == GID_LOOM256) if (_gameId == GID_LOOM256) {
_vars[VAR_MUSIC_FLAG] = 0;
#ifdef COMPRESSED_SOUND_FILE
playMP3CDTrack(1, 0, offset, delay);
#else
_system->play_cdrom(1, 0, offset, delay); _system->play_cdrom(1, 0, offset, delay);
#endif
}
else else
warning("parseString: 8"); warning("parseString: 8");
} }

31
scumm.h
View file

@ -82,7 +82,7 @@ struct ResHdr {
} GCC_PACK; } GCC_PACK;
#define RES_DATA(x) (((byte*)x) + sizeof(ResHdr)) #define RES_DATA(x) (((byte*)x) + sizeof(ResHdr))
#define RES_SIZE(x) ( READ_BE_UINT32_UNALIGNED(&((ResHdr*)x)->size) ) #define RES_SIZE(x) ( READ_BE_UINT32(&((ResHdr*)x)->size) )
struct RoomHeader { struct RoomHeader {
@ -595,7 +595,10 @@ public:
char *getGameName(); char *getGameName();
Scumm(); // constructor Scumm(); // constructor
byte *_videoBuffer; /* video buffer */
byte _videoBuffer[328*200]; // main video buffer
/* system call object */
/* Scumm main loop */ /* Scumm main loop */
@ -952,6 +955,27 @@ public:
uint _curSoundPos; uint _curSoundPos;
int current_cd_sound; int current_cd_sound;
#ifdef COMPRESSED_SOUND_FILE
#define CACHE_TRACKS 10
#define MP3_BUFFER_SIZE 200000
/* used for mp3 CD music */
int _current_cache;
int _cached_tracks[CACHE_TRACKS];
struct mad_header _mad_header[CACHE_TRACKS];
long _mp3_size[CACHE_TRACKS];
FILE* _mp3_tracks[CACHE_TRACKS];
void* _mp3_buffer;
PlayingSoundHandle _mp3_handle;
int getCachedTrack(int track);
void playMP3CDTrack(int track, int num_loops, int start, int delay);
#endif
int16 _soundQuePos, _soundQue[0x100]; int16 _soundQuePos, _soundQue[0x100];
byte _soundQue2Pos, _soundQue2[10]; byte _soundQue2Pos, _soundQue2[10];
bool _soundsPaused, _soundsPaused2; bool _soundsPaused, _soundsPaused2;
@ -1120,6 +1144,7 @@ public:
void restoreBG(int left, int top, int right, int bottom); void restoreBG(int left, int top, int right, int bottom);
void redrawBGStrip(int start, int num); void redrawBGStrip(int start, int num);
void redrawBGAreas(); void redrawBGAreas();
void redrawLines(int from, int to);
void moveCamera(); void moveCamera();
void cameraMoved(); void cameraMoved();
@ -1821,4 +1846,4 @@ byte *findResourceSmall(uint32 tag, byte *searchin);
//void setShakePos(Scumm *s, int shake_pos); //void setShakePos(Scumm *s, int shake_pos);
void setWindowName(Scumm *s); void setWindowName(Scumm *s);
uint16 newTag2Old(uint32 oldTag); uint16 newTag2Old(uint32 oldTag);
//void cd_playtrack(int track, int offset, int delay);

View file

@ -63,7 +63,6 @@ void Scumm::scummInit()
if (!(_features & GF_SMALL_NAMES)) if (!(_features & GF_SMALL_NAMES))
loadCharset(1); loadCharset(1);
initScreens(0, 16, 320, 144); initScreens(0, 16, 320, 144);
setShake(0); setShake(0);
@ -167,6 +166,11 @@ void Scumm::scummInit()
_vars[VAR_V5_TALK_STRING_Y] = -0x50; _vars[VAR_V5_TALK_STRING_Y] = -0x50;
getGraphicsPerformance(); getGraphicsPerformance();
#ifdef COMPRESSED_SOUND_FILE
_current_cache = 0;
_mp3_buffer = NULL;
#endif
} }
@ -238,14 +242,14 @@ int Scumm::scummLoop(int delta)
_vars[VAR_MOUSE_Y] = mouse.y; _vars[VAR_MOUSE_Y] = mouse.y;
_vars[VAR_DEBUGMODE] = _debugMode; _vars[VAR_DEBUGMODE] = _debugMode;
if (_features & GF_AUDIOTRACKS) { if (_features & GF_AUDIOTRACKS) {
if (delta) { if (delta) {
if (++counter != 2) if (++counter != 2)
_vars[VAR_MI1_TIMER] += 5; _vars[VAR_MI1_TIMER] += 5;
else { else {
counter = 0; counter = 0;
_vars[VAR_MI1_TIMER] += 6; _vars[VAR_MI1_TIMER] += 6;
} }
} }
} else if (_features & GF_OLD256) } else if (_features & GF_OLD256)
_vars[VAR_MUSIC_FLAG]++; // ENDERFIX _vars[VAR_MUSIC_FLAG]++; // ENDERFIX
@ -902,8 +906,9 @@ void Scumm::convertKeysToClicks()
Actor *Scumm::derefActorSafe(int id, const char *errmsg) Actor *Scumm::derefActorSafe(int id, const char *errmsg)
{ {
if (id < 1 || id >= NUM_ACTORS) { if (id < 1 || id >= NUM_ACTORS) {
if (_debugMode) warning
warning("Invalid actor %d in %s (script %d, opcode 0x%x) - This is potentially a BIG problem.", id, errmsg, vm.slot[_curExecScript].number, _opcode); ("Invalid actor %d in %s (script %d, opcode 0x%x) - This is potentially a BIG problem.",
id, errmsg, vm.slot[_curExecScript].number, _opcode);
return NULL; return NULL;
} }
return derefActor(id); return derefActor(id);
@ -1147,7 +1152,6 @@ void Scumm::waitForTimer(int msec_delay) {
} }
} }
_system->update_cdrom(); /* Loop CD Audio if needed */
if (_system->get_msecs() >= start_time + msec_delay) if (_system->get_msecs() >= start_time + msec_delay)
break; break;
_system->delay_msecs(10); _system->delay_msecs(10);
@ -1212,7 +1216,6 @@ void Scumm::launch()
_minHeapThreshold = 400000; _minHeapThreshold = 400000;
/* Create a primary virtual screen */ /* Create a primary virtual screen */
_videoBuffer = (byte*)malloc(328*200);
allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0); allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0);
initVirtScreen(0, 0, 200, false, false); initVirtScreen(0, 0, 200, false, false);
@ -1288,15 +1291,7 @@ Scumm *Scumm::createFromDetector(GameDetector *detector, OSystem *syst)
/* bind the mixer to the system => mixer will be invoked /* bind the mixer to the system => mixer will be invoked
* automatically when samples need to be generated */ * automatically when samples need to be generated */
if (!scumm->_mixer->bind_to_system(syst)) { scumm->_mixer->bind_to_system(syst);
warning("Sound initialization failed");
if (detector->_use_adlib) {
detector->_use_adlib = false;
detector->_midi_driver = MD_NULL;
warning("Adlib music was selected, switching to midi null driver");
}
}
scumm->_mixer->set_volume(128); scumm->_mixer->set_volume(128);
scumm->_fullScreen = detector->_fullScreen; scumm->_fullScreen = detector->_fullScreen;

View file

@ -4,7 +4,6 @@
#include "SDL_thread.h" #include "SDL_thread.h"
#include "gameDetector.h" #include "gameDetector.h"
#include "mp3_cd.h"
#include <SDL.h> #include <SDL.h>
#define MAX(a,b) (((a)<(b)) ? (b) : (a)) #define MAX(a,b) (((a)<(b)) ? (b) : (a))

130
sound.cpp
View file

@ -504,6 +504,7 @@ void *Scumm::openSfxFile()
warning("Unable to open DIG voice bundle: %s", buf); warning("Unable to open DIG voice bundle: %s", buf);
return file; return file;
} }
/* Try opening the file <_exe_name>.sou first, eg tentacle.sou. /* Try opening the file <_exe_name>.sou first, eg tentacle.sou.
* That way, you can keep .sou files for multiple games in the * That way, you can keep .sou files for multiple games in the
* same directory */ * same directory */
@ -583,9 +584,134 @@ void Scumm::playSfxSound(void *sound, uint32 size, uint rate)
void Scumm::playSfxSound_MP3(void *sound, uint32 size) void Scumm::playSfxSound_MP3(void *sound, uint32 size)
{ {
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
_mixer->play_mp3(NULL, sound, size, SoundMixer::FLAG_AUTOFREE); _mixer->play_mp3(NULL, sound, size, SoundMixer::FLAG_AUTOFREE);
#else
error("Should never happen !!!");
#endif #endif
} }
#ifdef COMPRESSED_SOUND_FILE
int Scumm::getCachedTrack(int track) {
int i;
char track_name[1024];
FILE* file;
int current_index;
struct mad_stream stream;
struct mad_frame frame;
unsigned char buffer[8192];
unsigned int buflen = 0;
int count = 0, result = 0;
// See if we find the track in the cache
for (i=0; i<CACHE_TRACKS; i++)
if (_cached_tracks[i] == track) {
if (_mp3_tracks[i])
return i;
else
return -1;
}
current_index = _current_cache++;
_current_cache %= CACHE_TRACKS;
// Not found, see if it exists
sprintf(track_name, "%strack%d.mp3", _gameDataPath, track);
file = fopen(track_name, "rb");
_cached_tracks[current_index] = track;
_mp3_tracks[current_index] = NULL;
if (!file) {
warning("Track %d not available in mp3 format", track);
return -1;
}
// Check the format and bitrate
mad_stream_init(&stream);
mad_frame_init(&frame);
while (1) {
if (buflen < sizeof(buffer)) {
uint16 bytes;
bytes = fread(buffer + buflen, 1, sizeof(buffer) - buflen, file);
if (bytes <= 0) {
if (bytes == -1) {
warning("Invalid format for track %d", track);
return -1;
}
break;
}
buflen += bytes;
}
mad_stream_buffer(&stream, buffer, buflen);
while (1) {
if (mad_frame_decode(&frame, &stream) == -1) {
if (!MAD_RECOVERABLE(stream.error))
break;
if (stream.error != MAD_ERROR_BADCRC)
continue;
}
if (count++)
break;
}
if (count || stream.error != MAD_ERROR_BUFLEN)
break;
memmove(buffer, stream.next_frame,
buflen = &buffer[buflen] - stream.next_frame);
}
if (count)
memcpy(&_mad_header[current_index], &frame.header, sizeof(mad_header));
else {
warning("Invalid format for track %d", track);
return -1;
}
mad_frame_finish(&frame);
mad_stream_finish(&stream);
// Get file size
fseek(file, 0, SEEK_END);
_mp3_size[current_index] = ftell(file);
_mp3_tracks[current_index] = file;
if (!_mp3_buffer)
_mp3_buffer = malloc(MP3_BUFFER_SIZE);
return current_index;
}
void Scumm::playMP3CDTrack(int track, int num_loops, int start, int delay) {
int index;
long offset;
float frame_size;
mad_timer_t duration;
if (!start && !delay) {
_mixer->stop(_mp3_handle);
return;
}
index = getCachedTrack(track);
if (index < 0)
return;
// Calc offset
frame_size = 144 * _mad_header[index].bitrate / _mad_header[index].samplerate;
offset = (long)((float)start / (float)75 * 1000 /
(float)((float)1152 / (float)_mad_header[index].samplerate *
1000) * (float)(frame_size + 0.5));
// Calc delay
mad_timer_set(&duration, 0, delay, 75);
// Go
fseek(_mp3_tracks[index], offset, SEEK_SET);
_mixer->play_mp3_cdtrack(&_mp3_handle, _mp3_tracks[index], _mp3_buffer, MP3_BUFFER_SIZE, duration);
}
#endif

View file

@ -40,6 +40,11 @@ void SoundMixer::play_raw(PlayingSoundHandle *handle, void *sound, uint32 size,
void SoundMixer::play_mp3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags) { void SoundMixer::play_mp3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags) {
insert(handle, new Channel_MP3(this, sound, size, flags)); insert(handle, new Channel_MP3(this, sound, size, flags));
} }
void SoundMixer::play_mp3_cdtrack(PlayingSoundHandle *handle, FILE* file, void *buffer, uint32 buffer_size, mad_timer_t duration) {
if (*handle)
stop(*handle);
insert(handle, new Channel_MP3_CDMUSIC(this, file, buffer, buffer_size, duration));
}
#endif #endif
void SoundMixer::mix(int16 *buf, uint len) { void SoundMixer::mix(int16 *buf, uint len) {
@ -282,153 +287,139 @@ void SoundMixer::Channel_MP3::destroy() {
delete this; delete this;
} }
/* MP3 CD music */
SoundMixer::Channel_MP3_CDMUSIC::Channel_MP3_CDMUSIC(SoundMixer *mixer, FILE* file, void *buffer, uint32 buffer_size, mad_timer_t duration) {
_mixer = mixer;
_file = file;
_duration = duration;
_initialized = false;
_buffer_size = buffer_size;
_ptr = buffer;
_flags = 0;
mad_stream_init(&_stream);
#ifdef _WIN32_WCE
// 11 kHz on WinCE
mad_stream_options(&_stream, MAD_OPTION_HALFSAMPLERATE);
#endif #endif
mad_frame_init(&_frame);
mad_synth_init(&_synth);
}
#if 0 void SoundMixer::Channel_MP3_CDMUSIC::mix(int16 *data, uint len) {
mad_fixed_t const *ch;
mad_timer_t frame_duration;
void MixerChannel::mix(int16 * data, uint32 len) if (!_initialized) {
{ int skip_loop;
} else if (type == MIXER_MP3_CDMUSIC) { // just skipped
mad_fixed_t const *ch; memset(_ptr, 0,_buffer_size + MAD_BUFFER_GUARD);
mad_timer_t frame_duration; _size = fread(_ptr, 1, _buffer_size, _file);
static long last_pos = 0; if (!_size) {
destroy();
if (!sound_data.mp3_cdmusic.playing)
return; return;
}
while (1) { // Resync
mad_stream_buffer(&_stream,(unsigned char *)_ptr,_size);
// See if we just skipped skip_loop = 2;
if (ftell(sound_data.mp3_cdmusic.file) != last_pos) { while (skip_loop != 0) {
int skip_loop; if (mad_frame_decode(&_frame,&_stream) == 0) {
/* Do not decrease duration - see if it's a problem */
// Read the new data skip_loop--;
memset(_sfx_sound, 0, if (skip_loop == 0) {
sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD); mad_synth_frame(&_synth, &_frame);
sound_data.mp3_cdmusic.size =
fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
sound_data.mp3_cdmusic.file);
if (!sound_data.mp3_cdmusic.size) {
sound_data.mp3_cdmusic.playing = false;
return;
} }
last_pos = ftell(sound_data.mp3_cdmusic.file); } else {
// Resync if (!MAD_RECOVERABLE(_stream.error)) {
mad_stream_buffer(&sound_data.mp3_cdmusic.stream,
(unsigned char *)_sfx_sound,
sound_data.mp3_cdmusic.size);
skip_loop = 2;
while (skip_loop != 0) {
if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
&sound_data.mp3_cdmusic.stream) == 0) {
/* Do not decrease duration - see if it's a problem */
skip_loop--;
if (skip_loop == 0) {
mad_synth_frame(&sound_data.mp3_cdmusic.synth,
&sound_data.mp3_cdmusic.frame);
}
} else {
if (!MAD_RECOVERABLE(sound_data.mp3_cdmusic.stream.error)) {
debug(1, "Unrecoverable error while skipping !"); debug(1, "Unrecoverable error while skipping !");
sound_data.mp3_cdmusic.playing = false; destroy();
return; return;
}
} }
} }
// We are supposed to be in synch }
mad_frame_mute(&sound_data.mp3_cdmusic.frame); // We are supposed to be in synch
mad_synth_mute(&sound_data.mp3_cdmusic.synth); mad_frame_mute(&_frame);
// Resume decoding mad_synth_mute(&_synth);
if (mad_frame_decode(&sound_data.mp3_cdmusic.frame, // Resume decoding
&sound_data.mp3_cdmusic.stream) == 0) { if (mad_frame_decode(&_frame,&_stream) == 0) {
sound_data.mp3_cdmusic.position = _pos_in_frame = 0;
(unsigned char *)sound_data.mp3_cdmusic.stream.next_frame - _initialized = true;
(unsigned char *)_sfx_sound; }
sound_data.mp3_cdmusic.pos_in_frame = 0; else {
} else { debug(1, "Cannot resume decoding");
sound_data.mp3_cdmusic.playing = false; destroy();
return; return;
} }
} }
// Get samples, play samples ...
ch = sound_data.mp3_cdmusic.synth.pcm.samples[0] + while(1) {
sound_data.mp3_cdmusic.pos_in_frame; // Get samples, play samples ...
while ((sound_data.mp3_cdmusic.pos_in_frame < ch = _synth.pcm.samples[0] + _pos_in_frame;
sound_data.mp3_cdmusic.synth.pcm.length) && (len > 0)) { while ((_pos_in_frame < _synth.pcm.length) && (len > 0)) {
*data++ += scale_sample(*ch++); *data++ += scale_sample(*ch++);
len--; len--;
sound_data.mp3_cdmusic.pos_in_frame++; _pos_in_frame++;
} }
if (len == 0) { if (len == 0) {
return;
}
// See if we have finished
// May be incorrect to check the size at the end of a frame but I suppose
// they are short enough :)
frame_duration = _frame.header.duration;
mad_timer_negate(&frame_duration);
mad_timer_add(&_duration, frame_duration);
if (mad_timer_compare(_duration, mad_timer_zero) < 0) {
destroy();
return; return;
} }
// See if we have finished if (mad_frame_decode(&_frame, &_stream) == -1) {
// May be incorrect to check the size at the end of a frame but I suppose if (_stream.error == MAD_ERROR_BUFLEN) {
// they are short enough :)
frame_duration = sound_data.mp3_cdmusic.frame.header.duration;
mad_timer_negate(&frame_duration);
mad_timer_add(&sound_data.mp3_cdmusic.duration, frame_duration);
if (mad_timer_compare(sound_data.mp3_cdmusic.duration, mad_timer_zero)
< 0) {
sound_data.mp3_cdmusic.playing = false;
}
if (mad_frame_decode(&sound_data.mp3_cdmusic.frame,
&sound_data.mp3_cdmusic.stream) == -1) {
if (sound_data.mp3_cdmusic.stream.error == MAD_ERROR_BUFLEN) {
int not_decoded; int not_decoded;
if (!sound_data.mp3_cdmusic.stream.next_frame) { if (!_stream.next_frame) {
memset(_sfx_sound, 0, memset(_ptr, 0, _buffer_size + MAD_BUFFER_GUARD);
sound_data.mp3_cdmusic.buffer_size + MAD_BUFFER_GUARD); _size =
sound_data.mp3_cdmusic.size = fread(_ptr, 1, _buffer_size, _file);
fread(_sfx_sound, 1, sound_data.mp3_cdmusic.buffer_size,
sound_data.mp3_cdmusic.file);
sound_data.mp3_cdmusic.position = 0;
not_decoded = 0; not_decoded = 0;
} else { }
not_decoded = sound_data.mp3_cdmusic.stream.bufend - else {
sound_data.mp3_cdmusic.stream.next_frame; not_decoded = _stream.bufend - _stream.next_frame;
memcpy(_sfx_sound, sound_data.mp3_cdmusic.stream.next_frame, memcpy(_ptr, _stream.next_frame, not_decoded);
not_decoded); _size =
fread((unsigned char *)_ptr + not_decoded, 1,
sound_data.mp3_cdmusic.size = _buffer_size - not_decoded, _file);
fread((unsigned char *)_sfx_sound + not_decoded, 1,
sound_data.mp3_cdmusic.buffer_size - not_decoded,
sound_data.mp3_cdmusic.file);
} }
last_pos = ftell(sound_data.mp3_cdmusic.file); _stream.error = MAD_ERROR_NONE;
sound_data.mp3_cdmusic.stream.error = MAD_ERROR_NONE;
// Restream // Restream
mad_stream_buffer(&sound_data.mp3_cdmusic.stream, mad_stream_buffer(&_stream, (unsigned char *)_ptr, _size + not_decoded);
(unsigned char *)_sfx_sound, if (mad_frame_decode(&_frame, &_stream) == -1) {
sound_data.mp3_cdmusic.size + not_decoded);
if (mad_frame_decode
(&sound_data.mp3_cdmusic.frame,
&sound_data.mp3_cdmusic.stream) == -1) {
debug(1, "Error decoding after restream %d !", debug(1, "Error decoding after restream %d !",
sound_data.mp3.stream.error); _stream.error);
} }
} else if (!MAD_RECOVERABLE(sound_data.mp3.stream.error)) { } else if (!MAD_RECOVERABLE(_stream.error)) {
error("MAD frame decode error in MP3 CDMUSIC !"); error("MAD frame decode error in MP3 CDMUSIC !");
} }
}
mad_synth_frame(&sound_data.mp3_cdmusic.synth,
&sound_data.mp3_cdmusic.frame);
sound_data.mp3_cdmusic.pos_in_frame = 0;
sound_data.mp3_cdmusic.position =
(unsigned char *)sound_data.mp3_cdmusic.stream.next_frame -
(unsigned char *)_sfx_sound;
}
} }
mad_synth_frame(&_synth, &_frame);
_pos_in_frame = 0;
} }
} }
void SoundMixer::Channel_MP3_CDMUSIC::destroy() {
if (_flags & FLAG_AUTOFREE)
free(_ptr);
_mixer->uninsert(this);
mad_synth_finish(&_synth);
mad_frame_finish(&_frame);
mad_stream_finish(&_stream);
delete this;
}
#endif #endif

View file

@ -53,6 +53,26 @@ private:
Channel_MP3(SoundMixer *mixer, void *sound, uint size, byte flags); Channel_MP3(SoundMixer *mixer, void *sound, uint size, byte flags);
}; };
class Channel_MP3_CDMUSIC : public Channel {
SoundMixer *_mixer;
void *_ptr;
struct mad_stream _stream;
struct mad_frame _frame;
struct mad_synth _synth;
uint32 _pos_in_frame;
uint32 _size;
uint32 _buffer_size;
mad_timer_t _duration;
FILE *_file;
bool _initialized;
byte _flags;
public:
void mix(int16 *data, uint len);
void destroy();
Channel_MP3_CDMUSIC(SoundMixer *mixer, FILE* file, void *buffer, uint32 buffer_size, mad_timer_t duration);
};
#endif #endif
static void on_generate_samples(void *s, byte *samples, int len); static void on_generate_samples(void *s, byte *samples, int len);
@ -81,11 +101,12 @@ public:
enum { enum {
FLAG_AUTOFREE = 1, FLAG_AUTOFREE = 1,
FLAG_UNSIGNED = 2, /* unsigned samples */ FLAG_UNSIGNED = 2, /* unsigned samples */
FLAG_FILE = 4, /* sound is a FILE * that's read from */ FLAG_FILE = 4, /* sound is a FILE * that's read from */
}; };
void play_raw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags); void play_raw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags);
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
void play_mp3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags); void play_mp3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags);
void play_mp3_cdtrack(PlayingSoundHandle *handle, FILE* file, void *buffer, uint32 buffer_size, mad_timer_t duration);
#endif #endif
/* Premix procedure, useful when using fmopl adlib */ /* Premix procedure, useful when using fmopl adlib */

View file

@ -25,7 +25,6 @@
#include "scumm.h" #include "scumm.h"
#include "gui.h" #include "gui.h"
#include "cdmusic.h" #include "cdmusic.h"
#include "mp3_cd.h"
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>