remove flac and mad mp3 support

This commit is contained in:
nehalmistry 2006-05-06 00:54:24 +00:00
parent 3fdd493f09
commit e37cbba505
11 changed files with 10 additions and 929 deletions

View file

@ -29,8 +29,8 @@ TOOLLIBS=$(XLDFLAGS) -lpng -lz -lm @EXTRA_LIBS@ @THREAD_LIBS@ -L/usr/local/lib \
STRATAGUS_LIBS= -lpng -lz -lm \
@EXTRA_LIBS@ @VIDEO_LIBS@ @THREAD_LIBS@ $(COMP_LIBS) \
@FLAC_LIBS@ @VORBIS_LIBS@ @THEORA_LIBS@ @MNG_LIBS@ \
@MAD_LIBS@ @MIKMOD_LIBS@ @LUA_LIBS@ @STATIC_LDFLAGS@ \
@VORBIS_LIBS@ @THEORA_LIBS@ @MNG_LIBS@ \
@MIKMOD_LIBS@ @LUA_LIBS@ @STATIC_LDFLAGS@ \
-lz -lm $(LDFLAGS)
DISTLIST=$(TOPDIR)/distlist
@ -52,7 +52,7 @@ CFLAGS=$(CPPFLAGS) $(IFLAGS) @DEFS@ -I. \
@PROFILE_CFLAGS@ @STRATAGUS_CFLAGS@ @EXTRA_CFLAGS@ \
@VIDEO_CFLAGS@ @BZ2_CFLAGS@ \
@VORBIS_CFLAGS@ @THEORA_CFLAGS@ \
@MNG_CFLAGS@ @MAD_CFLAGS@ @FLAC_CFLAGS@ \
@MNG_CFLAGS@ \
@MIKMOD_CFLAGS@ @LUA_CFLAGS@ \
$(COMP_CFLAGS) @PLATFORM@ \

View file

@ -262,38 +262,6 @@ AC_SUBST(MNG_CFLAGS)
AC_SUBST(MNG_LIBS)
dnl ----------------------------
dnl --- CHECK FOR MAD LIB ------
AC_ARG_WITH(mad,
[ --with-mad [Use mad mp3 (default: no)]], MAD="$with_mad")
MAD_CFLAGS=
MAD_LIBS=
if test "$MAD" != "yes"; then
MAD_CFLAGS=""
MAD_LIBS=""
else
AC_CHECK_LIB(mad, mad_decoder_init,, AC_MSG_ERROR(libmad not found))
MAD_CFLAGS="-DUSE_MAD"
MAD_LIBS="-lmad"
fi
AC_SUBST(MAD_CFLAGS)
AC_SUBST(MAD_LIBS)
dnl ----------------------------
dnl --- CHECK FOR FLAC LIB -----
AC_ARG_WITH(flac,
[ --with-flac [Use FLAC (default: no)]], FLAC="$with_flac")
if test "$FLAC" != "yes"; then
FLAC_CFLAGS=
FLAC_LIBS=
else
AC_CHECK_LIB(FLAC, FLAC__stream_decoder_init,, AC_MSG_ERROR(libFLAC not found))
FLAC_CFLAGS="-DUSE_FLAC"
FLAC_LIBS="-lFLAC"
fi
AC_SUBST(FLAC_CFLAGS)
AC_SUBST(FLAC_LIBS)
dnl ----------------------------
dnl ---- CHECK FOR LUA ---------
AC_ARG_WITH(lua,
[ --with-lua=prefix [Prefix where Lua is installed]], LUAPFX="$with_lua")

View file

@ -50,8 +50,6 @@
<li><a href="http://www.xipg.org/">libogg</a> (recommended).<p>
<li><a href="http://mikmod.raphnet.net/">libmikmod</a> (optional).<p>
<li><a href="http://sources.redhat.com/bzip2/">libbzip2</a> (optional).<p>
<li><a href="http://flac.sourceforge.net/">libFLAC</a> (optional).<p>
<li><a href="http://www.underbit.com/products/mad/">libmad</a> (optional).<p>
<a href="http://stratagus.sourceforge.net/games.shtml">A stratagus game</a>.<br>
</ul>
@ -63,7 +61,7 @@
architectures like (big endian) PPC or (64bit) Alpha should also
work at least with Linux.</font><p>
<li><b>Memory:</b> 32 MB of RAM (64 MB for mp3/ogg support).<br><p>
<li><b>Memory:</b> 32 MB of RAM (64 MB for ogg support).<br><p>
<li><b>Video Card:</b> Any graphics card that can handle 16 bpp
and 640x480 is supported. (OpenGL is supported, and requires a 32MB Card)<p>

