mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-13 09:36:43 +00:00
Combined OpenAL+Audiere sound test now compiles and runs, but segfaults
This commit is contained in:
parent
9e332c4067
commit
56f9daed96
13 changed files with 142 additions and 172 deletions
|
@ -40,7 +40,6 @@ class InputFilter : public SoundFactory
|
||||||
// Set capabilities
|
// Set capabilities
|
||||||
needsUpdate = snd->needsUpdate;
|
needsUpdate = snd->needsUpdate;
|
||||||
has3D = snd->has3D;
|
has3D = snd->has3D;
|
||||||
canRepeatStream = snd->canRepeatStream;
|
|
||||||
canLoadStream = inp->canLoadStream;
|
canLoadStream = inp->canLoadStream;
|
||||||
|
|
||||||
// Both these should be true, or the use of this class is pretty
|
// Both these should be true, or the use of this class is pretty
|
||||||
|
@ -51,13 +50,13 @@ class InputFilter : public SoundFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual SoundPtr load(const std::string &file)
|
virtual SoundPtr load(const std::string &file)
|
||||||
{ return load(inp->load(file), stream); }
|
{ return loadRaw(inp->load(file)); }
|
||||||
|
|
||||||
virtual SoundPtr load(Stream::StreamPtr input)
|
virtual SoundPtr load(Stream::StreamPtr input)
|
||||||
{ return load(inp->load(input), stream); }
|
{ return loadRaw(inp->load(input)); }
|
||||||
|
|
||||||
virtual SoundPtr load(SampleSourcePtr input)
|
virtual SoundPtr loadRaw(SampleSourcePtr input)
|
||||||
{ return snd->load(input, stream); }
|
{ return snd->loadRaw(input); }
|
||||||
|
|
||||||
virtual void update() { snd->update(); }
|
virtual void update() { snd->update(); }
|
||||||
virtual void setListenerPos(float x, float y, float z,
|
virtual void setListenerPos(float x, float y, float z,
|
||||||
|
|
|
@ -15,8 +15,8 @@ class OpenAL_Audiere_Factory : public InputFilter
|
||||||
public:
|
public:
|
||||||
OpenAL_Audiere_Factory()
|
OpenAL_Audiere_Factory()
|
||||||
{
|
{
|
||||||
set(new OpenAL_Factory,
|
set(SoundFactoryPtr(new OpenAL_Factory),
|
||||||
new AudiereLoader);
|
SampleSourceLoaderPtr(new AudiereLoader));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Sound
|
||||||
virtual void pause() = 0;
|
virtual void pause() = 0;
|
||||||
|
|
||||||
/// Check if the sound is still playing
|
/// Check if the sound is still playing
|
||||||
virtual bool isPlaying() = 0 const;
|
virtual bool isPlaying() const = 0;
|
||||||
|
|
||||||
/// Set the volume. The parameter must be between 0.0 and 1.0.
|
/// Set the volume. The parameter must be between 0.0 and 1.0.
|
||||||
virtual void setVolume(float) = 0;
|
virtual void setVolume(float) = 0;
|
||||||
|
@ -120,7 +120,7 @@ class SoundFactory
|
||||||
large files, but they are not required to.
|
large files, but they are not required to.
|
||||||
@return a new Sound object
|
@return a new Sound object
|
||||||
*/
|
*/
|
||||||
virtual SoundPtr load(SampleSource *input) = 0;
|
virtual SoundPtr loadRaw(SampleSourcePtr input) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Load a sound file from stream. Only valid if canLoadStream
|
@brief Load a sound file from stream. Only valid if canLoadStream
|
||||||
|
@ -130,7 +130,7 @@ class SoundFactory
|
||||||
@param stream true if the file should be streamed
|
@param stream true if the file should be streamed
|
||||||
@see load(InputSource*,bool)
|
@see load(InputSource*,bool)
|
||||||
*/
|
*/
|
||||||
virtual SoundPtr load(Stream::Stream *input) = 0;
|
virtual SoundPtr load(Stream::StreamPtr input) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Load a sound directly from file. Only valid if canLoadFile
|
@brief Load a sound directly from file. Only valid if canLoadFile
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "openal_out.h"
|
#include "openal_out.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "../../stream/filters/buffer_stream.h"
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
using namespace Mangle::Sound;
|
||||||
|
|
||||||
// ---- Helper functions and classes ----
|
// ---- Helper functions and classes ----
|
||||||
|
@ -28,7 +30,7 @@ static void checkALError(const std::string &msg)
|
||||||
fail("\"" + std::string(alGetString(err)) + "\" while " + msg);
|
fail("\"" + std::string(alGetString(err)) + "\" while " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getALFormat(InputStream *inp, int &fmt, int &rate)
|
static void getALFormat(SampleSourcePtr inp, int &fmt, int &rate)
|
||||||
{
|
{
|
||||||
int ch, bits;
|
int ch, bits;
|
||||||
inp->getInfo(&rate, &ch, &bits);
|
inp->getInfo(&rate, &ch, &bits);
|
||||||
|
@ -61,6 +63,41 @@ static void getALFormat(InputStream *inp, int &fmt, int &rate)
|
||||||
fail("Unsupported input format");
|
fail("Unsupported input format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- OpenAL_Factory ----
|
||||||
|
|
||||||
|
OpenAL_Factory::OpenAL_Factory(bool doSetup)
|
||||||
|
: didSetup(doSetup)
|
||||||
|
{
|
||||||
|
needsUpdate = false;
|
||||||
|
has3D = true;
|
||||||
|
canLoadFile = false;
|
||||||
|
canLoadStream = false;
|
||||||
|
canLoadSource = true;
|
||||||
|
|
||||||
|
if(doSetup)
|
||||||
|
{
|
||||||
|
// Set up sound system
|
||||||
|
Device = alcOpenDevice(NULL);
|
||||||
|
Context = alcCreateContext(Device, NULL);
|
||||||
|
|
||||||
|
if(!Device || !Context)
|
||||||
|
fail("Failed to initialize context or device");
|
||||||
|
|
||||||
|
alcMakeContextCurrent(Context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenAL_Factory::~OpenAL_Factory()
|
||||||
|
{
|
||||||
|
// Deinitialize sound system
|
||||||
|
if(didSetup)
|
||||||
|
{
|
||||||
|
alcMakeContextCurrent(NULL);
|
||||||
|
if(Context) alcDestroyContext(Context);
|
||||||
|
if(Device) alcCloseDevice(Device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- OpenAL_Sound ----
|
// ---- OpenAL_Sound ----
|
||||||
|
|
||||||
void OpenAL_Sound::play()
|
void OpenAL_Sound::play()
|
||||||
|
@ -81,7 +118,7 @@ void OpenAL_Sound::pause()
|
||||||
checkALError("pausing");
|
checkALError("pausing");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenAL_Sound::isPlaying()
|
bool OpenAL_Sound::isPlaying() const
|
||||||
{
|
{
|
||||||
ALint state;
|
ALint state;
|
||||||
alGetSourcei(inst, AL_SOURCE_STATE, &state);
|
alGetSourcei(inst, AL_SOURCE_STATE, &state);
|
||||||
|
@ -105,7 +142,12 @@ void OpenAL_Sound::setPos(float x, float y, float z)
|
||||||
|
|
||||||
void OpenAL_Sound::setRepeat(bool rep)
|
void OpenAL_Sound::setRepeat(bool rep)
|
||||||
{
|
{
|
||||||
alSourcei(Source, AL_LOOPING, rep?AL_TRUE:AL_FALSE);
|
alSourcei(inst, AL_LOOPING, rep?AL_TRUE:AL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundPtr OpenAL_Sound::clone() const
|
||||||
|
{
|
||||||
|
return SoundPtr(new OpenAL_Sound(bufferID, refCnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor used for cloned sounds
|
// Constructor used for cloned sounds
|
||||||
|
@ -121,11 +163,12 @@ OpenAL_Sound::OpenAL_Sound(ALuint buf, int *ref)
|
||||||
alSourcei(inst, AL_BUFFER, bufferID);
|
alSourcei(inst, AL_BUFFER, bufferID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Constructor used for original (non-cloned) sounds
|
||||||
OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input)
|
OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input)
|
||||||
{
|
{
|
||||||
// Get the format
|
// Get the format
|
||||||
int fmt, rate;
|
int fmt, rate;
|
||||||
getALFormat(inp, fmt, rate);
|
getALFormat(input, fmt, rate);
|
||||||
|
|
||||||
// Set up the OpenAL buffer
|
// Set up the OpenAL buffer
|
||||||
alGenBuffers(1, &bufferID);
|
alGenBuffers(1, &bufferID);
|
||||||
|
@ -135,15 +178,15 @@ OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input)
|
||||||
if(input->hasPtr)
|
if(input->hasPtr)
|
||||||
{
|
{
|
||||||
// If so, we can read the data directly from the stream
|
// If so, we can read the data directly from the stream
|
||||||
alBufferData(bufferID, fmt, &input.getPtr(), input.size(), rate);
|
alBufferData(bufferID, fmt, input->getPtr(), input->size(), rate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Read the entire stream into a temporary buffer first
|
// Read the entire stream into a temporary buffer first
|
||||||
BufferStream buf(input);
|
Mangle::Stream::BufferStream buf(input);
|
||||||
|
|
||||||
// Then copy that into OpenAL
|
// Then copy that into OpenAL
|
||||||
alBufferData(bufferID, fmt, &buf.getPtr(), buf.size(), rate);
|
alBufferData(bufferID, fmt, buf.getPtr(), buf.size(), rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkALError("loading sound buffer");
|
checkALError("loading sound buffer");
|
||||||
|
@ -165,8 +208,8 @@ OpenAL_Sound::~OpenAL_Sound()
|
||||||
// Return sound
|
// Return sound
|
||||||
alDeleteSources(1, &inst);
|
alDeleteSources(1, &inst);
|
||||||
|
|
||||||
// Decrease the reference
|
// Decrease the reference counter
|
||||||
if(--(*refCnt))
|
if((-- *refCnt) == 0)
|
||||||
{
|
{
|
||||||
// We're the last owner. Delete the buffer and the counter
|
// We're the last owner. Delete the buffer and the counter
|
||||||
// itself.
|
// itself.
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define MANGLE_SOUND_OPENAL_OUT_H
|
#define MANGLE_SOUND_OPENAL_OUT_H
|
||||||
|
|
||||||
#include "../output.h"
|
#include "../output.h"
|
||||||
#include "../../stream/filters/buffer_stream.h"
|
|
||||||
|
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
|
@ -34,7 +33,7 @@ class OpenAL_Sound : public Sound
|
||||||
void setPos(float x, float y, float z);
|
void setPos(float x, float y, float z);
|
||||||
void setRepeat(bool);
|
void setRepeat(bool);
|
||||||
void setStreaming(bool) {} // Not implemented yet
|
void setStreaming(bool) {} // Not implemented yet
|
||||||
Sound* clone() const;
|
SoundPtr clone() const;
|
||||||
|
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
void setPan(float) {}
|
void setPan(float) {}
|
||||||
|
@ -50,48 +49,18 @@ class OpenAL_Factory : public SoundFactory
|
||||||
/// Initialize object. Pass true (default) if you want the
|
/// Initialize object. Pass true (default) if you want the
|
||||||
/// constructor to set up the current ALCdevice and ALCcontext for
|
/// constructor to set up the current ALCdevice and ALCcontext for
|
||||||
/// you.
|
/// you.
|
||||||
OpenAL_Factory(bool doSetup = true)
|
OpenAL_Factory(bool doSetup = true);
|
||||||
: didSetup(doSetup)
|
~OpenAL_Factory();
|
||||||
{
|
|
||||||
needsUpdate = false;
|
|
||||||
has3D = true;
|
|
||||||
canLoadFile = false;
|
|
||||||
canLoadStream = false;
|
|
||||||
canLoadSource = true;
|
|
||||||
|
|
||||||
if(doSetup)
|
SoundPtr load(const std::string &file) { assert(0); }
|
||||||
{
|
SoundPtr load(Stream::StreamPtr input) { assert(0); }
|
||||||
// Set up sound system
|
SoundPtr loadRaw(SampleSourcePtr input)
|
||||||
Device = alcOpenDevice(NULL);
|
|
||||||
Context = alcCreateContext(Device, NULL);
|
|
||||||
|
|
||||||
if(!Device || !Context)
|
|
||||||
fail("Failed to initialize context or device");
|
|
||||||
|
|
||||||
alcMakeContextCurrent(Context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~OpenAL_Factory()
|
|
||||||
{
|
|
||||||
// Deinitialize sound system
|
|
||||||
if(didSetup)
|
|
||||||
{
|
|
||||||
alcMakeContextCurrent(NULL);
|
|
||||||
if(Context) alcDestroyContext(Context);
|
|
||||||
if(Device) alcCloseDevice(Device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundPtr load(const std::string &file, bool stream=false) { assert(0); }
|
|
||||||
SoundPtr load(Stream::StreamPtr input, bool stream=false) { assert(0); }
|
|
||||||
SoundPtr load(SampleSourcePtr input, bool stream=false)
|
|
||||||
{ return SoundPtr(new OpenAL_Sound(input)); }
|
{ return SoundPtr(new OpenAL_Sound(input)); }
|
||||||
|
|
||||||
void update() {}
|
void update() {}
|
||||||
setListenerPos(float x, float y, float z,
|
void setListenerPos(float x, float y, float z,
|
||||||
float fx, float fy, float fz,
|
float fx, float fy, float fz,
|
||||||
float ux, float uy, float uz)
|
float ux, float uy, float uz)
|
||||||
{
|
{
|
||||||
ALfloat orient[6];
|
ALfloat orient[6];
|
||||||
orient[0] = fx;
|
orient[0] = fx;
|
||||||
|
|
|
@ -21,13 +21,13 @@ class SampleSource : public Stream::Stream
|
||||||
|
|
||||||
/// Get the sample rate, number of channels, and bits per
|
/// Get the sample rate, number of channels, and bits per
|
||||||
/// sample. NULL parameters are ignored.
|
/// sample. NULL parameters are ignored.
|
||||||
virtual void getInfo(int32_t *rate, int32_t *channels, int32_t *bits) const = 0;
|
virtual void getInfo(int32_t *rate, int32_t *channels, int32_t *bits) = 0;
|
||||||
|
|
||||||
bool eof() const { return isEof; }
|
bool eof() const { return isEof; }
|
||||||
|
|
||||||
// Disabled functions by default. You can still override them in
|
// Disabled functions by default. You can still override them in
|
||||||
// subclasses.
|
// subclasses.
|
||||||
void seek(size_t pos) const { assert(0); }
|
void seek(size_t pos) { assert(0); }
|
||||||
size_t tell() const { assert(0); }
|
size_t tell() const { assert(0); }
|
||||||
size_t size() const { assert(0); }
|
size_t size() const { assert(0); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "../../stream/clients/audiere_file.h"
|
#include "../../stream/clients/audiere_file.h"
|
||||||
|
|
||||||
|
using namespace Mangle::Stream;
|
||||||
|
|
||||||
// Exception handling
|
// Exception handling
|
||||||
class Audiere_Exception : public std::exception
|
class Audiere_Exception : public std::exception
|
||||||
{
|
{
|
||||||
|
@ -109,11 +111,11 @@ AudiereSource::AudiereSource(const std::string &file)
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
AudiereSource::AudiereSource(Stream::StreamPtr input)
|
AudiereSource::AudiereSource(StreamPtr input)
|
||||||
{
|
{
|
||||||
// Use our Stream::AudiereFile implementation to convert a Mangle
|
// Use our Stream::AudiereFile implementation to convert a Mangle
|
||||||
// 'Stream' to an Audiere 'File'
|
// 'Stream' to an Audiere 'File'
|
||||||
sample = OpenSampleSource(new Stream::AudiereFile(input));
|
sample = OpenSampleSource(new AudiereFile(input));
|
||||||
if(!sample)
|
if(!sample)
|
||||||
fail("Couldn't load stream");
|
fail("Couldn't load stream");
|
||||||
|
|
||||||
|
@ -125,7 +127,7 @@ AudiereSource::AudiereSource(audiere::SampleSourcePtr src)
|
||||||
{ assert(sample); setup(); }
|
{ assert(sample); setup(); }
|
||||||
|
|
||||||
// Common function called from all constructors
|
// Common function called from all constructors
|
||||||
AudiereSource::setup()
|
void AudiereSource::setup()
|
||||||
{
|
{
|
||||||
assert(sample);
|
assert(sample);
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,14 @@ class AudiereSource : public SampleSource
|
||||||
// How much of the above buffer is in use
|
// How much of the above buffer is in use
|
||||||
int pullSize;
|
int pullSize;
|
||||||
|
|
||||||
void getFormat();
|
void setup();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Decode the given sound file
|
/// Decode the given sound file
|
||||||
AudiereSource(const std::string &file);
|
AudiereSource(const std::string &file);
|
||||||
|
|
||||||
/// Decode the given sound stream
|
/// Decode the given sound stream
|
||||||
AudiereSource(Stream::StreamPtr src);
|
AudiereSource(Mangle::Stream::StreamPtr src);
|
||||||
|
|
||||||
/// Read directly from an existing audiere::SampleSource
|
/// Read directly from an existing audiere::SampleSource
|
||||||
AudiereSource(audiere::SampleSourcePtr src);
|
AudiereSource(audiere::SampleSourcePtr src);
|
||||||
|
@ -41,9 +41,9 @@ class AudiereSource : public SampleSource
|
||||||
void getInfo(int32_t *rate, int32_t *channels, int32_t *bits);
|
void getInfo(int32_t *rate, int32_t *channels, int32_t *bits);
|
||||||
size_t read(void *data, size_t length);
|
size_t read(void *data, size_t length);
|
||||||
|
|
||||||
void seek(size_t pos) const { sample->setPosition(pos); }
|
void seek(size_t pos) { sample->setPosition(pos/frameSize); }
|
||||||
size_t tell() const { return sample->getPosition(); }
|
size_t tell() const { return sample->getPosition()*frameSize; }
|
||||||
size_t size() const { return sample->getLength(); }
|
size_t size() const { return sample->getLength()*frameSize; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "loadertemplate.h"
|
#include "loadertemplate.h"
|
||||||
|
|
|
@ -4,22 +4,24 @@
|
||||||
template <class SourceT, bool stream, bool file>
|
template <class SourceT, bool stream, bool file>
|
||||||
class SSL_Template : public SampleSourceLoader
|
class SSL_Template : public SampleSourceLoader
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
SSL_Template()
|
SSL_Template()
|
||||||
{
|
{
|
||||||
canLoadStream = stream;
|
canLoadStream = stream;
|
||||||
canLoadFile = file;
|
canLoadFile = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleSource *load(const std::string &file)
|
SampleSourcePtr load(const std::string &filename)
|
||||||
{
|
{
|
||||||
assert(canLoadFile);
|
assert(canLoadFile);
|
||||||
return new SourceT(file);
|
return SampleSourcePtr(new SourceT(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleSource *load(Stream::StreamPtr input)
|
SampleSourcePtr load(Stream::StreamPtr input)
|
||||||
{
|
{
|
||||||
assert(canLoadStream);
|
assert(canLoadStream);
|
||||||
return new SourceT(input);
|
return SampleSourcePtr(new SourceT(input));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
GCC=g++ -I../
|
GCC=g++ -I../
|
||||||
|
|
||||||
all: audiere_test ffmpeg_openal_test openal_audiere_test
|
all: openal_audiere_test
|
||||||
|
|
||||||
L_FFMPEG=$(shell pkg-config --libs libavcodec libavformat)
|
#L_FFMPEG=$(shell pkg-config --libs libavcodec libavformat)
|
||||||
L_OPENAL=$(shell pkg-config --libs openal)
|
L_OPENAL=$(shell pkg-config --libs openal)
|
||||||
L_AUDIERE=-laudiere
|
L_AUDIERE=-laudiere
|
||||||
|
|
||||||
ffmpeg_openal_test: ffmpeg_openal_test.cpp ../servers/input_ffmpeg.cpp ../servers/output_openal.cpp
|
openal_audiere_test: openal_audiere_test.cpp ../sources/audiere_source.cpp ../outputs/openal_out.cpp ../../stream/clients/audiere_file.cpp
|
||||||
$(GCC) $^ -o $@ $(L_FFMPEG) $(L_OPENAL)
|
|
||||||
|
|
||||||
openal_audiere_test: openal_audiere_test.cpp ../servers/input_audiere.cpp ../servers/output_openal.cpp ../../stream/clients/audiere_file.cpp
|
|
||||||
$(GCC) $^ -o $@ $(L_AUDIERE) $(L_OPENAL)
|
$(GCC) $^ -o $@ $(L_AUDIERE) $(L_OPENAL)
|
||||||
|
|
||||||
audiere_test: audiere_test.cpp ../servers/audiere_imp.cpp
|
|
||||||
$(GCC) $^ -o $@ $(L_AUDIERE)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *_test
|
rm *_test
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
// This file is included directly into the test programs
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class TestStream : public Mangle::Stream::Stream
|
|
||||||
{
|
|
||||||
ifstream io;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
TestStream(const char* name)
|
|
||||||
{
|
|
||||||
io.open(name, ios::binary);
|
|
||||||
isSeekable = true;
|
|
||||||
hasPosition = true;
|
|
||||||
hasSize = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(void* buf, size_t len)
|
|
||||||
{
|
|
||||||
io.read((char*)buf, len);
|
|
||||||
return io.gcount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek(size_t pos)
|
|
||||||
{
|
|
||||||
io.seekg(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tell() const
|
|
||||||
{ return ((TestStream*)this)->io.tellg(); }
|
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{ return 0; }
|
|
||||||
|
|
||||||
bool eof() const
|
|
||||||
{ return io.eof(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
void play(const char* name, bool music=false, bool stream=false)
|
|
||||||
{
|
|
||||||
// Only load streams if the backend supports it
|
|
||||||
if(stream && !mg.canLoadStream)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cout << "Playing " << name;
|
|
||||||
if(stream) cout << " (from stream)";
|
|
||||||
cout << "\n";
|
|
||||||
|
|
||||||
Sound *snd = NULL;
|
|
||||||
Instance *s = NULL;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(stream)
|
|
||||||
snd = mg.load(new TestStream(name), music);
|
|
||||||
else
|
|
||||||
snd = mg.load(name, music);
|
|
||||||
|
|
||||||
|
|
||||||
s = snd->getInstance(false, false);
|
|
||||||
s->play();
|
|
||||||
|
|
||||||
while(s->isPlaying())
|
|
||||||
{
|
|
||||||
usleep(10000);
|
|
||||||
if(mg.needsUpdate) mg.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(exception &e)
|
|
||||||
{
|
|
||||||
cout << " ERROR: " << e.what() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(s) s->drop();
|
|
||||||
if(snd) snd->drop();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
play("cow.wav");
|
|
||||||
play("owl.ogg", true);
|
|
||||||
play("cow.wav", false, true);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,7 +1,54 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#include "../../stream/servers/file_stream.h"
|
||||||
|
#include "../../stream/filters/buffer_stream.h"
|
||||||
#include "../filters/openal_audiere.h"
|
#include "../filters/openal_audiere.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Mangle::Stream;
|
||||||
using namespace Mangle::Sound;
|
using namespace Mangle::Sound;
|
||||||
|
|
||||||
OpenAL_Audiere_Factory mg;
|
OpenAL_Audiere_Factory mg;
|
||||||
|
|
||||||
#include "common.cpp"
|
void play(const char* name, bool stream=false)
|
||||||
|
{
|
||||||
|
// Only load streams if the backend supports it
|
||||||
|
if(stream && !mg.canLoadStream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cout << "Playing " << name;
|
||||||
|
if(stream) cout << " (from stream)";
|
||||||
|
cout << "\n";
|
||||||
|
|
||||||
|
SoundPtr snd;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(stream)
|
||||||
|
snd = mg.load(StreamPtr(new FileStream(name)));
|
||||||
|
else
|
||||||
|
snd = mg.load(name);
|
||||||
|
|
||||||
|
snd->play();
|
||||||
|
|
||||||
|
while(snd->isPlaying())
|
||||||
|
{
|
||||||
|
usleep(10000);
|
||||||
|
if(mg.needsUpdate) mg.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(exception &e)
|
||||||
|
{
|
||||||
|
cout << " ERROR: " << e.what() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
play("cow.wav");
|
||||||
|
play("owl.ogg");
|
||||||
|
play("cow.wav", true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Stream {
|
||||||
/** A Stream that reads another Stream into a buffer, and serves it as
|
/** A Stream that reads another Stream into a buffer, and serves it as
|
||||||
a MemoryStream. Might be expanded with other capabilities later.
|
a MemoryStream. Might be expanded with other capabilities later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class BufferStream : public MemoryStream
|
class BufferStream : public MemoryStream
|
||||||
{
|
{
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
|
@ -17,6 +18,8 @@ class BufferStream : public MemoryStream
|
||||||
public:
|
public:
|
||||||
BufferStream(StreamPtr input)
|
BufferStream(StreamPtr input)
|
||||||
{
|
{
|
||||||
|
assert(input);
|
||||||
|
|
||||||
// Allocate memory, read the stream into it. Then call set()
|
// Allocate memory, read the stream into it. Then call set()
|
||||||
if(input->hasSize)
|
if(input->hasSize)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue