summaryrefslogtreecommitdiffstats
path: root/src/audio/oal/stream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/oal/stream.cpp')
-rw-r--r--src/audio/oal/stream.cpp127
1 files changed, 118 insertions, 9 deletions
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 34518f54..34080514 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -4,8 +4,15 @@
#include "stream.h"
#include "sampman.h"
+#ifdef AUDIO_OPUS
+#include <opusfile.h>
+#else
#ifdef _WIN32
+
+// TODO: This is due to version difference of 32-bit libmpg123 and 64-bit libmpg123, fix it
+#ifndef _WIN64
typedef long ssize_t;
+#endif
#pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123.lib" )
#else
@@ -13,7 +20,9 @@ typedef long ssize_t;
#endif
#include <sndfile.h>
#include <mpg123.h>
+#endif
+#ifndef AUDIO_OPUS
class CSndFile : public IDecoder
{
SNDFILE *m_pfSound;
@@ -166,19 +175,118 @@ public:
size_t size;
int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
+#if defined(__LP64__) || defined(_WIN64)
+ assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX));
+#endif
if (err != MPG123_OK && err != MPG123_DONE) return 0;
- return size;
+ return (uint32)size;
}
};
+#else
+class COpusFile : public IDecoder
+{
+ OggOpusFile *m_FileH;
+ bool m_bOpened;
+ uint32 m_nRate;
+ uint32 m_nChannels;
+public:
+ COpusFile(const char *path) : m_FileH(nil),
+ m_bOpened(false),
+ m_nRate(0),
+ m_nChannels(0)
+ {
+ int ret;
+ m_FileH = op_open_file(path, &ret);
+
+ if (m_FileH) {
+ m_nChannels = op_head(m_FileH, 0)->channel_count;
+ m_nRate = op_head(m_FileH, 0)->input_sample_rate;
+ const OpusTags *tags = op_tags(m_FileH, 0);
+ for (int i = 0; i < tags->comments; i++) {
+ if (strncmp(tags->user_comments[i], "SAMPLERATE", sizeof("SAMPLERATE")-1) == 0)
+ {
+ sscanf(tags->user_comments[i], "SAMPLERATE=%i", &m_nRate);
+ break;
+ }
+ }
+
+ m_bOpened = true;
+ }
+ }
+
+ ~COpusFile()
+ {
+ if (m_FileH)
+ {
+ op_free(m_FileH);
+ m_FileH = nil;
+ }
+ }
+
+ bool IsOpened()
+ {
+ return m_bOpened;
+ }
+
+ uint32 GetSampleSize()
+ {
+ return sizeof(uint16);
+ }
+
+ uint32 GetSampleCount()
+ {
+ if ( !IsOpened() ) return 0;
+ return op_pcm_total(m_FileH, 0);
+ }
+
+ uint32 GetSampleRate()
+ {
+ return m_nRate;
+ }
+
+ uint32 GetChannels()
+ {
+ return m_nChannels;
+ }
+
+ void Seek(uint32 milliseconds)
+ {
+ if ( !IsOpened() ) return;
+ op_pcm_seek(m_FileH, ms2samples(milliseconds) * GetSampleSize());
+ }
+
+ uint32 Tell()
+ {
+ if ( !IsOpened() ) return 0;
+ return samples2ms(op_pcm_tell(m_FileH)/GetSampleSize());
+ }
+
+ uint32 Decode(void *buffer)
+ {
+ if ( !IsOpened() ) return 0;
+
+ int size = op_read(m_FileH, (opus_int16 *)buffer, GetBufferSamples(), NULL);
+
+ if (size < 0)
+ return 0;
+
+ return size * m_nChannels * GetSampleSize();
+ }
+};
+#endif
void CStream::Initialise()
{
+#ifndef AUDIO_OPUS
mpg123_init();
+#endif
}
void CStream::Terminate()
{
+#ifndef AUDIO_OPUS
mpg123_exit();
+#endif
}
CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
@@ -196,15 +304,11 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
{
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
- FILE *test = fopen(filename, "r");
- if (!test) {
- char *r = (char*)alloca(strlen(filename) + 2);
- if (casepath(filename, r))
- {
- strcpy(m_aFilename, r);
- }
+ char *real = casepath(filename);
+ if (real) {
+ strcpy(m_aFilename, real);
+ free(real);
} else {
- fclose(test);
#else
{
#endif
@@ -213,10 +317,15 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
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"))
m_pSoundFile = new CSndFile(m_aFilename);
+#else
+ if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus"))
+ m_pSoundFile = new COpusFile(m_aFilename);
+#endif
else
m_pSoundFile = nil;
ASSERT(m_pSoundFile != nil);