source & sample

This commit is contained in:
James Turk 2005-07-05 06:44:55 +00:00
parent 5284fb2959
commit 564e8630cb
12 changed files with 530 additions and 74 deletions

View File

@ -5,7 +5,7 @@
# James Turk (jpt2433@rit.edu)
#
# Version:
# $Id: SConstruct,v 1.16 2005/07/04 06:33:06 cozman Exp $
# $Id: SConstruct,v 1.17 2005/07/05 06:44:55 cozman Exp $
import os,os.path
import glob
@ -73,7 +73,7 @@ if not env.GetOption('clean'):
if not conf.CheckLibWithHeader('corona', 'corona.h', 'C++'):
print 'Corona not found, exiting.'
Exit(1)
if conf.CheckLibWithHeader(OAL_LIB, 'zAL/al.h', 'C++'):
if conf.CheckLibWithHeader(OAL_LIB, 'AL/al.h', 'C++'):
conf.env.Append(CPPFLAGS='-DPHOTON_USE_OPENAL')
else:
print 'OpenAL not found, continuing without OpenAL support.'

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: AudioCore.hpp,v 1.6 2005/07/04 03:06:48 cozman Exp $
// $Id: AudioCore.hpp,v 1.7 2005/07/05 06:44:56 cozman Exp $
#ifdef PHOTON_USE_OPENAL
@ -64,15 +64,23 @@ public:
// Parameters:
// name - Name of audio device to use.
static void setDesiredDevice(const std::string& name);
// Group: Error Checking
public:
static std::string checkOpenALError();
static void throwOpenALError(const std::string& func);
// OpenAL specifics
private:
util::VersionInfo initOpenAL();
static std::string checkOpenALError();
// data members
private:
static std::string deviceName_;
ALfloat listenerPos_[3];
ALfloat listenerVel_[3];
ALfloat listenerOri_[6];
};

View File

@ -0,0 +1,43 @@
//This file is part of Photon (http://photon.sourceforge.net)
//Copyright (C) 2004-2005 James Turk
//
// Author:
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: SampleResourceManager.hpp,v 1.1 2005/07/05 06:44:56 cozman Exp $
#ifndef PHOTON_AUDIO_SAMPLERESOURCEMANAGER_HPP
#define PHOTON_AUDIO_SAMPLERESOURCEMANAGER_HPP
#include "ResourceManager.hpp"
#include "audio/Source.hpp"
namespace photon
{
namespace audio
{
class SampleResource : public Resource
{
public:
uint bufferID;
};
class SampleResourceManager : public ResourceManager<SampleResource>
{
public:
void getAudioData(const std::string& name, uint& bufferID);
private:
virtual void loadResourceData(SampleResource &res,
const ResourceDescriptor& path);
virtual void freeResourceData(SampleResource &res);
};
typedef Source<SampleResourceManager> Sample;
}
}
#endif //PHOTON_AUDIO_SAMPLERESOURCEMANAGER_HPP

272
include/audio/Source.hpp Normal file
View File

