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

--HG--
branch : nfb
This commit is contained in:
2013-11-17 01:46:12 -08:00
parent 7f09dae997
commit 19bf71938d
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_enable_obstruction = true;
m_start_audio_frame = -1; m_start_audio_frame = -1;
m_paused_audio_frame = 0;
} }
KRAudioSource::~KRAudioSource() KRAudioSource::~KRAudioSource()
@@ -314,12 +315,13 @@ void KRAudioSource::setRolloffFactor(float rolloff_factor)
void KRAudioSource::setLooping(bool looping) 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; m_looping = looping;
// Audio source must be stopped and re-started for loop mode changes to take effect
} }
bool KRAudioSource::getLooping() bool KRAudioSource::getLooping()
{ {
// Returns true if the playback will automatically loop
return m_looping; return m_looping;
} }
@@ -400,8 +402,15 @@ void KRAudioSource::physicsUpdate(float deltaTime)
void KRAudioSource::play() void KRAudioSource::play()
{ {
// 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(); KRAudioManager *audioManager = getContext().getAudioManager();
m_start_audio_frame = audioManager->getAudioFrame(); assert(m_start_audio_frame == -1);
m_start_audio_frame = audioManager->getAudioFrame() - m_paused_audio_frame;
m_paused_audio_frame = -1;
audioManager->activateAudioSource(this); audioManager->activateAudioSource(this);
if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) { if(audioManager->getAudioEngine() == KRAudioManager::KRAKEN_AUDIO_OPENAL) {
getContext().getAudioManager()->makeCurrentContext(); getContext().getAudioManager()->makeCurrentContext();
@@ -420,18 +429,27 @@ void KRAudioSource::play()
} }
ALDEBUG(alSourcePlay(m_sourceID)); ALDEBUG(alSourcePlay(m_sourceID));
} }
}
m_playing = true; m_playing = true;
} }
void KRAudioSource::stop() void KRAudioSource::stop()
{ {
// 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_start_audio_frame = -1;
m_playing = false; m_playing = false;
getContext().getAudioManager()->deactivateAudioSource(this); getContext().getAudioManager()->deactivateAudioSource(this);
} }
}
bool KRAudioSource::isPlaying() 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; return m_playing;
} }
@@ -504,16 +522,46 @@ int KRAudioSource::getBufferFrame()
return m_currentBufferFrame; 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) void KRAudioSource::sample(int frame_count, int channel, float *buffer, float gain)
{ {
KRAudioSample *source_sample = getAudioSample(); KRAudioSample *source_sample = getAudioSample();
if(source_sample && m_playing) { 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); source_sample->sample(next_frame, frame_count, channel, buffer, gain, m_looping);
if(!m_looping && next_frame > source_sample->getFrameCount()) { if(!m_looping && next_frame > source_sample->getFrameCount()) {
stop(); stop();

View File

@@ -51,10 +51,41 @@ public:
virtual void physicsUpdate(float deltaTime); 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); 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(); 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(); 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(); 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); void setSample(const std::string &sound_name);
std::string getSample(); std::string getSample();
@@ -66,8 +97,7 @@ public:
float getPitch(); float getPitch();
void setPitch(float pitch); void setPitch(float pitch);
bool getLooping();
void setLooping(bool looping);
bool getIs3D(); bool getIs3D();
void setIs3D(bool is3D); void setIs3D(bool is3D);
@@ -94,12 +124,11 @@ public:
KRAudioBuffer *getBuffer(); KRAudioBuffer *getBuffer();
int getBufferFrame(); int getBufferFrame();
__int64_t getStartAudioFrame();
void sample(int frame_count, int channel, float *buffer, float gain); void sample(int frame_count, int channel, float *buffer, float gain);
private: 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 int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer
void advanceBuffer(); void advanceBuffer();