Combined OpenAL+Audiere sound test now compiles and runs, but segfaults

actorid
Nicolay Korslund 15 years ago
parent 9e332c4067
commit 56f9daed96

@ -40,7 +40,6 @@ class InputFilter : public SoundFactory
// Set capabilities
needsUpdate = snd->needsUpdate;
has3D = snd->has3D;
canRepeatStream = snd->canRepeatStream;
canLoadStream = inp->canLoadStream;
// 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)
{ return load(inp->load(file), stream); }
{ return loadRaw(inp->load(file)); }
virtual SoundPtr load(Stream::StreamPtr input)
{ return load(inp->load(input), stream); }
{ return loadRaw(inp->load(input)); }
virtual SoundPtr load(SampleSourcePtr input)
{ return snd->load(input, stream); }
virtual SoundPtr loadRaw(SampleSourcePtr input)
{ return snd->loadRaw(input); }
virtual void update() { snd->update(); }
virtual void setListenerPos(float x, float y, float z,

@ -15,8 +15,8 @@ class OpenAL_Audiere_Factory : public InputFilter
public:
OpenAL_Audiere_Factory()
{
set(new OpenAL_Factory,
new AudiereLoader);
set(SoundFactoryPtr(new OpenAL_Factory),
SampleSourceLoaderPtr(new AudiereLoader));
}
};

@ -39,7 +39,7 @@ class Sound
virtual void pause() = 0;
/// 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.
virtual void setVolume(float) = 0;
@ -120,7 +120,7 @@ class SoundFactory
large files, but they are not required to.
@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
@ -130,7 +130,7 @@ class SoundFactory
@param stream true if the file should be streamed
@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