@ -0,0 +1,272 @@
//This file is part of Photon (http://photon.sourceforge.net)
//Copyright (C) 2004-2005 James Turk
//
// Author:
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: Source.hpp,v 1.1 2005/07/05 06:44:56 cozman Exp $
#ifndef PHOTON_AUDIO_SOURCE_HPP
#define PHOTON_AUDIO_SOURCE_HPP
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alut.h"
#include "ResourceManaged.hpp"
#include "audio/AudioCore.hpp"
namespace photon
{
namespace audio
{
// Class: Source
// Simple OO wrapper around an OpenAL source.
//
// Children:
//
// Operators:
// - Source = Source
// - bool : True if source has loaded buffer, false if not.
// - ostream& << Source
template <class ResMgrT>
class Source : public ResourceManaged<ResMgrT>
{
// Group: (Con/De)structors
public:
// Function: Source
// Default constructor, initalizes internal state of Source.
Source();
// Function: Source
// Copy constructor, copies another Source.
//
// Parameters:
// rhs - Source to construct copy of.
Source(const Source &rhs);
// Function: Source
// Initializing constructor, loads Source via call to <open>.
//
// Parameters:
// name - Name of the Source <Resource> to open.
//
// See Also:
// <open>
Source(const std::string& name);
// Function: ~Source
// Destructor for source, frees the OpenAL source resource.
~Source();
// Group: General
public:
// Function: open
// Opens an audio file, supported formats are WAV and Ogg.
//
// Parameters:
// name - Name of the Source <Resource> to open.
void open(const std::string& name);
Source& operator=(const Source& rhs);
operator bool() const;
// Group: Source Control
public:
// Function: play
// Starts the playback of the sound attached to the source.
void play();
// Function: stop
// Stops the playback of the sound attached to the source.
void stop();
// Function: pause
// Pauses the playback of the sound attached to the source.
void pause();
// Function: rewind
// Rewinds the position of the sound attached to the source.
void rewind();
// Function: setLooping
// Sets if the source's sound is looping or is played only once.
//
// Parameters:
// loop - If true, will make sound loop, otherwise will play only once.
void setLooping(bool loop);
// Group: Accessors
public:
//friend std::ostream& operator<<(std::ostream& o, const Source& rhs);
// Group: Resource Creation
public:
// Function: addResource
// Define a new named resource.
// (Ex. Image::addResource("monkey","images/monkey.png") would
// make it so that any attempts to load "monkey" would load the image
// images/monkey.png)
//
// Parameters:
// name - Name to give to resource.
// path - Path of resource data file.
static void addResource(const std::string& name, const std::string& path);
// Function: addResource
// Define a new unaliased resource. (name == path).
// (Ex. Image::addResource("images/monkey.png") is essentially the same as
// Image::addResource("images/monkey.png","images/monkey.png")
//
// Parameters:.
// path - Path of resource data file.
static void addResource(const std::string& path);
private:
uint sourceID_;
static const float ORIGIN[];
};
template<class ResMgrT>
const float Source<ResMgrT>::ORIGIN[] = {0, 0, 0};
// you know the drill, Template Implementation //
template<class ResMgrT>
Source<ResMgrT>::Source()
{
alGenSources(1, &sourceID_);
AudioCore::throwOpenALError("Source::Source()");
}
template<class ResMgrT>
Source<ResMgrT>::Source(const Source &rhs) :
ResourceManaged<ResMgrT>(rhs)
{
alGenSources(1, &sourceID_);
AudioCore::throwOpenALError("Source::Source(const Source&)");
}
template<class ResMgrT>
Source<ResMgrT>::Source(const std::string& name)
{
alGenSources(1, &sourceID_);
AudioCore::throwOpenALError("Source::Source(const std::string&)");
open(name);
}
template<class ResMgrT>
Source<ResMgrT>::~Source()
{
if(alIsSource(sourceID_))
{
alDeleteSources(1, &sourceID_);
}
}
template<class ResMgrT>
void Source<ResMgrT>::open(const std::string& name)
{
uint bufferID;
ResourceManaged<ResMgrT>::open(name);
resMgr_.getAudioData(getName(), bufferID);
// attach buffer to source
alSourcei(sourceID_, AL_BUFFER, bufferID);
alSourcef(sourceID_, AL_PITCH, 1.0);
alSourcef(sourceID_, AL_GAIN, 1.0);
alSourcefv(sourceID_, AL_POSITION, ORIGIN);
alSourcefv(sourceID_, AL_VELOCITY, ORIGIN);
AudioCore::throwOpenALError("Source::open");
}
template<class ResMgrT>
Source<ResMgrT>& Source<ResMgrT>::operator=(const Source<ResMgrT>& rhs)
{
if(&rhs != this)
{
uint bufferID;
ResourceManaged<ResMgrT>::operator=(rhs);
resMgr_.getAudioData(getName(), bufferID);
// attach buffer to source
alSourcei(sourceID_, AL_BUFFER, bufferID);
alSourcef(sourceID_, AL_PITCH, 1.0);
alSourcef(sourceID_, AL_GAIN, 1.0);
alSourcefv(sourceID_, AL_POSITION, ORIGIN);
alSourcefv(sourceID_, AL_VELOCITY, ORIGIN);
AudioCore::throwOpenALError("Source::operator=");
}
return *this;
}
template<class ResMgrT>
Source<ResMgrT>::operator bool() const
{
return alIsSource(sourceID_) == AL_TRUE;
}
/*std::ostream& operator<<(std::ostream& o, const Source& rhs)
{
return o << "Source: { Name: " << rhs.getName() << " BufferID: "
<< rhs.bufferID_;
}*/
template<class ResMgrT>
void Source<ResMgrT>::play()
{
alSourcePlay(sourceID_);
}
template<class ResMgrT>
void Source<ResMgrT>::stop()
{
alSourceStop(sourceID_);
}
template<class ResMgrT>
void Source<ResMgrT>::pause()
{
alSourcePause(sourceID_);
}
template<class ResMgrT>
void Source<ResMgrT>::rewind()
{
alSourceRewind(sourceID_);
}
template<class ResMgrT>
void Source<ResMgrT>::setLooping(bool loop)
{
alSourcefv(sourceID_, AL_LOOPING, loop);
}
template<class ResMgrT>
void Source<ResMgrT>::addResource(const std::string& name, const std::string& path)
{
resMgr_.newResource(name, ResourceDescriptor(path));
}
template<class ResMgrT>
void Source<ResMgrT>::addResource(const std::string& path)
{
resMgr_.newResource(path, ResourceDescriptor(path));
}
}
}
#endif //PHOTON_AUDIO_SOURCE_HPP

