cpp_photon/include/audio/Source.hpp

362 lines
9.1 KiB
C++
Raw Permalink Normal View History

2005-07-05 06:44:55 +00:00
//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.5 2005/10/28 22:13:33 cozman Exp $
2005-07-18 05:14:18 +00:00
#ifdef PHOTON_USE_OPENAL
2005-07-05 06:44:55 +00:00
#ifndef PHOTON_AUDIO_SOURCE_HPP
#define PHOTON_AUDIO_SOURCE_HPP
#include "AL/al.h"
#include "ResourceManaged.hpp"
#include "audio/AudioCore.hpp"
namespace photon
{
namespace audio
{
// Class: Source
// Simple wrapper object around an OpenAL source, defines the interface used
// for Sample and Music.
2005-07-18 05:14:18 +00:00
//
// Source is a template class and can not be used directly, use either Sample
// or Music. Sample is for playing small files such as sound effects. Music
// is for streaming files such as background music.
//
// Source is a resource managed class, and therefore all resources should
// be registered using <Source::addResource> and then loaded by their assigned
// name via <Source::open> or the appropriate constructor.
2005-07-05 06:44:55 +00:00
//
// Operators:
// - Source = Source
// - bool : True if source has loaded buffer, false if not.
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 Vorbis.
2005-07-05 06:44:55 +00:00
//
// Parameters:
// name - Name of the Source <Resource> to open.
void open(const std::string& name);
Source& operator=(const Source& rhs);
operator bool() const;
2005-07-18 05:14:18 +00:00
2005-07-05 06:44:55 +00:00
// 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:
2005-07-18 05:14:18 +00:00
// Function: isValid
// Determine status of Source.
//
// Returns:
// True if source is loaded, false if source is not loaded/initialized.
bool isValid() const;
// Function: isPlaying
// Determine if source is playing.
//
// Returns:
// True if source is playing, false if source is stopped.
bool isPlaying() const;
// Function: isLooping
// Determine if source is looping.
//
// Returns:
// True if source is looping, false if source is not looping.
bool isLooping() const;
2005-07-05 06:44:55 +00:00
//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:
2005-07-18 05:14:18 +00:00
uint sourceID_; // sources store their own sourceID (can't resource manage)
2005-07-05 06:44:55 +00:00
2005-07-18 05:14:18 +00:00
static const float ORIGIN[]; // use origin
2005-07-05 06:44:55 +00:00
};
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_);
OALAudioCore::throwOpenALError("Source::Source()");
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
Source<ResMgrT>::Source(const Source &rhs) :
ResourceManaged<ResMgrT>(rhs)
{
alGenSources(1, &sourceID_);
OALAudioCore::throwOpenALError("Source::Source(const Source&)");
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
Source<ResMgrT>::Source(const std::string& name)
{
alGenSources(1, &sourceID_);
OALAudioCore::throwOpenALError("Source::Source(const std::string&)");
2005-07-05 06:44:55 +00:00
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);
2005-08-08 21:39:40 +00:00
ResourceManaged<ResMgrT>::resMgr_.getAudioData(
ResourceManaged<ResMgrT>::getName(), bufferID);
2005-07-05 06:44:55 +00:00
// attach buffer to source and set default settings
2005-07-05 06:44:55 +00:00
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);
OALAudioCore::throwOpenALError("Source::open");
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
Source<ResMgrT>& Source<ResMgrT>::operator=(const Source<ResMgrT>& rhs)
{
if(&rhs != this)
{
uint bufferID;
ResourceManaged<ResMgrT>::operator=(rhs);
2005-08-08 21:39:40 +00:00
ResourceManaged<ResMgrT>::resMgr_.getAudioData(
ResourceManaged<ResMgrT>::getName(), bufferID);
2005-07-05 06:44:55 +00:00
// 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);
OALAudioCore::throwOpenALError("Source::operator=");
2005-07-05 06:44:55 +00:00
}
return *this;
}
template<class ResMgrT>
Source<ResMgrT>::operator bool() const
{
return isValid(); // do the work in isValid to avoid split implementation
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::play()
{
2005-07-18 05:14:18 +00:00
if(!isValid())
{
throw PreconditionException("Invalid Source::play call.");
}
alSourcePlay(sourceID_); // play it
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::stop()
{
2005-07-18 05:14:18 +00:00
if(!isValid())
{
throw PreconditionException("Invalid Source::stop call.");
}
alSourceStop(sourceID_); // stop it
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::pause()
{
2005-07-18 05:14:18 +00:00
if(!isValid())
{
throw PreconditionException("Invalid Source::pause call.");
}
alSourcePause(sourceID_); // pause it
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::rewind()
{
2005-07-18 05:14:18 +00:00
if(!isValid())
{
throw PreconditionException("Invalid Source::rewind call.");
}
alSourceRewind(sourceID_); // rewind it (doesn't stop)
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::setLooping(bool loop)
{
2005-07-18 05:14:18 +00:00
if(!isValid())
{
throw PreconditionException("Invalid Source::setLooping call.");
}
alSourcei(sourceID_, AL_LOOPING, loop); // toggle looping
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
2005-07-18 05:14:18 +00:00
bool Source<ResMgrT>::isValid() const
{
return alIsSource(sourceID_) == AL_TRUE; // true if valid audio loaded
2005-07-18 05:14:18 +00:00
}
template<class ResMgrT>
bool Source<ResMgrT>::isPlaying() const
{
if(!isValid())
{
throw PreconditionException("Invalid Source::isPlaying call.");
}
// check state using OpenAL query function
2005-07-18 05:14:18 +00:00
int state;
alGetSourcei(sourceID_, AL_SOURCE_STATE, &state);
return state == AL_PLAYING;
}
template<class ResMgrT>
bool Source<ResMgrT>::isLooping() const
{
if(!isValid())
{
throw PreconditionException("Invalid Source::isLooping call.");
}
// query looping status
2005-07-18 05:14:18 +00:00
int loop;
alGetSourcei(sourceID_, AL_LOOPING, &loop);
return loop == AL_TRUE;
}
template<class ResMgrT>
void Source<ResMgrT>::addResource(const std::string& name,
const std::string& path)
2005-07-05 06:44:55 +00:00
{
// adds an aliased resource
2005-08-08 21:39:40 +00:00
ResourceManaged<ResMgrT>::resMgr_.newResource(name,
ResourceDescriptor(path));
2005-07-05 06:44:55 +00:00
}
template<class ResMgrT>
void Source<ResMgrT>::addResource(const std::string& path)
{
// add non-aliased resource
2005-08-08 21:39:40 +00:00
ResourceManaged<ResMgrT>::resMgr_.newResource(path,
ResourceDescriptor(path));
2005-07-05 06:44:55 +00:00
}
}
}
#endif //PHOTON_AUDIO_SOURCE_HPP
2005-07-18 05:14:18 +00:00
#endif //PHOTON_USE_OPENAL