|
|
@@ -4,20 +4,23 @@ |
|
|
#include "stream.h" |
|
|
#include "sampman.h" |
|
|
|
|
|
#ifdef AUDIO_OPUS |
|
|
#include <opusfile.h> |
|
|
#else |
|
|
#ifdef _WIN32 |
|
|
#ifdef AUDIO_OAL_USE_SNDFILE |
|
|
#pragma comment( lib, "libsndfile-1.lib" ) |
|
|
#endif |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
#pragma comment( lib, "libmpg123-0.lib" ) |
|
|
#endif |
|
|
#endif |
|
|
#ifdef AUDIO_OAL_USE_SNDFILE |
|
|
#include <sndfile.h> |
|
|
#endif |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
#include <mpg123.h> |
|
|
#endif |
|
|
#ifdef AUDIO_OAL_USE_OPUS |
|
|
#include <opusfile.h> |
|
|
#endif |
|
|
|
|
|
#ifndef _WIN32 |
|
|
#include "crossplatform.h" |
|
|
@@ -81,7 +84,6 @@ class CSortStereoBuffer |
|
|
|
|
|
CSortStereoBuffer SortStereoBuffer; |
|
|
|
|
|
#ifndef AUDIO_OPUS |
|
|
class CImaADPCMDecoder |
|
|
{ |
|
|
const uint16 StepTable[89] = { |
|
|
@@ -461,11 +463,9 @@ class CSndFile : public IDecoder |
|
|
}; |
|
|
#endif |
|
|
|
|
|
#ifdef _WIN32 |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though) |
|
|
#define MP3_USE_FUZZY_SEEK |
|
|
#endif // _WIN32 |
|
|
|
|
|
|
|
|
class CMP3File : public IDecoder |
|
|
{ |
|
|
@@ -574,6 +574,55 @@ class CMP3File : public IDecoder |
|
|
} |
|
|
}; |
|
|
|
|
|
class CADFFile : public CMP3File |
|
|
{ |
|
|
static ssize_t r_read(void* fh, void* buf, size_t size) |
|
|
{ |
|
|
size_t bytesRead = fread(buf, 1, size, (FILE*)fh); |
|
|
uint8* _buf = (uint8*)buf; |
|
|
for (size_t i = 0; i < size; i++) |
|
|
_buf[i] ^= 0x22; |
|
|
return bytesRead; |
|
|
} |
|
|
static off_t r_seek(void* fh, off_t pos, int seekType) |
|
|
{ |
|
|
fseek((FILE*)fh, pos, seekType); |
|
|
return ftell((FILE*)fh); |
|
|
} |
|
|
static void r_close(void* fh) |
|
|
{ |
|
|
fclose((FILE*)fh); |
|
|
} |
|
|
public: |
|
|
CADFFile(const char* path) |
|
|
{ |
|
|
m_pMH = mpg123_new(nil, nil); |
|
|
if (m_pMH) |
|
|
{ |
|
|
#ifdef MP3_USE_FUZZY_SEEK |
|
|
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS | MPG123_QUIET, 0.0); |
|
|
#endif |
|
|
long rate = 0; |
|
|
int channels = 0; |
|
|
int encoding = 0; |
|
|
|
|
|
FILE* f = fopen(path, "rb"); |
|
|
|
|
|
m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK |
|
|
&& mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; |
|
|
m_nRate = rate; |
|
|
m_nChannels = channels; |
|
|
|
|
|
if (IsOpened()) |
|
|
{ |
|
|
mpg123_format_none(m_pMH); |
|
|
mpg123_format(m_pMH, rate, channels, encoding); |
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
#endif |
|
|
#define VAG_LINE_SIZE (0x10) |
|
|
#define VAG_SAMPLES_IN_LINE (28) |
|
|
|
|
|
@@ -811,7 +860,7 @@ class CVbFile : public IDecoder |
|
|
return bufSizePerChannel * m_nChannels; |
|
|
} |
|
|
}; |
|
|
#else |
|
|
#ifdef AUDIO_OAL_USE_OPUS |
|
|
class COpusFile : public IDecoder |
|
|
{ |
|
|
OggOpusFile *m_FileH; |
|
|
@@ -907,64 +956,16 @@ class COpusFile : public IDecoder |
|
|
}; |
|
|
#endif |
|
|
|
|
|
class CADFFile : public CMP3File |
|
|
{ |
|
|
static ssize_t r_read(void* fh, void* buf, size_t size) |
|
|
{ |
|
|
size_t bytesRead = fread(buf, 1, size, (FILE*)fh); |
|
|
uint8* _buf = (uint8*)buf; |
|
|
for (size_t i = 0; i < size; i++) |
|
|
_buf[i] ^= 0x22; |
|
|
return bytesRead; |
|
|
} |
|
|
static off_t r_seek(void* fh, off_t pos, int seekType) |
|
|
{ |
|
|
fseek((FILE*)fh, pos, seekType); |
|
|
return ftell((FILE*)fh); |
|
|
} |
|
|
static void r_close(void* fh) |
|
|
{ |
|
|
fclose((FILE*)fh); |
|
|
} |
|
|
public: |
|
|
CADFFile(const char* path) |
|
|
{ |
|
|
m_pMH = mpg123_new(nil, nil); |
|
|
if (m_pMH) |
|
|
{ |
|
|
#ifdef MP3_USE_FUZZY_SEEK |
|
|
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0); |
|
|
#endif |
|
|
long rate = 0; |
|
|
int channels = 0; |
|
|
int encoding = 0; |
|
|
|
|
|
FILE* f = fopen(path, "rb"); |
|
|
|
|
|
m_bOpened = mpg123_replace_reader_handle(m_pMH, r_read, r_seek, r_close) == MPG123_OK |
|
|
&& mpg123_open_handle(m_pMH, f) == MPG123_OK && mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK; |
|
|
m_nRate = rate; |
|
|
m_nChannels = channels; |
|
|
|
|
|
if (IsOpened()) |
|
|
{ |
|
|
mpg123_format_none(m_pMH); |
|
|
mpg123_format(m_pMH, rate, channels, encoding); |
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
void CStream::Initialise() |
|
|
{ |
|
|
#ifndef AUDIO_OPUS |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
mpg123_init(); |
|
|
#endif |
|
|
} |
|
|
|
|
|
void CStream::Terminate() |
|
|
{ |
|
|
#ifndef AUDIO_OPUS |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
mpg123_exit(); |
|
|
#endif |
|
|
} |
|
|
@@ -997,21 +998,22 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU |
|
|
|
|
|
DEV("Stream %s\n", m_aFilename); |
|
|
|
|
|
#ifndef AUDIO_OPUS |
|
|
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) |
|
|
m_pSoundFile = new CMP3File(m_aFilename); |
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) |
|
|
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav")) |
|
|
#ifdef AUDIO_OAL_USE_SNDFILE |
|
|
m_pSoundFile = new CSndFile(m_aFilename); |
|
|
#else |
|
|
m_pSoundFile = new CWavFile(m_aFilename); |
|
|
#endif |
|
|
#ifdef AUDIO_OAL_USE_MPG123 |
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".mp3")], ".mp3")) |
|
|
m_pSoundFile = new CMP3File(m_aFilename); |
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf")) |
|
|
m_pSoundFile = new CADFFile(m_aFilename); |
|
|
#endif |
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB")) |
|
|
m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate); |
|
|
#else |
|
|
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) |
|
|
#ifdef AUDIO_OAL_USE_OPUS |
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus")) |
|
|
m_pSoundFile = new COpusFile(m_aFilename); |
|
|
#endif |
|
|
else |
|
|
|