View File

@ -13,7 +13,10 @@
#include "Log.hpp"
#include "ResourceManaged.hpp"
#include "ResourceManager.hpp"
#include "audio/SampleResourceManager.hpp"
#include "audio/Source.hpp"
#include "audio/AudioCore.hpp"
#include "audio/MusicResourceManager.hpp"
#include "math/math.hpp"
#include "math/Rect.hpp"
#include "math/Vector2.hpp"

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: ConfigFile.hpp,v 1.3 2005/03/03 09:25:19 cozman Exp $
// $Id: ConfigFile.hpp,v 1.4 2005/07/05 06:44:56 cozman Exp $
#ifndef PHOTON_UTIL_CONFIGFILE_HPP
#define PHOTON_UTIL_CONFIGFILE_HPP
@ -14,7 +14,6 @@
#include <list>
#include <sstream>
#include <functional>
#include <iostream>
namespace photon
{

View File

@ -65,6 +65,8 @@ Group: photon:: {
Group: Video {
File: Color (video/Color.hpp)
File: Font (video/Font.hpp)
File: Image (video/Image.hpp)
File: Pen (video/Pen.hpp)
File: Texture (video/Texture.hpp)
File: VideoCore (video/VideoCore.hpp)

View File

@ -7,11 +7,13 @@
<font NAME="SansSerif" SIZE="12"/>
<node ID="Freemind_Link_1613164220" TEXT="better SConstruct file">
<icon BUILTIN="button_ok"/>
<icon BUILTIN="button_ok"/>
</node>
<node ID="Freemind_Link_614612335" TEXT="all stable ZEngine/Nova features">
<font NAME="SansSerif" SIZE="12"/>
<node ID="Freemind_Link_1795651487" TEXT="&quot;ResourceManage&quot;ment">
<icon BUILTIN="button_ok"/>
<icon BUILTIN="button_ok"/>
</node>
<node ID="Freemind_Link_50716011" TEXT="Texture">
<icon BUILTIN="button_ok"/>
@ -22,14 +24,11 @@
<icon BUILTIN="button_ok"/>
</node>
</node>
<node ID="Freemind_Link_1851655735" TEXT="Music">
<icon BUILTIN="help"/>
</node>
<node ID="Freemind_Link_1045379727" TEXT="Sound">
<icon BUILTIN="help"/>
</node>
<node ID="Freemind_Link_107267630" TEXT="&quot;Engine&quot;">
<icon BUILTIN="help"/>
<icon BUILTIN="button_ok"/>
</node>
<node ID="Freemind_Link_1045379727" TEXT="Sample">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node ID="Freemind_Link_188779968" TEXT="Test Suite">
@ -37,7 +36,9 @@
<icon BUILTIN="button_ok"/>
</node>
<node ID="Freemind_Link_1104675603" TEXT="Tests">
<node ID="Freemind_Link_1348104879" TEXT="Kernel/AppCore"/>
<node ID="Freemind_Link_1348104879" TEXT="Kernel/AppCore">
<node ID="Freemind_Link_1664207862" TEXT="how to test?"/>
</node>
<node ID="Freemind_Link_288973656" TEXT="Texture">
<icon BUILTIN="button_ok"/>
</node>
@ -52,8 +53,9 @@
<node ID="Freemind_Link_25725154" TEXT="Sound/Music"/>
</node>
</node>
<node FOLDED="true" ID="Freemind_Link_22783417" TEXT="Example Game">
<node ID="Freemind_Link_22783417" TEXT="Example Game">
<node ID="Freemind_Link_714736465" TEXT="Drawing Program?"/>
<node ID="Freemind_Link_74598855" TEXT="Public Project?"/>
</node>
</node>
<node ID="Freemind_Link_486829238" POSITION="right" TEXT="0.2 Release">
@ -63,21 +65,25 @@
<node ID="Freemind_Link_1497432478" TEXT="Particle System"/>
<node ID="Freemind_Link_1339011485" TEXT="Tilemap System"/>
<node ID="Freemind_Link_1070201117" TEXT="Transitions"/>
<node ID="Freemind_Link_654490435" TEXT="Second Example Game"/>
<node ID="Freemind_Link_654490435" TEXT="Second Example Game">
<node ID="Freemind_Link_1191623789" TEXT="Public Project?"/>
</node>
<node ID="Freemind_Link_1851655735" TEXT="Music">
<icon BUILTIN="help"/>
</node>
</node>
<node ID="Freemind_Link_351891371" POSITION="left" TEXT="General Mateinance">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node ID="Freemind_Link_1978849189" TEXT="Clean up CVS">
<font NAME="SansSerif" SIZE="12"/>
</node>
<node ID="Freemind_Link_1642641448" TEXT="Ensure compilation succeeds on Win/Linux simultaneously"/>
<node ID="Freemind_Link_330674889" TEXT="Find an OSX user to test"/>
<node ID="Freemind_Link_1190200631" TEXT="Clean up source"/>
</node>
<node ID="Freemind_Link_682620075" POSITION="left" TEXT="Current Problems">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<node ID="Freemind_Link_1080393911" TEXT="audio:: could using some cleaning"/>
<node ID="Freemind_Link_1979809987" TEXT="Sample doesn&apos;t load via FileBuffer yet"/>
</node>
<node COLOR="#147f1e" ID="Freemind_Link_438641521" POSITION="left" TEXT="Version: $Id: photon.mm,v 1.11 2005/07/04 03:06:48 cozman Exp $">
<node COLOR="#147f1e" ID="Freemind_Link_438641521" POSITION="left" TEXT="Version: $Id: photon.mm,v 1.12 2005/07/05 06:44:55 cozman Exp $">
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
</node>
</node>

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: Application.cpp,v 1.10 2005/06/13 05:38:06 cozman Exp $
// $Id: Application.cpp,v 1.11 2005/07/05 06:44:56 cozman Exp $
#include "Application.hpp"
@ -13,7 +13,6 @@
#include "GL/gl.h"
#include <boost/lexical_cast.hpp>
#include <iostream>
#include "exceptions.hpp"
#include "Log.hpp"
#include "Kernel.hpp"

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: AudioCore.cpp,v 1.6 2005/07/04 03:06:48 cozman Exp $
// $Id: AudioCore.cpp,v 1.7 2005/07/05 06:44:56 cozman Exp $
#ifdef PHOTON_USE_OPENAL
@ -19,7 +19,7 @@ namespace photon
namespace audio
{
AudioCore::AudioCore()
AudioCore::AudioCore()
{
util::VersionInfo oalReq(0,0,7); // requires OpenAL 1.0 (TODO: check?)
util::ensureVersion("OpenAL", initOpenAL(), oalReq);
@ -48,51 +48,6 @@ std::string AudioCore::getAudioDeviceName() const
return name;
}
util::VersionInfo AudioCore::initOpenAL()
{
ALCdevice* device(0);
ALCcontext* context(0);
std::stringstream ss; // stream for parsing version
std::string junks; // junk string for parsing
char junkc; // junk character for parsing
uint major,minor,patch; // version numbers
// obtain default device if no deviceName is set, otherwise use deviceName
device = alcOpenDevice(deviceName_.empty() ? 0 :
reinterpret_cast<const ALubyte*>(deviceName_.c_str()) );
if(device == 0)
{
throw APIError("Failed to obtain OpenAL device " + deviceName_ + ": " +
checkOpenALError());
}
// create context
context = alcCreateContext(device,0);
if(context == 0)
{
throw APIError("Failed to obtain an OpenAL context: " +
checkOpenALError());
}
alcMakeContextCurrent(context); // context must be current to get version
ss << alGetString(AL_VERSION);
#if defined(WINVER)
ss >> junks >> major >> junkc >> minor; // format is "OpenAL 1.0"
#elif defined(linux)
ss >> major >> junkc >> minor >> junkc >> patch;
#else
#warning OpenAL only built on Windows/Linux, find out version on OSX
#endif
//std::cerr << util::VersionInfo(major,minor,patch);
return util::VersionInfo(major,minor,patch);
}
std::string AudioCore::checkOpenALError()
{
ALenum errCode = alGetError();
@ -126,6 +81,64 @@ std::string AudioCore::checkOpenALError()
return err;
}
void AudioCore::throwOpenALError(const std::string& func)
{
std::string err( checkOpenALError() );
if(err.length())
{
throw APIError(err + " within " + func);
}
}
util::VersionInfo AudioCore::initOpenAL()
{
ALCdevice* device(0);
ALCcontext* context(0);
std::stringstream ss; // stream for parsing version
std::string junks; // junk string for parsing
char junkc; // junk character for parsing
uint major,minor,patch; // version numbers
// obtain default device if no deviceName is set, otherwise use deviceName
device = alcOpenDevice(deviceName_.empty() ? 0 :
reinterpret_cast<const ALubyte*>(deviceName_.c_str()) );
if(device == 0)
{
throw APIError("Failed to obtain OpenAL device " + deviceName_ + ": " +
checkOpenALError());
}
// create context
context = alcCreateContext(device,0);
if(context == 0)
{
throw APIError("Failed to obtain an OpenAL context: " +
checkOpenALError());
}
alcMakeContextCurrent(context); // context must be current to get version
// setup listener to default position
ALfloat posvel[] = { 0.0, 0.0, 0.0 };
ALfloat ori[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };
alListenerfv(AL_POSITION, posvel);
alListenerfv(AL_VELOCITY, posvel);
alListenerfv(AL_ORIENTATION, ori);
ss << alGetString(AL_VERSION);
#if defined(WINVER)
ss >> junks >> major >> junkc >> minor; // format is "OpenAL 1.0"
#elif defined(linux)
ss >> major >> junkc >> minor >> junkc >> patch;
#else
#warning OpenAL only built on Windows/Linux, find out version on OSX
#endif
return util::VersionInfo(major,minor,patch);
}
void AudioCore::setDesiredDevice(const std::string& name)
{
// deviceName_ is used inside initOpenAL, must be set prior to construction

View File

@ -0,0 +1,65 @@
//This file is part of Photon (http://photon.sourceforge.net)
//Copyright (C) 2004-2005 James Turk
//
// Author:
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: SampleResourceManager.cpp,v 1.1 2005/07/05 06:44:56 cozman Exp $
#include "audio/SampleResourceManager.hpp"
#include "audio/AudioCore.hpp"
#include "util/FileBuffer.hpp"
#include "AL/al.h"
#include "AL/alut.h"
namespace photon
{
namespace audio
{
void SampleResourceManager::getAudioData(const std::string& name,
uint& bufferID)
{
SampleResource resource( getResource(name) );
bufferID = resource.bufferID;
}
void SampleResourceManager::loadResourceData(SampleResource &res,
const ResourceDescriptor& desc)
{
//util::FileBuffer buf(path.path);
// OpenAL variables to load into.
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
ALboolean loop;
///std::vector<ubyte> data = buf.getData();
alGenBuffers(1, &res.bufferID); // create OpenAL buffer
AudioCore::throwOpenALError("alGenBuffers");
alutLoadWAVFile((ALbyte*)desc.path.c_str(), &format, &data, &size, &freq, &loop);
AudioCore::throwOpenALError("alutLoadWAVFile");
alBufferData(res.bufferID, format, data, size, freq);
alutUnloadWAV(format, data, size, freq);
AudioCore::throwOpenALError("SampleResourceManager::loadResourceData");
}
void SampleResourceManager::freeResourceData(SampleResource& res)
{
if(alIsBuffer(res.bufferID))
{
alDeleteBuffers(1, &res.bufferID);
}
}
}
}

View File

@ -5,26 +5,72 @@
// James Turk (jpt2433@rit.edu)
//
// Version:
// $Id: AudioCore_test.cpp,v 1.2 2005/07/04 03:06:48 cozman Exp $
// $Id: AudioCore_test.cpp,v 1.3 2005/07/05 06:44:56 cozman Exp $
#include "photon.hpp"
#include <iostream>
using namespace photon;
#include <boost/lexical_cast.hpp>
#ifdef PHOTON_USE_OPENAL
using namespace photon::audio;
class MainTask : public Task
{
public:
MainTask() :
Task("MainTask"),
app(AppCore::getInstance()),
video(video::VideoCore::getInstance())
{
LogSinkPtr csp( new ConsoleSink("console") );
log.addSink(csp);
video.setOrthoView(800,600);
Sample::addResource("wavdata/ocean.wav");
sample.open("wavdata/ocean.wav");
sample.play();
}
void update()
{
static double t=0;
if(app.getTime() - t > 1.0)
{
app.setTitle("FPS: " +
boost::lexical_cast<std::string>(app.getFramerate()) );
t = app.getTime();
}
video.clear();
}
private:
audio::Sample sample;
Log log;
AppCore& app;
video::VideoCore& video;
};
class AudioTest : public Application
{
public:
int main(const StrVec& args)
{
AppCore::getInstance().createDisplay(800,600,32,0,0,false);
AudioCore::setDesiredDevice("OSS");
new AudioCore;
AudioCore& audio(AudioCore::getInstance());
std::cout << audio.getAudioDeviceName();
Kernel::getInstance().addTask(TaskPtr(new MainTask()));
Kernel::getInstance().run();
return 0;
}