@ -1,6 +1,8 @@
#include "openal_out.h"
#include <assert.h>
#include "../../stream/filters/buffer_stream.h"
using namespace Mangle::Sound;
// ---- Helper functions and classes ----
@ -28,7 +30,7 @@ static void checkALError(const std::string &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;
inp->getInfo(&rate, &ch, &bits);
@ -61,6 +63,41 @@ static void getALFormat(InputStream *inp, int &fmt, int &rate)
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 ----
void OpenAL_Sound::play()
@ -81,7 +118,7 @@ void OpenAL_Sound::pause()
checkALError("pausing");
}
bool OpenAL_Sound::isPlaying()
bool OpenAL_Sound::isPlaying() const
{
ALint 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)
{
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
@ -121,11 +163,12 @@ OpenAL_Sound::OpenAL_Sound(ALuint buf, int *ref)
alSourcei(inst, AL_BUFFER, bufferID);
}
// Constructor used for original (non-cloned) sounds
OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input)
{
// Get the format
int fmt, rate;
getALFormat(inp, fmt, rate);
getALFormat(input, fmt, rate);
// Set up the OpenAL buffer
alGenBuffers(1, &bufferID);
@ -135,15 +178,15 @@ OpenAL_Sound::OpenAL_Sound(SampleSourcePtr input)
if(input->hasPtr)
{
// 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
{
// Read the entire stream into a temporary buffer first
BufferStream buf(input);
Mangle::Stream::BufferStream buf(input);
// 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");
@ -165,8 +208,8 @@ OpenAL_Sound::~OpenAL_Sound()
// Return sound
alDeleteSources(1, &inst);
// Decrease the reference
if(--(*refCnt))
// Decrease the reference counter
if((-- *refCnt) == 0)
{
// We're the last owner. Delete the buffer and the counter
// itself.

@ -2,7 +2,6 @@
#define MANGLE_SOUND_OPENAL_OUT_H
#include "../output.h"
#include "../../stream/filters/buffer_stream.h"
#include <AL/al.h>
#include <AL/alc.h>
@ -34,7 +33,7 @@ class OpenAL_Sound : public Sound
void setPos(float x, float y, float z);
void setRepeat(bool);
void setStreaming(bool) {} // Not implemented yet
Sound* clone() const;
SoundPtr clone() const;
/// Not implemented
void setPan(float) {}
@ -50,48 +49,18 @@ class OpenAL_Factory : public SoundFactory
/// Initialize object. Pass true (default) if you want the
/// constructor to set up the current ALCdevice and ALCcontext for
/// you.
OpenAL_Factory(bool doSetup = true)
: 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()
{
// Deinitialize sound system
if(didSetup)
{
alcMakeContextCurrent(NULL);
if(Context) alcDestroyContext(Context);
if(Device) alcCloseDevice(Device);
}
}
OpenAL_Factory(bool doSetup = true);
~OpenAL_Factory();
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)
SoundPtr load(const std::string &file) { assert(0); }
SoundPtr load(Stream::StreamPtr input) { assert(0); }
SoundPtr loadRaw(SampleSourcePtr input)
{ return SoundPtr(new OpenAL_Sound(input)); }
void update() {}
setListenerPos(float x, float y, float z,
float fx, float fy, float fz,
float ux, float uy, float uz)
void setListenerPos(float x, float y, float z,
float fx, float fy, float fz,
float ux, float uy, float uz)
{
ALfloat orient[6];
orient[0] = fx;

@ -21,13 +21,13 @@ class SampleSource : public Stream::Stream
/// Get the sample rate, number of channels, and bits per
/// 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; }
// Disabled functions by default. You can still override them in
// subclasses.
void seek(size_t pos) const { assert(0); }
void seek(size_t pos) { assert(0); }
size_t tell() const { assert(0); }
size_t size() const { assert(0); }
};

@ -2,6 +2,8 @@
#include "../../stream/clients/audiere_file.h"
using namespace Mangle::Stream;
// Exception handling
class Audiere_Exception : public std::exception
{
@ -109,11 +111,11 @@ AudiereSource::AudiereSource(const std::string &file)
setup();
}
AudiereSource::AudiereSource(Stream::StreamPtr input)
AudiereSource::AudiereSource(StreamPtr input)
{
// Use our Stream::AudiereFile implementation to convert a Mangle
// 'Stream' to an Audiere 'File'
sample = OpenSampleSource(new Stream::AudiereFile(input));
sample = OpenSampleSource(new AudiereFile(input));
if(!sample)
fail("Couldn't load stream");
@ -125,7 +127,7 @@ AudiereSource::AudiereSource(audiere::SampleSourcePtr src)
{ assert(sample); setup(); }
// Common function called from all constructors
AudiereSource::setup()
void AudiereSource::setup()
{
assert(sample);

@ -26,14 +26,14 @@ class AudiereSource : public SampleSource
// How much of the above buffer is in use
int pullSize;
void getFormat();
void setup();
public:
/// Decode the given sound file
AudiereSource(const std::string &file);
/// Decode the given sound stream
AudiereSource(Stream::StreamPtr src);
AudiereSource(Mangle::Stream::StreamPtr src);
/// Read directly from an existing audiere::SampleSource
AudiereSource(audiere::SampleSourcePtr src);
@ -41,9 +41,9 @@ class AudiereSource : public SampleSource
void getInfo(int32_t *rate, int32_t *channels, int32_t *bits);
size_t read(void *data, size_t length);
void seek(size_t pos) const { sample->setPosition(pos); }
size_t tell() const { return sample->getPosition(); }
size_t size() const { return sample->getLength(); }
void seek(size_t pos) { sample->setPosition(pos/frameSize); }
size_t tell() const { return sample->getPosition()*frameSize; }
size_t size() const { return sample->getLength()*frameSize; }
};
#include "loadertemplate.h"

@ -4,22 +4,24 @@
template <class SourceT, bool stream, bool file>
class SSL_Template : public SampleSourceLoader
{
public:
SSL_Template()
{
canLoadStream = stream;
canLoadFile = file;
}
SampleSource *load(const std::string &file)
SampleSourcePtr load(const std::string &filename)
{
assert(canLoadFile);
return new SourceT(file);
return SampleSourcePtr(new SourceT(filename));
}
SampleSource *load(Stream::StreamPtr input)
SampleSourcePtr load(Stream::StreamPtr input)
{
assert(canLoadStream);
return new SourceT(input);
return SampleSourcePtr(new SourceT(input));
}
};

@ -1,19 +1,13 @@
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_AUDIERE=-laudiere
ffmpeg_openal_test: ffmpeg_openal_test.cpp ../servers/input_ffmpeg.cpp ../servers/output_openal.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
openal_audiere_test: openal_audiere_test.cpp ../sources/audiere_source.cpp ../outputs/openal_out.cpp ../../stream/clients/audiere_file.cpp
$(GCC) $^ -o $@ $(L_AUDIERE) $(L_OPENAL)
audiere_test: audiere_test.cpp ../servers/audiere_imp.cpp
$(GCC) $^ -o $@ $(L_AUDIERE)
clean:
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"
using namespace std;
using namespace Mangle::Stream;
using namespace Mangle::Sound;
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 MemoryStream. Might be expanded with other capabilities later.
*/
class BufferStream : public MemoryStream
{
std::vector<char> buffer;
@ -17,6 +18,8 @@ class BufferStream : public MemoryStream
public:
BufferStream(StreamPtr input)
{
assert(input);
// Allocate memory, read the stream into it. Then call set()
if(input->hasSize)
{

Loading…
Cancel
Save