mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 04:10:24 +00:00
Finished first rewrite draft. Not done or tested, but good enough for now.
This commit is contained in:
parent
aafe01dccc
commit
d60f0fa900
7 changed files with 40 additions and 209 deletions
|
@ -1,7 +1,7 @@
|
||||||
#ifndef MANGLE_INPUT_FILTER_H
|
#ifndef MANGLE_INPUT_FILTER_H
|
||||||
#define MANGLE_INPUT_FILTER_H
|
#define MANGLE_INPUT_FILTER_H
|
||||||
|
|
||||||
#include "../sound.h"
|
#include "../output.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -10,39 +10,29 @@ namespace Sound {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief This filter class adds file loading capabilities to a
|
@brief This filter class adds file loading capabilities to a
|
||||||
Sound::Manager class, by associating an InputManager with it.
|
Sound::SoundFactory class, by associating an SampleSourceLoader
|
||||||
|
with it.
|
||||||
|
|
||||||
The class takes an existing Manager able to load streams, and
|
The class takes an existing SoundFactory able to load streams, and
|
||||||
associates an InputManager with it. The combined class is able to
|
associates an SampleSourceLoader with it. The combined class is
|
||||||
load files directly.
|
able to load files directly.
|
||||||
|
|
||||||
Example:
|
|
||||||
\code
|
|
||||||
|
|
||||||
// Add FFmpeg input to an OpenAL soud output manager. OpenAL cannot
|
|
||||||
// decode sound files on its own.
|
|
||||||
InputFilter mg(new OpenAL_Manager, new FFM_InputManager);
|
|
||||||
|
|
||||||
// We can now load filenames directly.
|
|
||||||
mg.load("file1.mp3");
|
|
||||||
\endcode
|
|
||||||
*/
|
*/
|
||||||
class InputFilter : public Manager
|
class InputFilter : public SoundFactory
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Manager *snd;
|
SoundFactory *snd;
|
||||||
InputManager *inp;
|
SampleSourceLoader *inp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Empty constructor
|
/// Empty constructor
|
||||||
InputFilter() {}
|
InputFilter() {}
|
||||||
|
|
||||||
/// Assign an input manager and a sound manager to this object
|
/// Assign an input manager and a sound manager to this object
|
||||||
InputFilter(Manager *_snd, InputManager *_inp)
|
InputFilter(SoundFactory *_snd, SampleSourceLoader *_inp)
|
||||||
{ set(_snd, _inp); }
|
{ set(_snd, _inp); }
|
||||||
|
|
||||||
/// Assign an input manager and a sound manager to this object
|
/// Assign an input manager and a sound manager to this object
|
||||||
void set(Manager *_snd, InputManager *_inp)
|
void set(SoundFactory *_snd, SampleSourceLoader *_inp)
|
||||||
{
|
{
|
||||||
inp = _inp;
|
inp = _inp;
|
||||||
snd = _snd;
|
snd = _snd;
|
|
@ -2,23 +2,23 @@
|
||||||
#define MANGLE_FFMPEG_OPENAL_H
|
#define MANGLE_FFMPEG_OPENAL_H
|
||||||
|
|
||||||
#include "input_filter.h"
|
#include "input_filter.h"
|
||||||
#include "input_audiere.h"
|
#include "../sources/audiere_source.h"
|
||||||
#include "output_openal.h"
|
#include "../outputs/openal_out.h"
|
||||||
|
|
||||||
namespace Mangle {
|
namespace Mangle {
|
||||||
namespace Sound {
|
namespace Sound {
|
||||||
|
|
||||||
/// A InputFilter that adds audiere decoding to OpenAL. Audiere has
|
/// A InputFilter that adds audiere decoding to OpenAL. Audiere has
|
||||||
/// it's own output, but OpenAL sports 3D and other advanced features.
|
/// it's own output, but OpenAL sports 3D and other advanced features.
|
||||||
class OpenAL_Audiere_Manager : public InputFilter
|
class OpenAL_Audiere_Factory : public InputFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenAL_Audiere_Manager()
|
OpenAL_Audiere_Factory()
|
||||||
{
|
{
|
||||||
set(new OpenAL_Manager,
|
set(new OpenAL_Factory,
|
||||||
new AudiereInput);
|
new AudiereLoader);
|
||||||
}
|
}
|
||||||
~OpenAL_Audiere_Manager()
|
~OpenAL_Audiere_Factory()
|
||||||
{
|
{
|
||||||
delete snd;
|
delete snd;
|
||||||
delete inp;
|
delete inp;
|
|
@ -1,8 +1,6 @@
|
||||||
#include "openal_out.h"
|
#include "openal_out.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// ALuint bufferID;
|
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
using namespace Mangle::Sound;
|
||||||
|
|
||||||
// ---- Helper functions and classes ----
|
// ---- Helper functions and classes ----
|
||||||
|
@ -65,11 +63,6 @@ static void getALFormat(InputStream *inp, int &fmt, int &rate)
|
||||||
|
|
||||||
// ---- OpenAL_Sound ----
|
// ---- OpenAL_Sound ----
|
||||||
|
|
||||||
OpenAL_Sound::OpenAL_Sound(SampleSource *input)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenAL_Sound::play()
|
void OpenAL_Sound::play()
|
||||||
{
|
{
|
||||||
alSourcePlay(inst);
|
alSourcePlay(inst);
|
||||||
|
@ -110,174 +103,34 @@ void OpenAL_Sound::setPos(float x, float y, float z)
|
||||||
checkALError("setting position");
|
checkALError("setting position");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OpenAL_Sound::OpenAL_Sound(SampleSource *input)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Instance *OpenAL_Sound::getInstance(bool is3d, bool repeat)
|
|
||||||
{
|
{
|
||||||
assert((!repeat || !stream) && "OpenAL implementation does not support looping streams");
|
|
||||||
|
|
||||||
if(stream)
|
|
||||||
return new OpenAL_Stream_Instance(source->getStream(), owner);
|
|
||||||
|
|
||||||
// Load the buffer if it hasn't been done already
|
|
||||||
if(bufferID == 0)
|
|
||||||
{
|
|
||||||
// Get an input stream and load the file from it
|
|
||||||
InputStream *inp = source->getStream();
|
|
||||||
|
|
||||||
std::vector<unsigned char> buffer;
|
|
||||||
|
|
||||||
// Add 32 kb at each increment
|
|
||||||
const int ADD = 32*1024;
|
|
||||||
|
|
||||||
// Fill the buffer. We increase the buffer until it's large
|
|
||||||
// enough to fit all the data.
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
// Increase the buffer
|
|
||||||
int oldlen = buffer.size();
|
|
||||||
buffer.resize(oldlen+ADD);
|
|
||||||
|
|
||||||
// Read the data
|
|
||||||
size_t len = inp->getData(&buffer[oldlen], ADD);
|
|
||||||
|
|
||||||
// If we read less than requested, we're done.
|
|
||||||
if(len < ADD)
|
|
||||||
{
|
|
||||||
// Downsize the buffer to the right size
|
|
||||||
buffer.resize(oldlen+len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the format
|
// Get the format
|
||||||
int fmt, rate;
|
int fmt, rate;
|
||||||
getALFormat(inp, fmt, rate);
|
getALFormat(inp, fmt, rate);
|
||||||
|
|
||||||
// We don't need the file anymore
|
// Read the entire stream into a buffer
|
||||||
inp->drop();
|
BufferStream buf(input);
|
||||||
source->drop();
|
|
||||||
source = NULL;
|
|
||||||
|
|
||||||
// Move the data into OpenAL
|
// Move the data into OpenAL
|
||||||
alGenBuffers(1, &bufferID);
|
alGenBuffers(1, &bufferID);
|
||||||
alBufferData(bufferID, fmt, &buffer[0], buffer.size(), rate);
|
|
||||||
checkALError("loading sound buffer");
|
|
||||||
} // End of buffer loading
|
|
||||||
|
|
||||||
// At this point, the file data has been loaded into the buffer
|
|
||||||
// in 'bufferID', and we should be ready to go.
|
|
||||||
assert(bufferID != 0);
|
assert(bufferID != 0);
|
||||||
|
alBufferData(bufferID, fmt, &buf.getPtr(), buf.size(), rate);
|
||||||
|
checkALError("loading sound buffer");
|
||||||
|
|
||||||
return new OpenAL_Simple_Instance(bufferID);
|
// Create a source
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---- OpenAL_Simple_Instance ----
|
|
||||||
|
|
||||||
OpenAL_Simple_Instance::OpenAL_Simple_Instance(ALuint buf)
|
|
||||||
{
|
|
||||||
// Create instance and associate buffer
|
|
||||||
alGenSources(1, &inst);
|
alGenSources(1, &inst);
|
||||||
alSourcei(inst, AL_BUFFER, buf);
|
alSourcei(inst, AL_BUFFER, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenAL_Simple_Instance::~OpenAL_Simple_Instance()
|
OpenAL_Sound::~OpenAL_Sound()
|
||||||
{
|
{
|
||||||
// Stop
|
// Stop
|
||||||
alSourceStop(inst);
|
alSourceStop(inst);
|
||||||
|
|
||||||
// Return sound
|
// Return sound
|
||||||
alDeleteSources(1, &inst);
|
alDeleteSources(1, &inst);
|
||||||
}
|
|
||||||
|
// Delete buffer
|
||||||
|
alDeleteBuffers(1, &bufferID);
|
||||||
// ---- OpenAL_Stream_Instance ----
|
|
||||||
|
|
||||||
OpenAL_Stream_Instance::OpenAL_Stream_Instance(InputStream *_stream,
|
|
||||||
OpenAL_Manager *_owner)
|
|
||||||
: stream(_stream), owner(_owner)
|
|
||||||
{
|
|
||||||
// Deduce the file format from the stream info
|
|
||||||
getALFormat(stream, fmt, rate);
|
|
||||||
|
|
||||||
// Create the buffers and the sound instance
|
|
||||||
alGenBuffers(BUFS, bufs);
|
|
||||||
alGenSources(1, &inst);
|
|
||||||
|
|
||||||
checkALError("initializing");
|
|
||||||
|
|
||||||
// Fill the buffers and que them
|
|
||||||
for(int i=0; i<BUFS; i++)
|
|
||||||
queueBuffer(bufs[i]);
|
|
||||||
|
|
||||||
checkALError("buffering initial data");
|
|
||||||
|
|
||||||
// Add ourselves to the stream list
|
|
||||||
lit = owner->add_stream(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenAL_Stream_Instance::queueBuffer(ALuint bId)
|
|
||||||
{
|
|
||||||
char buf[SIZE];
|
|
||||||
|
|
||||||
// Get the data
|
|
||||||
int len = stream->getData(buf, SIZE);
|
|
||||||
if(len == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// .. and stash it
|
|
||||||
alBufferData(bId, fmt, buf, len, rate);
|
|
||||||
alSourceQueueBuffers(inst, 1, &bId);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenAL_Stream_Instance::~OpenAL_Stream_Instance()
|
|
||||||
{
|
|
||||||
// Remove ourselves from streaming list
|
|
||||||
owner->remove_stream(lit);
|
|
||||||
|
|
||||||
// Stop
|
|
||||||
alSourceStop(inst);
|
|
||||||
|
|
||||||
// Kill the input stream
|
|
||||||
stream->drop();
|
|
||||||
|
|
||||||
// Return sound
|
|
||||||
alDeleteSources(1, &inst);
|
|
||||||
|
|
||||||
// Delete buffers
|
|
||||||
alDeleteBuffers(BUFS, bufs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenAL_Stream_Instance::update()
|
|
||||||
{
|
|
||||||
ALint count;
|
|
||||||
alGetSourcei(inst, AL_BUFFERS_PROCESSED, &count);
|
|
||||||
|
|
||||||
for(int i = 0;i < count;i++)
|
|
||||||
{
|
|
||||||
// Unque a finished buffer
|
|
||||||
ALuint bId;
|
|
||||||
alSourceUnqueueBuffers(inst, 1, &bId);
|
|
||||||
|
|
||||||
// Queue a new buffer
|
|
||||||
queueBuffer(bId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#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>
|
||||||
|
@ -15,6 +16,7 @@ class OpenAL_Sound : public Sound
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
ALuint inst;
|
ALuint inst;
|
||||||
|
ALuint bufferID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenAL_Sound(SampleSource *input);
|
OpenAL_Sound(SampleSource *input);
|
||||||
|
@ -39,7 +41,7 @@ class OpenAL_Sound : public Sound
|
||||||
void setPos(float x, float y, float z);
|
void setPos(float x, float y, float z);
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenALFactory : public SoundFactory
|
class OpenAL_Factory : public SoundFactory
|
||||||
{
|
{
|
||||||
ALCdevice *Device;
|
ALCdevice *Device;
|
||||||
ALCcontext *Context;
|
ALCcontext *Context;
|
||||||
|
@ -49,7 +51,7 @@ class OpenALFactory : 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.
|
||||||
OpenALFactory(bool doSetup = true)
|
OpenAL_Factory(bool doSetup = true)
|
||||||
: didSetup(doSetup)
|
: didSetup(doSetup)
|
||||||
{
|
{
|
||||||
needsUpdate = false;
|
needsUpdate = false;
|
||||||
|
@ -72,7 +74,7 @@ class OpenALFactory : public SoundFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~OpenALFactory()
|
~OpenAL_Factory()
|
||||||
{
|
{
|
||||||
// Deinitialize sound system
|
// Deinitialize sound system
|
||||||
if(didSetup)
|
if(didSetup)
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "audiere_imp.h"
|
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
|
||||||
|
|
||||||
AudiereManager mg;
|
|
||||||
|
|
||||||
#include "common.cpp"
|
|
|
@ -1,7 +0,0 @@
|
||||||
#include "openal_ffmpeg.h"
|
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
|
||||||
|
|
||||||
OpenAL_FFM_Manager mg;
|
|
||||||
|
|
||||||
#include "common.cpp"
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "openal_audiere.h"
|
#include "../filters/openal_audiere.h"
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
using namespace Mangle::Sound;
|
||||||
|
|
||||||
OpenAL_Audiere_Manager mg;
|
OpenAL_Audiere_Factory mg;
|
||||||
|
|
||||||
#include "common.cpp"
|
#include "common.cpp"
|
||||||
|
|
Loading…
Reference in a new issue