View file

@ -83,10 +83,8 @@ extern char *CurrentMusicFile;
-- Functions
----------------------------------------------------------------------------*/
extern CSample *LoadFlac(const char *name, int flags); /// Load a flac file
extern CSample *LoadWav(const char *name, int flags); /// Load a wav file
extern CSample *LoadVorbis(const char *name, int flags); /// Load a vorbis file
extern CSample *LoadMp3(const char *name, int flags); /// Load a mp3 file
extern CSample *LoadMikMod(const char *name, int flags); /// Load a module file
/// Set the channel volume

View file

@ -26,7 +26,7 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
MODULE = src/sound
MSRC = script_sound.cpp flac.cpp mad.cpp mikmod.cpp music.cpp ogg.cpp \
MSRC = script_sound.cpp mikmod.cpp music.cpp ogg.cpp \
sound.cpp sound_id.cpp sound_server.cpp unitsound.cpp wav.cpp
SRC += $(addprefix $(MODULE)/,$(MSRC))

View file

@ -1,369 +0,0 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name flac.cpp - flac support */
//
// (c) Copyright 2002-2005 by Lutz Sammer, Fabrice Rossi and Nehal Mistry
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; only version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
// $Id$
//@{
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
#include "stratagus.h"
#ifdef USE_FLAC // {
#include <stdlib.h>
#include <string.h>
#include "FLAC/stream_decoder.h"
#include "myendian.h"
#include "iolib.h"
#include "sound_server.h"
/*----------------------------------------------------------------------------
-- Declaration
----------------------------------------------------------------------------*/
/**
** Private flac data structure to handle flac streaming.
*/
struct FlacData {
FLAC__StreamDecoder *FlacStream; /// Decoder stream
CFile *FlacFile; /// File handle
};
class CSampleFlac : public CSample
{
public:
~CSampleFlac();
int Read(void *buf, int len);
FlacData Data;
};
class CSampleFlacStream : public CSample
{
public:
~CSampleFlacStream();
int Read(void *buf, int len);
FlacData Data;
};
struct FlacUserData {
CSample *Sample;
FlacData *Data;
};
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/**
** Read callback from FLAC stream decoder.
**
** @param stream Decoder stream.
** @param status Error state.
** @param user User data.
*/
static void FLAC_error_callback(const FLAC__StreamDecoder *stream,
FLAC__StreamDecoderErrorStatus status, void *user)
{
DebugPrint(" %s\n" _C_ FLAC__StreamDecoderErrorStatusString[status]);
}
/**
** Read callback from FLAC stream decoder.
**
** @param stream Decoder stream.
** @param buffer Buffer to be filled.
** @param bytes Number of bytes to be filled.
** @param user User data.
**
** @return Error status.
*/
static FLAC__StreamDecoderReadStatus FLAC_read_callback(
const FLAC__StreamDecoder *stream, FLAC__byte buffer[],
unsigned int *bytes, void *user)
{
CSample *sample;
FlacData *data;
unsigned int i;
sample = ((FlacUserData *)user)->Sample;
data = ((FlacUserData *)user)->Data;
if ((i = data->FlacFile->read(buffer, *bytes)) != *bytes) {
*bytes = i;
if (!i) {
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
}
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
/**
** Write callback from FLAC stream decoder.
**
** @param stream Decoder stream.
** @param metadata metadata block
** @param user User data.
*/
static void FLAC_metadata_callback(const FLAC__StreamDecoder *stream,
const FLAC__StreamMetadata *metadata, void *user)
{
CSample *sample;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
sample = ((FlacUserData *)user)->Sample;
sample->Channels = metadata->data.stream_info.channels;
sample->Frequency = metadata->data.stream_info.sample_rate;
sample->SampleSize = metadata->data.stream_info.bits_per_sample;
if (!sample->Buffer) {
Assert(metadata->data.stream_info.total_samples);
sample->Buffer = new unsigned char[metadata->data.stream_info.total_samples * 4];
}
}
}
/**
** Write callback from FLAC stream decoder.
**
** @param stream Decoder stream.
** @param frame Frame to decode.
** @param buffer Buffer to be filled.
** @param user User data.
**
** @return Error status.
*/
static FLAC__StreamDecoderWriteStatus FLAC_write_callback(
const FLAC__StreamDecoder *stream, const FLAC__Frame *frame,
const FLAC__int32 *const buffer[], void *user)
{
CSample *sample;
FlacData *data;
unsigned int i;
int j;
char *buf;
int ssize;
sample = ((FlacUserData *)user)->Sample;
data = ((FlacUserData *)user)->Data;
Assert(sample->Buffer);
Assert(frame->header.bits_per_sample == sample->SampleSize);
ssize = (frame->header.bits_per_sample / 8);
buf = new char[frame->header.blocksize * sample->Channels * ssize];
// FIXME: mono flac files don't play correctly
// FLAC splits it up the channels, we need to sew it back together
for (i = 0; i < frame->header.blocksize; ++i) {
for (j = 0; j < sample->Channels; ++j) {
if (ssize == 1) {
buf[i * sample->Channels + j] = ((const char *)buffer[j])[i];
} else {
buf[i * 2 * sample->Channels + j * 2] = ((const char *)buffer[j])[i * 2];
buf[i * 2 * sample->Channels + j * 2 + 1] = ((const char *)buffer[j])[i * 2 + 1];
}
}
}
memcpy(sample->Buffer + sample->Pos + sample->Len, buf,
frame->header.blocksize * sample->Channels * ssize);
sample->Len += frame->header.blocksize * sample->Channels * ssize;
delete[] buf;
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
/**
** Type member function to read from the flac file
**
** @param buf Buffer to write data to
** @param len Length of the buffer
**
** @return Number of bytes read
*/
int CSampleFlacStream::Read(void *buf, int len)
{
if (this->Pos > SOUND_BUFFER_SIZE / 2) {
memcpy(this->Buffer, this->Buffer + this->Pos, this->Len);
this->Pos = 0;
}
while (this->Len < SOUND_BUFFER_SIZE / 4 &&
FLAC__stream_decoder_get_state(this->Data.FlacStream) != FLAC__STREAM_DECODER_END_OF_STREAM) {
// need to read new data
FLAC__stream_decoder_process_single(this->Data.FlacStream);
}
if (this->Len < len) {
len = this->Len;
}
memcpy(buf, this->Buffer + this->Pos, len);
this->Pos += len;
this->Len -= len;
return len;
}
/**
** Type member function to free an flac file
*/
CSampleFlacStream::~CSampleFlacStream()
{
this->Data.FlacFile->close();
delete this->Data.FlacFile;
FLAC__stream_decoder_finish(this->Data.FlacStream);
FLAC__stream_decoder_delete(this->Data.FlacStream);
delete[] this->Buffer;
}
/**
** Type member function to read from the flac file
**
** @param buf Buffer to write data to
** @param len Length of the buffer
**
** @return Number of bytes read
*/
int CSampleFlac::Read(void *buf, int len)
{
if (len > this->Len) {
len = this->Len;
}
memcpy(buf, this->Buffer + this->Pos, len);
this->Pos += len;
this->Len -= len;
return len;
}
/**
** Type member function to free an flac file
*/
CSampleFlac::~CSampleFlac()
{
delete[] this->Buffer;
}
/**
** Load flac.
**
** @param name File name.
** @param flags Load flags.
**
** @return Returns the loaded sample.
*/
CSample *LoadFlac(const char *name, int flags)
{
CSample *sample;
FlacData *data;
CFile *f;
unsigned int magic[1];
FLAC__StreamDecoder *stream;
f = new CFile;
if (f->open(name, CL_OPEN_READ) == -1) {
fprintf(stderr, "Can't open file `%s'\n", name);
delete f;
return NULL;
}
f->read(magic, sizeof(magic));
if (AccessLE32(magic) != 0x43614C66) { // "fLaC" in ASCII
f->close();
delete f;
return NULL;
}
f->seek(0, SEEK_SET);
if (!(stream = FLAC__stream_decoder_new())) {
fprintf(stderr, "Can't initialize flac decoder\n");
f->close();
delete f;
return NULL;
}
if (flags & PlayAudioStream) {
sample = new CSampleFlacStream;
data = &((CSampleFlacStream *)sample)->Data;
} else {
sample = new CSampleFlac;
data = &((CSampleFlac *)sample)->Data;
}
data->FlacFile = f;
data->FlacStream = stream;
sample->Len = 0;
sample->Pos = 0;
FLAC__stream_decoder_set_read_callback(stream, FLAC_read_callback);
FLAC__stream_decoder_set_write_callback(stream, FLAC_write_callback);
FLAC__stream_decoder_set_metadata_callback(stream, FLAC_metadata_callback);
FLAC__stream_decoder_set_error_callback(stream, FLAC_error_callback);
FlacUserData d = { sample, data };
FLAC__stream_decoder_set_client_data(stream, &d);
FLAC__stream_decoder_init(stream);
if (flags & PlayAudioStream) {
sample->Buffer = new unsigned char[SOUND_BUFFER_SIZE];
FLAC__stream_decoder_process_until_end_of_metadata(stream);
} else {
// Buffer will be new'ed from metadata callback
sample->Buffer = NULL;
Assert(FLAC__stream_decoder_get_state(stream) ==
FLAC__STREAM_DECODER_SEARCH_FOR_METADATA);
FLAC__stream_decoder_process_until_end_of_stream(stream);
Assert(FLAC__stream_decoder_get_state(stream) ==
FLAC__STREAM_DECODER_END_OF_STREAM);
FLAC__stream_decoder_finish(stream);
FLAC__stream_decoder_delete(stream);
f->close();
delete f;
}
return sample;
}
#endif // USE_FLAC
//@}

View file

@ -1,479 +0,0 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name mad.cpp - mp3 support with libmad */
//
// (c) Copyright 2002-2005 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; only version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
// $Id$
//@{
/*----------------------------------------------------------------------------
-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
#include "stratagus.h"
#ifdef USE_MAD // {
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "mad.h"
#include "iolib.h"
#include "sound_server.h"
/*----------------------------------------------------------------------------
-- Declaration
----------------------------------------------------------------------------*/
#define MAD_INBUF_SIZE 65536
/**
** Private mp3 data structure to handle mp3 streaming.
*/
struct MadData {
struct mad_decoder MadDecoder; /// Mad decoder handle
CFile *MadFile; /// File handle
unsigned char Buffer[MAD_INBUF_SIZE]; /// Input buffer
int BufferLen; /// Length of filled buffer
};
class CSampleMad : public CSample
{
public:
~CSampleMad();
int Read(void *buf, int len);
MadData Data;
};
class CSampleMadStream : public CSample
{
public:
~CSampleMadStream();
int Read(void *buf, int len);
MadData Data;
};
struct MadUserData {
CSample *Sample;
MadData *Data;
};
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/**
** MAD read callback.
**
** @param user Our user pointer.
** @param stream MP3 stream.
**
** @return MAP_FLOW_STOP if eof, MAD_FLOW_CONTINUE otherwise.
*/
static enum mad_flow MAD_read(void *user, struct mad_stream *stream)
{
CSample *sample;
MadData *data;
int i;
sample = ((MadUserData *)user)->Sample;
data = ((MadUserData *)user)->Data;
if (stream->next_frame) {
memmove(data->Buffer, stream->next_frame, data->BufferLen =
&data->Buffer[data->BufferLen] - stream->next_frame);
}
i = data->MadFile->read(data->Buffer + data->BufferLen, MAD_INBUF_SIZE - data->BufferLen);
if (!i) {
return MAD_FLOW_STOP;
}
data->BufferLen += i;
mad_stream_buffer(stream, data->Buffer, data->BufferLen);
return MAD_FLOW_CONTINUE;
}
/**
** This is the output callback function. It is called after each frame of
** MPEG audio data has been completely decoded. The purpose of this
** callback is to output the decoded PCM audio.
**
** @param user User argument.
** @param header MAD header.
** @param pcm MAD pcm data struture.
*/
static enum mad_flow MAD_write(void *user,
struct mad_header const *header, struct mad_pcm *pcm)
{
CSample *sample;
int i;
int j;
int n;
short *buf;
int s;
int comp;
sample = ((MadUserData *)user)->Sample;
n = pcm->length;
if (!sample->SampleSize) {
sample->Frequency = pcm->samplerate;
sample->Channels = pcm->channels;
sample->SampleSize = 16;
}
comp = n * pcm->channels * 2;
buf = (short *)(sample->Buffer + sample->Pos + sample->Len);
for (i = 0; i < n; ++i) {
for (j = 0; j < sample->Channels; ++j) {
s = pcm->samples[j][i];
// round
s += (1L << (MAD_F_FRACBITS - 16));
// clip
if (s >= MAD_F_ONE) {
s = MAD_F_ONE - 1;
} else if (s < -MAD_F_ONE) {
s = -MAD_F_ONE;
}
// quantize
s >>= (MAD_F_FRACBITS + 1 - 16);
buf[i * sample->Channels + j] = s;
}
}
sample->Len += comp;
return MAD_FLOW_CONTINUE;
}
/**
** This is the error callback function. It is called whenever a decoding
** error occurs. The error is indicated by stream->error; the list of
** possible MAD_ERROR_* errors can be found in the mad.h (or
** libmad/stream.h) header file.
*/
static enum mad_flow MAD_error(void *user,
struct mad_stream *stream, struct mad_frame *frame)
{
fprintf(stderr, "decoding error 0x%04x (%s)\n",
stream->error, mad_stream_errorstr(stream));
return MAD_FLOW_BREAK;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/**
** Read one frame from mad decoder.
**
** @param sample Sample
** @param data Mad data
** @param buf Buffer to write data to
** @param len Length of the buffer
**
** @return Number of bytes read
*/
static int MadRead(CSample *sample, MadData *data, unsigned char *buf, int len)
{
struct mad_decoder *decoder;
struct mad_stream *stream;
struct mad_frame *frame;
struct mad_synth *synth;
decoder = &data->MadDecoder;
DebugPrint("%p %p %d\n" _C_ decoder _C_ buf _C_ len);
stream = &decoder->sync->stream;
frame = &decoder->sync->frame;
synth = &decoder->sync->synth;
DebugPrint("Error: %d\n" _C_ stream->error);
MadUserData d = { sample, data };
MAD_read(&d, stream);
if (mad_frame_decode(frame, stream) == -1) {
Assert(0);
}
mad_synth_frame(synth, frame);
decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm);
return 0;
do {
DebugPrint("Read stream\n");
switch (MAD_read(decoder->cb_data, stream)) {
case MAD_FLOW_STOP:
return 0;
case MAD_FLOW_BREAK:
return -1;
case MAD_FLOW_IGNORE:
continue;
case MAD_FLOW_CONTINUE:
break;
}
while (1) {
if (mad_frame_decode(frame, stream) == -1) {
if (!MAD_RECOVERABLE(stream->error)) {
break;
}
switch (MAD_error(decoder->cb_data, stream, frame)) {
case MAD_FLOW_STOP:
return 0;
case MAD_FLOW_BREAK:
return -1;
case MAD_FLOW_IGNORE:
break;
case MAD_FLOW_CONTINUE:
default:
continue;
}
}
mad_synth_frame(synth, frame);
#if 0
// FIXME: write out the frame buffer!
switch (decoder->output_func(decoder->cb_data, &frame->header,
&synth->pcm)) {
case MAD_FLOW_STOP:
return 0;
case MAD_FLOW_BREAK:
return -1;
case MAD_FLOW_IGNORE:
case MAD_FLOW_CONTINUE:
break;
}
#endif
}
// Should stop here!
} while (stream->error == MAD_ERROR_BUFLEN);
return -1;
}
/**
** Type member function to read from the mp3 file
**
** @param buf Buffer to write data to
** @param len Length of the buffer
**
** @return Number of bytes read
*/
int CSampleMadStream::Read(void *buf, int len)
{
int i;
int n;
int divide;
unsigned char sndbuf[SOUND_BUFFER_SIZE];
DebugPrint("%p %d\n" _C_ buf _C_ len);
if (this->Pos > SOUND_BUFFER_SIZE / 2) {
memcpy(this->Buffer, this->Buffer + this->Pos, this->Len);
this->Pos = 0;
}
divide = 176400 / (this->Frequency * 2 * this->Channels);
while (this->Len < SOUND_BUFFER_SIZE / 4) {
// not enough in buffer, read more
n = (SOUND_BUFFER_SIZE - this->Len) / divide;
i = MadRead(this, &this->Data, sndbuf, n);
if (i <= 0) {
break;
}
this->Len += i;
}
if (this->Len < len) {
len = this->Len;
}
memcpy(buf, this->Buffer + this->Pos, len);
this->Pos += len;
this->Len -= len;
return len;
}
/**
** Type member function to free an mp3 file
*/
CSampleMadStream::~CSampleMadStream()
{
// release the decoder
mad_synth_finish(this->Data.MadDecoder.sync->synth);
mad_frame_finish(&this->Data.MadDecoder.sync->frame);
mad_stream_finish(&this->Data.MadDecoder.sync->stream);
// delete this->Data.MadDecoder.sync;
mad_decoder_finish(&this->Data.MadDecoder);
this->Data.MadFile->close();
delete this->Data.MadFile;
}
/**
** Type member function to read from the mp3 file
**
** @param buf Buffer to write data to
** @param len Length of the buffer
**
** @return Number of bytes read
*/
int CSampleMad::Read(void *buf, int len)
{
if (len > this->Len) {
len = this->Len;
}
memcpy(buf, this->Buffer + this->Pos, len);
this->Pos += len;
this->Len -= len;
return len;
}
/**
** Type member function to free an mp3 file
*/
CSampleMad::~CSampleMad()
{
delete[] this->Buffer;
}
/**
** Load mp3.
**
** @param name File name.
** @param flags Load flags.
**
** @return Returns the loaded sample.
*/
CSample *LoadMp3(const char *name, int flags)
{
CFile *f;
unsigned char magic[2];
CSample *sample;
MadData *data;
f = new CFile;
if (f->open(name, CL_OPEN_READ) == -1) {
fprintf(stderr, "Can't open file `%s'\n", name);
delete f;
return NULL;
}
f->read(magic, sizeof(magic));
// 0xFF 0xE? for mp3 stream
if (magic[0] != 0xFF || (magic[1]&0xE0) != 0xE0) {
f->close();
delete f;
return NULL;
}
f->seek(0, SEEK_SET);
if (0 && flags & PlayAudioStream) {
sample = new CSampleMadStream;
data = &((CSampleMadStream *)sample)->Data;
} else {
sample = new CSampleMad;
data = &((CSampleMad *)sample)->Data;
}
data->MadFile = f;
data->BufferLen = 0;
sample->Len = 0;
sample->Pos = 0;
sample->SampleSize = 0;
// streaming currently broken
if (0 && flags & PlayAudioStream) {
#if 0
sample->SampleSize = 0;
// configure input, output, and error functions
mad_decoder_init(&data->MadDecoder, sample,
MAD_read, NULL /* header */, NULL /* filter */, MAD_write,
MAD_error, NULL /* message */);
data->MadDecoder.sync = malloc(sizeof(*data->MadDecoder.sync));
mad_stream_init(&data->MadDecoder.sync->stream);
mad_frame_init(&data->MadDecoder.sync->frame);
mad_synth_init(&data->MadDecoder.sync->synth);
mad_stream_options(&data->MadDecoder.sync->stream,
data->MadDecoder.options);
MadRead(sample, &sample->Data, sample->Buffer, SOUND_BUFFER_SIZE);
#endif
} else {
// FIXME: surely there's a better way to do this
sample->Buffer = new unsigned char[55000000];
Assert(sample->Buffer);
// configure input, output, and error functions
MadUserData d = { sample, data };
mad_decoder_init(&data->MadDecoder, &d,
MAD_read, NULL /* header */, NULL /* filter */, MAD_write,
MAD_error, NULL /* message */);
mad_decoder_run(&data->MadDecoder, MAD_DECODER_MODE_SYNC);
// release the decoder
mad_decoder_finish(&data->MadDecoder);
f->close();
delete f;
DebugPrint(" %d\n" _C_ sample->Len);
}
return sample;
}
#endif // USE_MAD
//@}

View file

@ -393,7 +393,6 @@ void SetSoundRange(CSound *sound, unsigned char range)
** @return the sound unique identifier
**
** @todo FIXME: Must handle the errors better.
** FIXME: Support for more sample files (ogg/flac/mp3).
*/
CSound *RegisterSound(const char *files[], unsigned number)
{

View file

@ -517,16 +517,6 @@ CSample *LoadSample(const char *name)
return sample;
}
#endif
#ifdef USE_FLAC
if ((sample = LoadFlac(buf, PlayAudioLoadInMemory))) {
return sample;
}
#endif
#ifdef USE_MAD
if ((sample = LoadMp3(buf, PlayAudioLoadInMemory))) {
return sample;
}
#endif
#ifdef USE_MIKMOD
if ((sample = LoadMikMod(buf, PlayAudioLoadInMemory))) {
return sample;
@ -682,16 +672,6 @@ int PlayMusic(const char *file)
sample = LoadVorbis(name, PlayAudioStream);
}
#endif
#ifdef USE_MAD
if (!sample) {
sample = LoadMp3(name, PlayAudioStream);
}
#endif
#ifdef USE_FLAC
if (!sample) {
sample = LoadFlac(name, PlayAudioStream);
}
#endif
#ifdef USE_MIKMOD
if (!sample) {
sample = LoadMikMod(name, PlayAudioStream);

View file

@ -95,7 +95,7 @@
** @see script_sound.cpp @see sound_id.cpp @see sound_server.cpp
** @see unitsound.cpp
** @see sdl_audio.cpp
** @see mad.cpp @see ogg.cpp @see flac.cpp @see wav.cpp
** @see ogg.cpp @see wav.cpp
**
** @subsection Video Video
**
@ -901,18 +901,12 @@ int main(int argc, char **argv)
#ifdef USE_BZ2LIB
"BZ2LIB "
#endif
#ifdef USE_FLAC
"FLAC "
#endif
#ifdef USE_VORBIS
"VORBIS "
#endif
#ifdef USE_THEORA
"THEORA "
#endif
#ifdef USE_MAD
"MP3 "
#endif
#ifdef USE_MIKMOD
"MIKMOD "
#endif

View file

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "src\include" /I "include" /I "src\guichan\include" /D "NDEBUG" /D "USE_WIN32" /D "USE_MNG" /D "USE_ZLIB" /D "USE_BZ2LIB" /D "USE_MIKMOD" /D "USE_VORBIS" /D "USE_THEORA" /D "USE_MAD" /D "USE_FLAC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "src\include" /I "include" /I "src\guichan\include" /D "NDEBUG" /D "USE_WIN32" /D "USE_MNG" /D "USE_ZLIB" /D "USE_BZ2LIB" /D "USE_MIKMOD" /D "USE_VORBIS" /D "USE_THEORA" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib opengl32.lib SDL.lib SDLmain.lib zlib.lib libbz2.lib libpng.lib lua.lib ogg_static.lib vorbis_static.lib mikmod.lib libFLAC_static.lib libmad.lib theora_static.lib libmng.lib /nologo /stack:0x2000000 /subsystem:windows /profile /machine:I386 /libpath:"lib"
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib opengl32.lib SDL.lib SDLmain.lib zlib.lib libbz2.lib libpng.lib lua.lib ogg_static.lib vorbis_static.lib mikmod.lib theora_static.lib libmng.lib /nologo /stack:0x2000000 /subsystem:windows /profile /machine:I386 /libpath:"lib"
!ELSEIF "$(CFG)" == "stratagus - Win32 Debug"
@ -69,7 +69,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "src\include" /I "include" /I "src\guichan\include" /D "_DEBUG" /D "DEBUG" /D "USE_WIN32" /D "USE_MNG" /D "USE_ZLIB" /D "USE_BZ2LIB" /D "USE_MIKMOD" /D "USE_VORBIS" /D "USE_THEORA" /D "USE_MAD" /D "USE_FLAC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "src\include" /I "include" /I "src\guichan\include" /D "_DEBUG" /D "DEBUG" /D "USE_WIN32" /D "USE_MNG" /D "USE_ZLIB" /D "USE_BZ2LIB" /D "USE_MIKMOD" /D "USE_VORBIS" /D "USE_THEORA" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@ -79,7 +79,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib opengl32.lib SDL.lib SDLmain.lib zlib.lib libbz2.lib libpng.lib lua.lib ogg_static.lib vorbis_static.lib mikmod.lib libFLAC_static.lib libmad.lib theora_static.lib libmng.lib /nologo /stack:0x2000000 /subsystem:windows /debug /machine:I386 /nodefaultlib:"MSVCRT" /libpath:"lib"
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib opengl32.lib SDL.lib SDLmain.lib zlib.lib libbz2.lib libpng.lib lua.lib ogg_static.lib vorbis_static.lib mikmod.lib theora_static.lib libmng.lib /nologo /stack:0x2000000 /subsystem:windows /debug /machine:I386 /nodefaultlib:"MSVCRT" /libpath:"lib"
# SUBTRACT LINK32 /profile
!ENDIF
@ -487,14 +487,6 @@ SOURCE=.\src\pathfinder\script_pathfinder.cpp
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sound\flac.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sound\mad.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sound\mikmod.cpp
# End Source File
# Begin Source File