Implemented API to read and seek the audio playback position of KRAudioSource

--HG--
extra : source : 5ef720e0f476c72b85a7e2fc841af965d2038264
This commit is contained in:
2013-11-17 01:46:12 -08:00
parent b0bfd6b29c
commit 29b518610b
2 changed files with 106 additions and 29 deletions

View File

@@ -56,6 +56,7 @@ KRAudioSource::KRAudioSource(KRScene &scene, std::string name) : KRNode(scene, n
m_enable_obstruction = true;
m_start_audio_frame = -1;
m_paused_audio_frame = 0;
}
KRAudioSource::~KRAudioSource()
@@ -314,12 +315,13 @@ void KRAudioSource::setRolloffFactor(float rolloff_factor)
void KRAudioSource::setLooping(bool looping)
{
// Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect
m_looping = looping;
// Audio source must be stopped and re-started for loop mode changes to take effect
}
bool KRAudioSource::getLooping()
{
// Returns true if the playback will automatically loop
return m_looping;
}
@@ -400,38 +402,54 @@ void KRAudioSource::physicsUpdate(float deltaTime)
void KRAudioSource::play()
{
KRAudioManager *audioManager = getContext().getAudioManager();
m_start_audio_frame = audioManager->getAudioFrame();
audioManager->activateAudioSource(this);
if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) {
getContext().getAudioManager()->makeCurrentContext();
prime();
updatePosition();
// Start playback of audio at the current audio sample position. If audio is already playing, this has no effect.
// play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample.
// If not set to looping, audio playback ends automatically at the end of the sample
if(!m_playing) {
KRAudioManager *audioManager = getContext().getAudioManager();
assert(m_start_audio_frame == -1);
m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame;
m_paused_audio_frame = -1;
audioManager->activateAudioSource(this);
if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) {
getContext().getAudioManager()->makeCurrentContext();
prime();
updatePosition();
if(m_is3d) {
ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f));
ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance));
ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor));
ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb)));
ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE));
} else {
ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE));
ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0));
if(m_is3d) {
ALDEBUG(alSource3f(m_sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f));
ALDEBUG(alSourcef(m_sourceID, AL_REFERENCE_DISTANCE, m_referenceDistance));
ALDEBUG(alSourcef(m_sourceID, AL_ROLLOFF_FACTOR, m_rolloffFactor));
ALDEBUG(alcASASetSourceProc(ALC_ASA_REVERB_SEND_LEVEL, m_sourceID, &m_reverb, sizeof(m_reverb)));
ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_FALSE));
} else {
ALDEBUG(alSourcei(m_sourceID, AL_SOURCE_RELATIVE, AL_TRUE));
ALDEBUG(alSource3f(m_sourceID, AL_POSITION, 0.0, 0.0, 0.0));
}
ALDEBUG(alSourcePlay(m_sourceID));
}
ALDEBUG(alSourcePlay(m_sourceID));
}
m_playing = true;
}
void KRAudioSource::stop()
{
m_start_audio_frame = -1;
m_playing = false;
getContext().getAudioManager()->deactivateAudioSource(this);
// Stop playback of audio. If audio is already stopped, this has no effect.
// If play() is called afterwards, playback will continue at the current audio sample position.
if(m_playing) {
m_paused_audio_frame = getAudioFrame();
m_start_audio_frame = -1;
m_playing = false;
getContext().getAudioManager()->deactivateAudioSource(this);
}
}
bool KRAudioSource::isPlaying()
{
// Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample.
return m_playing;
}
@@ -504,16 +522,46 @@ int KRAudioSource::getBufferFrame()
return m_currentBufferFrame;
}
__int64_t KRAudioSource::getStartAudioFrame()
__int64_t KRAudioSource::getAudioFrame()
{
return m_start_audio_frame;
// Returns the audio playback position in units of integer audio frames.
if(m_playing) {
return getContext().getAudioManager()->getAudioFrame() - m_start_audio_frame;
} else {
return m_paused_audio_frame;
}
}
void KRAudioSource::setAudioFrame(__int64_t next_frame)
{
// Sets the audio playback position with units of integer audio frames.
if(m_playing) {
m_start_audio_frame = getContext().getAudioManager()->getAudioFrame() - next_frame;
} else {
m_paused_audio_frame = next_frame;
}
}
float KRAudioSource::getAudioTime()
{
// Gets the audio playback position with units of floating point seconds.
return getAudioFrame() / 44100.0f;
}
void KRAudioSource::setAudioTime(float new_position)
{
// Sets the audio playback position with units of floating point seconds.
setAudioFrame(new_position * 44100.0f);
}
void KRAudioSource::sample(int frame_count, int channel, float *buffer, float gain)
{
KRAudioSample *source_sample = getAudioSample();
if(source_sample && m_playing) {
__int64_t next_frame = getContext().getAudioManager()->getAudioFrame() - getStartAudioFrame();
__int64_t next_frame = getAudioFrame();
source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping);
if(!m_looping && next_frame > source_sample->getFrameCount()) {
stop();

View File

@@ -51,10 +51,41 @@ public:
virtual void physicsUpdate(float deltaTime);
void render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass);
// ---- Audio Playback Controls ----
// Start playback of audio at the current audio sample position. If audio is already playing, this has no effect.
// play() does not automatically seek to the beginning of the sample. Call setAudioFrame( 0 ) first if you wish the playback to begin at the start of the audio sample.
// If not set to looping, audio playback ends automatically at the end of the sample
void play();
// Stop playback of audio. If audio is already stopped, this has no effect.
// If play() is called afterwards, playback will continue at the current audio sample position.
void stop();
// Returns true if audio is playing. Will return false if a non-looped playback has reached the end of the audio sample.
bool isPlaying();
// Returns the audio playback position in units of integer audio frames.
__int64_t getAudioFrame();
// Sets the audio playback position with units of integer audio frames.
void setAudioFrame(__int64_t next_frame);
// Gets the audio playback position with units of floating point seconds.
float getAudioTime();
// Sets the audio playback position with units of floating point seconds.
void setAudioTime(float new_position);
// Returns true if the playback will automatically loop
bool getLooping();
// Enable or disable looping playback; Audio source must be stopped and re-started for loop mode changes to take effect
void setLooping(bool looping);
// ---- End: Audio Playback Controls ----
void setSample(const std::string &sound_name);
std::string getSample();
@@ -66,8 +97,7 @@ public:
float getPitch();
void setPitch(float pitch);
bool getLooping();
void setLooping(bool looping);
bool getIs3D();
void setIs3D(bool is3D);
@@ -94,12 +124,11 @@ public:
KRAudioBuffer *getBuffer();
int getBufferFrame();
__int64_t getStartAudioFrame();
void sample(int frame_count, int channel, float *buffer, float gain);
private:
__int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback
__int64_t m_start_audio_frame; // Global audio frame that matches the start of the audio sample playback; when paused or not playing, this contains a value of -1
__int64_t m_paused_audio_frame; // When paused or not playing, this contains the local audio frame number. When playing, this contains a value of -1
int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer
void advanceBuffer();