|
|
@@ -4,20 +4,23 @@ |
|
#include "stream.h"
|
|
#include "stream.h"
|
|
#include "sampman.h"
|
|
#include "sampman.h"
|
|
|
|
|
|
#ifdef AUDIO_OPUS
|
|
|
|
#include <opusfile.h>
|
|
|
|
#else
|
|
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
#pragma comment( lib, "libsndfile-1.lib" )
|
|
#pragma comment( lib, "libsndfile-1.lib" )
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef AUDIO_OAL_USE_MPG123
|
|
#pragma comment( lib, "libmpg123-0.lib" )
|
|
#pragma comment( lib, "libmpg123-0.lib" )
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
#include <sndfile.h>
|
|
#include <sndfile.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef AUDIO_OAL_USE_MPG123
|
|
#include <mpg123.h>
|
|
#include <mpg123.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef AUDIO_OAL_USE_OPUS
|
|
|
|
#include <opusfile.h>
|
|
|
|
#endif
|
|
|
|
|
|
#ifndef _WIN32
|
|
#ifndef _WIN32
|
|
#include "crossplatform.h"
|
|
#include "crossplatform.h"
|
|
|
@@ -81,7 +84,6 @@ class CSortStereoBuffer |
|
|
|
|
|
CSortStereoBuffer SortStereoBuffer;
|
|
CSortStereoBuffer SortStereoBuffer;
|
|
|
|
|
|
#ifndef AUDIO_OPUS
|
|
|
|
class CImaADPCMDecoder
|
|
class CImaADPCMDecoder
|
|
{
|
|
{
|
|
const uint16 StepTable[89] = {
|
|
const uint16 StepTable[89] = {
|
|
|
@@ -461,11 +463,9 @@ class CSndFile : public IDecoder |
|
};
|
|
};
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef _WIN32
|
|
#ifdef AUDIO_OAL_USE_MPG123
|
|
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though)
|
|
// fuzzy seek eliminates stutter when playing ADF but spams errors a lot (nothing breaks though)
|
|
#define MP3_USE_FUZZY_SEEK
|
|
#define MP3_USE_FUZZY_SEEK
|
|
#endif // _WIN32
|
|
|
|
|
|
|
|
|
|
|
|
class CMP3File : public IDecoder
|
|
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_LINE_SIZE (0x10)
|
|
#define VAG_SAMPLES_IN_LINE (28)
|
|
#define VAG_SAMPLES_IN_LINE (28)
|
|
|
|
|
|
|
@@ -811,7 +860,7 @@ class CVbFile : public IDecoder |
|
return bufSizePerChannel * m_nChannels;
|
|
return bufSizePerChannel * m_nChannels;
|
|
}
|
|
}
|
|
};
|
|
};
|
|
#else
|
|
#ifdef AUDIO_OAL_USE_OPUS
|
|
class COpusFile : public IDecoder
|
|
class COpusFile : public IDecoder
|
|
{
|
|
{
|
|
OggOpusFile *m_FileH;
|
|
OggOpusFile *m_FileH;
|
|
|
@@ -907,64 +956,16 @@ class COpusFile : public IDecoder |
|
};
|
|
};
|
|
#endif
|
|
#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()
|
|
void CStream::Initialise()
|
|
{
|
|
{
|
|
#ifndef AUDIO_OPUS
|
|
#ifdef AUDIO_OAL_USE_MPG123
|
|
mpg123_init();
|
|
mpg123_init();
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
void CStream::Terminate()
|
|
void CStream::Terminate()
|
|
{
|
|
{
|
|
#ifndef AUDIO_OPUS
|
|
#ifdef AUDIO_OAL_USE_MPG123
|
|
mpg123_exit();
|
|
mpg123_exit();
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
@@ -997,21 +998,22 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU |
|
|
|
|
|
DEV("Stream %s\n", m_aFilename);
|
|
DEV("Stream %s\n", m_aFilename);
|
|
|
|
|
|
#ifndef AUDIO_OPUS
|
|
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav"))
|
|
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"))
|
|
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
#ifdef AUDIO_OAL_USE_SNDFILE
|
|
m_pSoundFile = new CSndFile(m_aFilename);
|
|
m_pSoundFile = new CSndFile(m_aFilename);
|
|
#else
|
|
#else
|
|
m_pSoundFile = new CWavFile(m_aFilename);
|
|
m_pSoundFile = new CWavFile(m_aFilename);
|
|
#endif
|
|
#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"))
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf"))
|
|
m_pSoundFile = new CADFFile(m_aFilename);
|
|
m_pSoundFile = new CADFFile(m_aFilename);
|
|
|
|
#endif
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB"))
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".vb")], ".VB"))
|
|
m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate);
|
|
m_pSoundFile = new CVbFile(m_aFilename, overrideSampleRate);
|
|
#else
|
|
#ifdef AUDIO_OAL_USE_OPUS
|
|
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus"))
|
|
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus"))
|
|
m_pSoundFile = new COpusFile(m_aFilename);
|
|
m_pSoundFile = new COpusFile(m_aFilename);
|
|
#endif
|
|
#endif
|
|
else
|
|
else
|
|
|
|