summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio/oal/channel.cpp59
-rw-r--r--src/audio/oal/channel.h4
-rw-r--r--src/audio/oal/stream.cpp476
-rw-r--r--src/audio/oal/stream.h89
-rw-r--r--src/audio/sampman_oal.cpp71
-rw-r--r--src/core/common.h2
-rw-r--r--src/core/re3.cpp14
7 files changed, 608 insertions, 107 deletions
diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp
index d8b50161..7742a06a 100644
--- a/src/audio/oal/channel.cpp
+++ b/src/audio/oal/channel.cpp
@@ -1,20 +1,21 @@
#include "channel.h"
#ifdef AUDIO_OAL
+#include "common.h"
#include "sampman.h"
extern bool IsFXSupported();
CChannel::CChannel()
{
- alChannel = AL_NONE;
+ alSource = AL_NONE;
alFilter = AL_FILTER_NULL;
SetDefault();
}
void CChannel::SetDefault()
{
- Buffer = AL_NONE;
+ alBuffer = AL_NONE;
Pitch = 1.0f;
Gain = 1.0f;
@@ -37,17 +38,17 @@ void CChannel::Reset()
void CChannel::Init(bool Is2D)
{
ASSERT(!HasSource());
- alGenSources(1, &alChannel);
+ alGenSources(1, &alSource);
if ( HasSource() )
{
- alSourcei(alChannel, AL_SOURCE_RELATIVE, AL_TRUE);
+ alSourcei(alSource, AL_SOURCE_RELATIVE, AL_TRUE);
if ( IsFXSupported() )
- alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
if ( Is2D )
{
- alSource3f(alChannel, AL_POSITION, 0.0f, 0.0f, 0.0f);
- alSourcef (alChannel, AL_GAIN, 1.0f);
+ alSource3f(alSource, AL_POSITION, 0.0f, 0.0f, 0.0f);
+ alSourcef (alSource, AL_GAIN, 1.0f);
}
else
{
@@ -64,15 +65,15 @@ void CChannel::Term()
{
if ( IsFXSupported() )
{
- alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
if(alFilter != AL_FILTER_NULL)
alDeleteFilters(1,&alFilter);
}
- alDeleteSources(1, &alChannel);
+ alDeleteSources(1, &alSource);
}
- alChannel = AL_NONE;
+ alSource = AL_NONE;
alFilter = AL_FILTER_NULL;
}
@@ -81,22 +82,22 @@ void CChannel::Start()
if ( !HasSource() ) return;
if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 )
- alBufferiv(Buffer, AL_LOOP_POINTS_SOFT, LoopPoints);
- alSourcei (alChannel, AL_BUFFER, Buffer);
- alSourcePlay(alChannel);
+ alBufferiv(alBuffer, AL_LOOP_POINTS_SOFT, LoopPoints);
+ alSourcei (alSource, AL_BUFFER, alBuffer);
+ alSourcePlay(alSource);
}
void CChannel::Stop()
{
if ( HasSource() )
- alSourceStop(alChannel);
+ alSourceStop(alSource);
Reset();
}
bool CChannel::HasSource()
{
- return alChannel != AL_NONE;
+ return alSource != AL_NONE;
}
bool CChannel::IsUsed()
@@ -104,7 +105,7 @@ bool CChannel::IsUsed()
if ( HasSource() )
{
ALint sourceState;
- alGetSourcei(alChannel, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(alSource, AL_SOURCE_STATE, &sourceState);
return sourceState == AL_PLAYING;
}
return false;
@@ -113,13 +114,13 @@ bool CChannel::IsUsed()
void CChannel::SetPitch(float pitch)
{
if ( !HasSource() ) return;
- alSourcef(alChannel, AL_PITCH, pitch);
+ alSourcef(alSource, AL_PITCH, pitch);
}
void CChannel::SetGain(float gain)
{
if ( !HasSource() ) return;
- alSourcef(alChannel, AL_GAIN, gain);
+ alSourcef(alSource, AL_GAIN, gain);
}
void CChannel::SetVolume(int32 vol)
@@ -145,7 +146,7 @@ void CChannel::SetCurrentFreq(uint32 freq)
void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
{
if ( !HasSource() ) return;
- alSourcei(alChannel, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
+ alSourcei(alSource, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
}
void CChannel::SetLoopPoints(ALint start, ALint end)
@@ -157,33 +158,33 @@ void CChannel::SetLoopPoints(ALint start, ALint end)
void CChannel::SetPosition(float x, float y, float z)
{
if ( !HasSource() ) return;
- alSource3f(alChannel, AL_POSITION, x, y, z);
+ alSource3f(alSource, AL_POSITION, x, y, z);
}
void CChannel::SetDistances(float max, float min)
{
if ( !HasSource() ) return;
- alSourcef (alChannel, AL_MAX_DISTANCE, max);
- alSourcef (alChannel, AL_REFERENCE_DISTANCE, min);
- alSourcef (alChannel, AL_MAX_GAIN, 1.0f);
- alSourcef (alChannel, AL_ROLLOFF_FACTOR, 1.0f);
+ alSourcef (alSource, AL_MAX_DISTANCE, max);
+ alSourcef (alSource, AL_REFERENCE_DISTANCE, min);
+ alSourcef (alSource, AL_MAX_GAIN, 1.0f);
+ alSourcef (alSource, AL_ROLLOFF_FACTOR, 1.0f);
}
void CChannel::SetPan(uint32 pan)
{
- SetPosition((pan-63)/64.0f, 0.0f, sqrtf(1.0f-SQR((pan-63)/64.0f)));
+ SetPosition((pan-63)/64.0f, 0.0f, Sqrt(1.0f-SQR((pan-63)/64.0f)));
}
void CChannel::SetBuffer(ALuint buffer)
{
- Buffer = buffer;
+ alBuffer = buffer;
}
void CChannel::ClearBuffer()
{
if ( !HasSource() ) return;
SetBuffer(AL_NONE);
- alSourcei(alChannel, AL_BUFFER, AL_NONE);
+ alSourcei(alSource, AL_BUFFER, AL_NONE);
}
void CChannel::SetReverbMix(ALuint slot, float mix)
@@ -194,7 +195,7 @@ void CChannel::SetReverbMix(ALuint slot, float mix)
Mix = mix;
EAX3_SetReverbMix(alFilter, mix);
- alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
}
void CChannel::UpdateReverb(ALuint slot)
@@ -203,7 +204,7 @@ void CChannel::UpdateReverb(ALuint slot)
if ( !HasSource() ) return;
if ( alFilter == AL_FILTER_NULL ) return;
EAX3_SetReverbMix(alFilter, Mix);
- alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+ alSource3i(alSource, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
}
#endif \ No newline at end of file
diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h
index d9ffea22..4dd09ca1 100644
--- a/src/audio/oal/channel.h
+++ b/src/audio/oal/channel.h
@@ -10,9 +10,9 @@
class CChannel
{
- ALuint alChannel;
+ ALuint alSource;
ALuint alFilter;
- ALuint Buffer;
+ ALuint alBuffer;
float Pitch, Gain;
float Mix;
int32 Frequency;
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index a65c9794..9bca0546 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -1,48 +1,223 @@
#include "stream.h"
-#include "common.h"
#ifdef AUDIO_OAL
+#include "common.h"
+#include "sampman.h"
+
+typedef long ssize_t;
+
+#include <sndfile.h>
+#include <mpg123.h>
+
+#pragma comment( lib, "libsndfile-1.lib" )
+#pragma comment( lib, "libmpg123.lib" )
+
+class CSndFile : public IDecoder
+{
+ SNDFILE *m_pfSound;
+ SF_INFO m_soundInfo;
+public:
+ CSndFile(const char *path) :
+ m_pfSound(nil)
+ {
+ memset(&m_soundInfo, 0, sizeof(m_soundInfo));
+ m_pfSound = sf_open(path, SFM_READ, &m_soundInfo);
+ }
+
+ ~CSndFile()
+ {
+ if ( m_pfSound )
+ {
+ sf_close(m_pfSound);
+ m_pfSound = nil;
+ }
+ }
+
+ bool IsOpened()
+ {
+ return m_pfSound != nil;
+ }
+
+ uint32 GetSampleSize()
+ {
+ return sizeof(uint16);
+ }
+
+ uint32 GetSampleCount()
+ {
+ return m_soundInfo.frames;
+ }
+
+ uint32 GetSampleRate()
+ {
+ return m_soundInfo.samplerate;
+ }
+
+ uint32 GetChannels()
+ {
+ return m_soundInfo.channels;
+ }
+
+ void Seek(uint32 milliseconds)
+ {
+ if ( !IsOpened() ) return;
+ sf_seek(m_pfSound, ms2samples(milliseconds), SF_SEEK_SET);
+ }
+
+ uint32 Tell()
+ {
+ if ( !IsOpened() ) return 0;
+ return samples2ms(sf_seek(m_pfSound, 0, SF_SEEK_CUR));
+ }
+
+ uint32 Decode(void *buffer)
+ {
+ if ( !IsOpened() ) return 0;
+ return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize();
+ }
+};
+
+class CMP3File : public IDecoder
+{
+ mpg123_handle *m_pMH;
+ bool m_bOpened;
+ uint32 m_nRate;
+ uint32 m_nChannels;
+public:
+ CMP3File(const char *path) :
+ m_pMH(nil),
+ m_bOpened(false),
+ m_nRate(0),
+ m_nChannels(0)
+ {
+ m_pMH = mpg123_new(nil, nil);
+ if ( m_pMH )
+ {
+ long rate = 0;
+ int channels = 0;
+ int encoding = 0;
+
+ m_bOpened = mpg123_open(m_pMH, path) == 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);
+ }
+ }
+ }
+
+ ~CMP3File()
+ {
+ if ( m_pMH )
+ {
+ mpg123_close(m_pMH);
+ mpg123_delete(m_pMH);
+ m_pMH = nil;
+ }
+ }
+
+ bool IsOpened()
+ {
+ return m_bOpened;
+ }
+
+ uint32 GetSampleSize()
+ {
+ return sizeof(uint16);
+ }
+
+ uint32 GetSampleCount()
+ {
+ if ( !IsOpened() ) return 0;
+ return mpg123_length(m_pMH);
+ }
+
+ uint32 GetSampleRate()
+ {
+ return m_nRate;
+ }
+
+ uint32 GetChannels()
+ {
+ return m_nChannels;
+ }
+
+ void Seek(uint32 milliseconds)
+ {
+ if ( !IsOpened() ) return;
+ mpg123_seek(m_pMH, ms2samples(milliseconds)*GetSampleSize(), SEEK_SET);
+ }
+
+ uint32 Tell()
+ {
+ if ( !IsOpened() ) return 0;
+ return samples2ms(mpg123_tell(m_pMH)/GetSampleSize());
+ }
+
+ uint32 Decode(void *buffer)
+ {
+ if ( !IsOpened() ) return 0;
+
+ size_t size;
+ int err = mpg123_read(m_pMH, (unsigned char *)buffer, GetBufferSize(), &size);
+ if (err != MPG123_OK && err != MPG123_DONE) return 0;
+ return size;
+ }
+};
void CStream::Initialise()
{
- //mpg123_init();
+ mpg123_init();
}
void CStream::Terminate()
{
- //mpg123_exit();
+ mpg123_exit();
}
CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
m_alSource(source),
m_alBuffers(buffers),
- m_nBitRate(0),
- m_nFormat(0),
- m_nFreq(0),
- m_nLength(0),
- m_nLengthMS(0),
- m_nBufferSize(0),
- m_pBuffer(NULL),
- m_bIsOpened(false),
- m_bPaused(true)
+ m_pBuffer(nil),
+ m_bPaused(false),
+ m_bActive(false),
+ m_pSoundFile(nil),
+ m_bReset(false),
+ m_nVolume(0),
+ m_nPan(0),
+ m_nPosBeforeReset(0)
{
strcpy(m_aFilename, filename);
- //DEV("Stream %s\n", m_aFilename);
-
- /*
- if ( true )
- {
- m_nBitRate = (wBitsPerSample * nChannels * wfex.nSamplesPerSec)/1000;
- m_nLength = ulDataSize;
- m_nLengthMS = m_nLength*8 / m_nBitRate;
- m_nBufferSize = nAvgBytesPerSec >> 2;
- m_nBufferSize -= (m_nLength % wfex.nBlockAlign);
- m_pBuffer = malloc(m_nBufferSize);
- m_bIsOpened = true;
+ DEV("Stream %s\n", m_aFilename);
+
+ 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
+ m_pSoundFile = nil;
+ ASSERT(m_pSoundFile != nil);
+ if (m_pSoundFile && m_pSoundFile->IsOpened() )
+ {
+ m_pBuffer = malloc(m_pSoundFile->GetBufferSize());
+ ASSERT(m_pBuffer!=nil);
+
+ DEV("AvgSamplesPerSec: %d\n", m_pSoundFile->GetAvgSamplesPerSec());
+ DEV("SampleCount: %d\n", m_pSoundFile->GetSampleCount());
+ DEV("SampleRate: %d\n", m_pSoundFile->GetSampleRate());
+ DEV("Channels: %d\n", m_pSoundFile->GetChannels());
+ DEV("Buffer Samples: %d\n", m_pSoundFile->GetBufferSamples());
+ DEV("Buffer sec: %f\n", (float(m_pSoundFile->GetBufferSamples()) / float(m_pSoundFile->GetChannels())/ float(m_pSoundFile->GetSampleRate())));
+ DEV("Length MS: %02d:%02d\n", (m_pSoundFile->GetLength() / 1000) / 60, (m_pSoundFile->GetLength() / 1000) % 60);
+
return;
- }*/
+ }
}
CStream::~CStream()
@@ -51,68 +226,295 @@ CStream::~CStream()
}
void CStream::Delete()
-{
+{
+ Stop();
+ ClearBuffers();
+
+ if ( m_pSoundFile )
+ {
+ delete m_pSoundFile;
+ m_pSoundFile = nil;
+ }
+
if ( m_pBuffer )
{
free(m_pBuffer);
- m_pBuffer = NULL;
+ m_pBuffer = nil;
}
}
+bool CStream::HasSource()
+{
+ return m_alSource != AL_NONE;
+}
+
bool CStream::IsOpened()
{
- return m_bIsOpened;
+ return m_pSoundFile->IsOpened();
}
bool CStream::IsPlaying()
{
+ if ( !HasSource() || !IsOpened() ) return false;
+
+ if ( m_pSoundFile->IsOpened() && !m_bPaused )
+ {
+ ALint sourceState;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if ( m_bActive || sourceState == AL_PLAYING )
+ return true;
+ }
+
return false;
}
+void CStream::Pause()
+{
+ if ( !HasSource() ) return;
+ ALint sourceState = AL_PAUSED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_PAUSED )
+ alSourcePause(m_alSource);
+}
+
void CStream::SetPause(bool bPause)
{
+ if ( !HasSource() ) return;
+ if ( bPause )
+ {
+ Pause();
+ m_bPaused = true;
+ }
+ else
+ {
+ if (m_bPaused)
+ SetPlay(true);
+ m_bPaused = false;
+ }
+}
+
+void CStream::SetPitch(float pitch)
+{
+ if ( !HasSource() ) return;
+ alSourcef(m_alSource, AL_PITCH, pitch);
+}
+
+void CStream::SetGain(float gain)
+{
+ if ( !HasSource() ) return;
+ alSourcef(m_alSource, AL_GAIN, gain);
+}
+
+void CStream::SetPosition(float x, float y, float z)
+{
+ if ( !HasSource() ) return;
+ alSource3f(m_alSource, AL_POSITION, x, y, z);
}
void CStream::SetVolume(uint32 nVol)
{
-
+ m_nVolume = nVol;
+ SetGain(ALfloat(nVol) / MAX_VOLUME);
}
void CStream::SetPan(uint8 nPan)
{
+ m_nPan = nPan;
+ SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f)));
}
-void CStream::SetPos(uint32 nPos)
+void CStream::SetPosMS(uint32 nPos)
{
+ if ( !m_pSoundFile->IsOpened() ) return;
+ m_pSoundFile->Seek(nPos);
+ ClearBuffers();
}
-uint32 CStream::GetPos()
+uint32 CStream::GetPosMS()
{
- return 0;
+ if ( !HasSource() ) return 0;
+ if ( !m_pSoundFile->IsOpened() ) return 0;
+
+ ALint offset;
+ //alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
+ alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset);
+
+ return m_pSoundFile->Tell()
+ - m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1))
+ + m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize());
}
-uint32 CStream::GetLength()
+uint32 CStream::GetLengthMS()
{
- return m_nLengthMS;
+ if ( !m_pSoundFile->IsOpened() ) return 0;
+ return m_pSoundFile->GetLength();
}
-bool CStream::Setup()
+bool CStream::FillBuffer(ALuint alBuffer)
{
- if ( !IsOpened() )
+ if ( !HasSource() )
return false;
-
+ if ( !m_pSoundFile->IsOpened() )
+ return false;
+ if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) )
+ return false;
+
+ uint32 size = m_pSoundFile->Decode(m_pBuffer);
+ if( size == 0 )
+ return false;
+
+ alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
+ m_pBuffer, size, m_pSoundFile->GetSampleRate());
+
+ return true;
+}
+
+int32 CStream::FillBuffers()
+{
+ int32 i = 0;
+ for ( i = 0; i < NUM_STREAMBUFFERS; i++ )
+ {
+ if ( !FillBuffer(m_alBuffers[i]) )
+ break;
+ alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
+ }
+
+ return i;
+}
+
+void CStream::ClearBuffers()
+{
+ if ( !HasSource() ) return;
+
+ ALint buffersQueued;
+ alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
+
+ ALuint value;
+ while (buffersQueued--)
+ alSourceUnqueueBuffers(m_alSource, 1, &value);
+}
+
+bool CStream::Setup()
+{
+ if ( m_pSoundFile->IsOpened() )
+ {
+ m_pSoundFile->Seek(0);
+ alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ //SetPosition(0.0f, 0.0f, 0.0f);
+ SetPitch(1.0f);
+ //SetPan(m_nPan);
+ //SetVolume(100);
+ }
+
return IsOpened();
}
+void CStream::SetPlay(bool state)
+{
+ if ( !HasSource() ) return;
+ if ( state )
+ {
+ ALint sourceState = AL_PLAYING;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_PLAYING )
+ alSourcePlay(m_alSource);
+ m_bActive = true;
+ }
+ else
+ {
+ ALint sourceState = AL_STOPPED;
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ if (sourceState != AL_STOPPED )
+ alSourceStop(m_alSource);
+ m_bActive = false;
+ }
+}
+
void CStream::Start()
{
+ if ( !HasSource() ) return;
+ if ( FillBuffers() != 0 )
+ SetPlay(true);
+}
+void CStream::Stop()
+{
+ if ( !HasSource() ) return;
+ SetPlay(false);
}
void CStream::Update()
{
if ( !IsOpened() )
return;
+
+ if ( !HasSource() )
+ return;
+
+ if ( m_bReset )
+ return;
+
+ if ( !m_bPaused )
+ {
+ ALint sourceState;
+ ALint buffersProcessed = 0;
+
+ alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+
+ ALint looping = AL_FALSE;
+ alGetSourcei(m_alSource, AL_LOOPING, &looping);
+
+ if ( looping == AL_TRUE )
+ {
+ TRACE("stream set looping");
+ alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
+ }
+
+ while( buffersProcessed-- )
+ {
+ ALuint buffer;
+
+ alSourceUnqueueBuffers(m_alSource, 1, &buffer);
+
+ if ( m_bActive && FillBuffer(buffer) )
+ alSourceQueueBuffers(m_alSource, 1, &buffer);
+ }
+
+ if ( sourceState != AL_PLAYING )
+ {
+ alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
+ SetPlay(buffersProcessed!=0);
+ }
+ }
}
+void CStream::ProviderInit()
+{
+ if ( m_bReset )
+ {
+ if ( Setup() )
+ {
+ SetPan(m_nPan);
+ SetVolume(m_nVolume);
+ SetPosMS(m_nPosBeforeReset);
+ if (m_bActive)
+ FillBuffers();
+ SetPlay(m_bActive);
+ if ( m_bPaused )
+ Pause();
+ }
+
+ m_bReset = false;
+ }
+}
+
+void CStream::ProviderTerm()
+{
+ m_bReset = true;
+ m_nPosBeforeReset = GetPosMS();
+
+ ClearBuffers();
+}
+
#endif \ No newline at end of file
diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h
index 666d42e0..f1e5f458 100644
--- a/src/audio/oal/stream.h
+++ b/src/audio/oal/stream.h
@@ -4,8 +4,56 @@
#ifdef AUDIO_OAL
#include <AL/al.h>
-#define NUM_STREAMBUFFERS 5
-#define STREAMBUFFER_SIZE 0x4000
+#define NUM_STREAMBUFFERS 4
+
+class IDecoder
+{
+public:
+ virtual ~IDecoder() { }
+
+ virtual bool IsOpened() = 0;
+
+ virtual uint32 GetSampleSize() = 0;
+ virtual uint32 GetSampleCount() = 0;
+ virtual uint32 GetSampleRate() = 0;
+ virtual uint32 GetChannels() = 0;
+
+ uint32 GetAvgSamplesPerSec()
+ {
+ return GetChannels() * GetSampleRate();
+ }
+
+ uint32 ms2samples(uint32 ms)
+ {
+ return float(ms) / 1000.0f * float(GetChannels()) * float(GetSampleRate());
+ }
+
+ uint32 samples2ms(uint32 sm)
+ {
+ return float(sm) * 1000.0f / float(GetChannels()) / float(GetSampleRate());
+ }
+
+ uint32 GetBufferSamples()
+ {
+ //return (GetAvgSamplesPerSec() >> 2) - (GetSampleCount() % GetChannels());
+ return (GetAvgSamplesPerSec() / 4); // 250ms
+ }
+
+ uint32 GetBufferSize()
+ {
+ return GetBufferSamples() * GetSampleSize();
+ }
+
+ virtual void Seek(uint32 milliseconds) = 0;
+ virtual uint32 Tell() = 0;
+
+ uint32 GetLength()
+ {
+ return float(GetSampleCount()) * 1000.0f / float(GetSampleRate());
+ }
+
+ virtual uint32 Decode(void *buffer) = 0;
+};
class CStream
{
@@ -13,30 +61,34 @@ class CStream
ALuint &m_alSource;
ALuint (&m_alBuffers)[NUM_STREAMBUFFERS];
- bool m_bIsOpened;
bool m_bPaused;
-
- uint32 m_nLength;
- uint32 m_nLengthMS;
- uint32 m_nBitRate;
-
- unsigned long m_nFormat;
- unsigned long m_nFreq;
+ bool m_bActive;
- uint32 m_nBufferSize;
void *m_pBuffer;
- ALint iTotalBuffersProcessed;
+ bool m_bReset;
+ uint32 m_nVolume;
+ uint8 m_nPan;
+ uint32 m_nPosBeforeReset;
+
+ IDecoder *m_pSoundFile;
+
+ bool HasSource();
+ void SetPosition(float x, float y, float z);
+ void SetPitch(float pitch);
+ void SetGain(float gain);
+ void Pause();
+ void SetPlay(bool state);
bool FillBuffer(ALuint alBuffer);
int32 FillBuffers();
+ void ClearBuffers();
public:
static void Initialise();
static void Terminate();
CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]);
~CStream();
-
void Delete();
bool IsOpened();
@@ -44,14 +96,17 @@ public:
void SetPause (bool bPause);
void SetVolume(uint32 nVol);
void SetPan (uint8 nPan);
- void SetPos (uint32 nPos);
-
- uint32 GetPos();
- uint32 GetLength();
+ void SetPosMS (uint32 nPos);
+ uint32 GetPosMS();
+ uint32 GetLengthMS();
bool Setup();
void Start();
+ void Stop();
void Update(void);
+
+ void ProviderInit();
+ void ProviderTerm();
};
#endif \ No newline at end of file
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index 6ae1bf79..ccddaa73 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -29,7 +29,6 @@
//TODO: fix eax3 reverb
//TODO: max channals
//TODO: loop count
-//TODO: mp3/wav stream
//TODO: mp3 player
#pragma comment( lib, "OpenAL32.lib" )
@@ -179,9 +178,9 @@ add_providers()
defaultProvider = pDeviceList->GetDefaultDevice();
if ( defaultProvider > MAXPROVIDERS )
defaultProvider = 0;
-
- delete pDeviceList;
}
+
+ delete pDeviceList;
}
static void
@@ -211,6 +210,10 @@ release_existing()
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
+ CStream *stream = aStream[i];
+ if (stream)
+ stream->ProviderTerm();
+
alDeleteSources(1, &ALStreamSources[i]);
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
}
@@ -298,6 +301,10 @@ set_new_provider(int index)
{
alGenSources(1, &ALStreamSources[i]);
alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+
+ CStream *stream = aStream[i];
+ if (stream)
+ stream->ProviderInit();
}
for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
@@ -524,6 +531,18 @@ cSampleManager::Initialise(void)
}
{
+ for ( int32 i = 0; i < MAX_STREAMS; i++ )
+ {
+ aStream[i] = NULL;
+ nStreamVolume[i] = 100;
+ nStreamPan[i] = 63;
+ }
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ nStreamLength[i] = 0;
+ }
+
+ {
add_providers();
if ( !InitialiseSampleBanks() )
@@ -545,17 +564,6 @@ cSampleManager::Initialise(void)
ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
}
- {
- for ( int32 i = 0; i < MAX_STREAMS; i++ )
- {
- aStream[i] = NULL;
- nStreamVolume[i] = 100;
- nStreamPan[i] = 63;
- }
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- nStreamLength[i] = 3600000;
- }
{
_bSampmanInitialised = true;
@@ -571,6 +579,25 @@ cSampleManager::Initialise(void)
}
}
+ {
+
+ for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ {
+ aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]);
+
+ if ( aStream[0] && aStream[0]->IsOpened() )
+ {
+ uint32 tatalms = aStream[0]->GetLengthMS();
+ delete aStream[0];
+ aStream[0] = NULL;
+
+ nStreamLength[i] = tatalms;
+ }
+ else
+ USERERROR("Can't open '%s'\n", StreamedNameTable[i]);
+ }
+ }
+
LoadSampleBank(SAMPLEBANK_MAIN);
return true;
@@ -653,7 +680,7 @@ cSampleManager::UpdateEffectsVolume(void)
if ( GetChannelUsedFlag(i) )
{
if ( nChannelVolume[i] != 0 )
- aChannel[i].SetVolume(m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
+ aChannel[i].SetVolume(m_nEffectsFadeVolume*nChannelVolume[i]*m_nEffectsVolume >> 14);
}
}
}
@@ -853,7 +880,7 @@ uint32
cSampleManager::GetSampleLength(uint32 nSample)
{
ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
- return m_aSamples[nSample].nSize >> 1;
+ return m_aSamples[nSample].nSize / sizeof(uint16);
}
bool cSampleManager::UpdateReverb(void)
@@ -1018,7 +1045,7 @@ cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
{
- nChannelVolume[nChannel] >>= 2;
+ nChannelVolume[nChannel] = vol / 4;
}
// no idea, does this one looks like a bug or it's SetChannelVolume ?
@@ -1060,7 +1087,7 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
{
- nChannelVolume[nChannel] >>= 2;
+ nChannelVolume[nChannel] = vol / 4;
}
aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
@@ -1209,11 +1236,11 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
if ( stream->IsOpened() )
{
- nStreamLength[nFile] = stream->GetLength();
+ nStreamLength[nFile] = stream->GetLengthMS();
if ( stream->Setup() )
{
if ( nPos != 0 )
- stream->SetPos(nPos);
+ stream->SetPosMS(nPos);
stream->Start();
}
@@ -1253,7 +1280,7 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
if ( stream )
{
- return stream->GetPos();
+ return stream->GetPosMS();
}
return 0;
@@ -1270,7 +1297,7 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
if ( nPan > MAX_VOLUME )
nPan = MAX_VOLUME;
- nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
+ nStreamVolume[nStream] = nVolume;
nStreamPan [nStream] = nPan;
CStream *stream = aStream[nStream];
diff --git a/src/core/common.h b/src/core/common.h
index 18f4715c..66a3ad81 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -209,6 +209,7 @@ void mysrand(unsigned int seed);
void re3_debug(const char *format, ...);
void re3_trace(const char *filename, unsigned int lineno, const char *func, const char *format, ...);
void re3_assert(const char *expr, const char *filename, unsigned int lineno, const char *func);
+void re3_usererror(const char *format, ...);
#define DEBUGBREAK() __debugbreak();
@@ -216,6 +217,7 @@ void re3_assert(const char *expr, const char *filename, unsigned int lineno, con
#define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__)
#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__)
#define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__)
+#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__)
#define assert(_Expression) (void)( (!!(_Expression)) || (re3_assert(#_Expression, __FILE__, __LINE__, __FUNCTION__), 0) )
#define ASSERT assert
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 2a9cbc77..b7eb6480 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -456,6 +456,20 @@ void re3_trace(const char *filename, unsigned int lineno, const char *func, cons
OutputDebugStringA(buff);
}
+void re3_usererror(const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ vsprintf_s(re3_buff, re3_buffsize, format, va);
+ va_end(va);
+
+ ::MessageBoxA(nil, re3_buff, "RE3 Error!",
+ MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
+
+ raise(SIGABRT);
+ _exit(3);
+}
+
#ifdef VALIDATE_SAVE_SIZE
int32 _saveBufCount;
#endif