diff options
Diffstat (limited to 'intern/audaspace/intern')
-rw-r--r-- | intern/audaspace/intern/AUD_SequencerHandle.cpp | 253 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_SequencerHandle.h | 18 |
2 files changed, 188 insertions, 83 deletions
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp index 135c960471c..56cfa0de683 100644 --- a/intern/audaspace/intern/AUD_SequencerHandle.cpp +++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp @@ -31,18 +31,92 @@ #include "AUD_ReadDevice.h" #include "AUD_MutexLock.h" +#define KEEP_TIME 10 + +void AUD_SequencerHandle::start() +{ + // we already tried to start, aborting + if(!m_valid) + return; + + // in case the sound is playing, we need to stop first + stop(); + + AUD_MutexLock lock(*m_entry); + + // let's try playing + if(m_entry->m_sound.get()) + { + m_handle = m_device.play(m_entry->m_sound, true); + m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle); + + // after starting we have to set the properties, so let's ensure that + m_status--; + } + + // if the sound could not be played, we invalidate + m_valid = m_handle.get(); +} + +bool AUD_SequencerHandle::updatePosition(float position) +{ + AUD_MutexLock lock(*m_entry); + + if(m_handle.get()) + { + // we currently have a handle, let's check where we are + if(position >= m_entry->m_end) + { + if(position >= m_entry->m_end + KEEP_TIME) + // far end, stopping + stop(); + else + { + // close end, just pausing + m_handle->pause(); + return true; + } + } + else if(position >= m_entry->m_begin) + { + // inside, resuming + m_handle->resume(); + return true; + } + else + { + if(position < m_entry->m_begin - KEEP_TIME) + // far beginning, stopping + stop(); + else + { + // close beginning, just pausing + m_handle->pause(); + return true; + } + } + } + else + { + // we don't have a handle, let's start if we should be playing + if(position >= m_entry->m_begin && position <= m_entry->m_end) + { + start(); + return m_valid; + } + } + + return false; +} + AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) : m_entry(entry), + m_valid(true), m_status(0), m_pos_status(0), m_sound_status(0), m_device(device) { - if(entry->m_sound.get()) - { - m_handle = device.play(entry->m_sound, true); - m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle); - } } AUD_SequencerHandle::~AUD_SequencerHandle() @@ -63,101 +137,116 @@ void AUD_SequencerHandle::stop() { if(m_handle.get()) m_handle->stop(); + m_handle = boost::shared_ptr<AUD_IHandle>(); + m_3dhandle = boost::shared_ptr<AUD_I3DHandle>(); } void AUD_SequencerHandle::update(float position, float frame, float fps) { - if(m_handle.get()) + if(m_sound_status != m_entry->m_sound_status) { - AUD_MutexLock lock(*m_entry); - if(position >= m_entry->m_end) - m_handle->pause(); - else if(position >= m_entry->m_begin) - m_handle->resume(); - - if(m_sound_status != m_entry->m_sound_status) - { - if(m_handle.get()) - m_handle->stop(); + // if a new sound has been set, it's possible to get valid again! + m_sound_status = m_entry->m_sound_status; + m_valid = true; - if(m_entry->m_sound.get()) - { - m_handle = m_device.play(m_entry->m_sound, true); - m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle); - } + // stop whatever sound has been playing + stop(); - m_sound_status = m_entry->m_sound_status; - m_pos_status--; - m_status--; - } + // seek starts and seeks to the correct position + if(!seek(position)) + // no handle, aborting + return; + } + else + { + if(!m_valid) + // invalid, aborting + return; - if(m_pos_status != m_entry->m_pos_status) + if(m_handle.get()) { - seek(position); - - m_pos_status = m_entry->m_pos_status; + // we have a handle, let's update the position + if(!updatePosition(position)) + // lost handle, aborting + return; } - - if(m_status != m_entry->m_status) + else { - m_3dhandle->setRelative(m_entry->m_relative); - m_3dhandle->setVolumeMaximum(m_entry->m_volume_max); - m_3dhandle->setVolumeMinimum(m_entry->m_volume_min); - m_3dhandle->setDistanceMaximum(m_entry->m_distance_max); - m_3dhandle->setDistanceReference(m_entry->m_distance_reference); - m_3dhandle->setAttenuation(m_entry->m_attenuation); - m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer); - m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner); - m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer); - - m_status = m_entry->m_status; + // we don't have a handle, let's see if we can start + if(!seek(position)) + return; } + } - float value; - - m_entry->m_volume.read(frame, &value); - m_handle->setVolume(value); - m_entry->m_pitch.read(frame, &value); - m_handle->setPitch(value); - m_entry->m_panning.read(frame, &value); - AUD_SoftwareDevice::setPanning(m_handle.get(), value); + AUD_MutexLock lock(*m_entry); + if(m_pos_status != m_entry->m_pos_status) + { + m_pos_status = m_entry->m_pos_status; - AUD_Vector3 v, v2; - AUD_Quaternion q; + // position changed, need to seek + if(!seek(position)) + // lost handle, aborting + return; + } - m_entry->m_orientation.read(frame, q.get()); - m_3dhandle->setSourceOrientation(q); - m_entry->m_location.read(frame, v.get()); - m_3dhandle->setSourceLocation(v); - m_entry->m_location.read(frame + 1, v2.get()); - v2 -= v; - m_3dhandle->setSourceVelocity(v2 * fps); + // so far everything alright and handle is there, let's keep going - if(m_entry->m_muted) - m_handle->setVolume(0); + if(m_status != m_entry->m_status) + { + m_status = m_entry->m_status; + + m_3dhandle->setRelative(m_entry->m_relative); + m_3dhandle->setVolumeMaximum(m_entry->m_volume_max); + m_3dhandle->setVolumeMinimum(m_entry->m_volume_min); + m_3dhandle->setDistanceMaximum(m_entry->m_distance_max); + m_3dhandle->setDistanceReference(m_entry->m_distance_reference); + m_3dhandle->setAttenuation(m_entry->m_attenuation); + m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer); + m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner); + m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer); } + + float value; + + m_entry->m_volume.read(frame, &value); + m_handle->setVolume(value); + m_entry->m_pitch.read(frame, &value); + m_handle->setPitch(value); + m_entry->m_panning.read(frame, &value); + AUD_SoftwareDevice::setPanning(m_handle.get(), value); + + AUD_Vector3 v, v2; + AUD_Quaternion q; + + m_entry->m_orientation.read(frame, q.get()); + m_3dhandle->setSourceOrientation(q); + m_entry->m_location.read(frame, v.get()); + m_3dhandle->setSourceLocation(v); + m_entry->m_location.read(frame + 1, v2.get()); + v2 -= v; + m_3dhandle->setSourceVelocity(v2 * fps); + + if(m_entry->m_muted) + m_handle->setVolume(0); } -void AUD_SequencerHandle::seek(float position) +bool AUD_SequencerHandle::seek(float position) { - if(m_handle.get()) - { - AUD_MutexLock lock(*m_entry); - if(position >= m_entry->m_end) - { - m_handle->pause(); - return; - } - - float seekpos = position - m_entry->m_begin; - if(seekpos < 0) - seekpos = 0; - seekpos += m_entry->m_skip; - m_handle->setPitch(1.0f); - m_handle->seek(seekpos); - if(position < m_entry->m_begin) - m_handle->pause(); - else - m_handle->resume(); - } + if(!m_valid) + // sound not valid, aborting + return false; + + if(!updatePosition(position)) + // no handle, aborting + return false; + + AUD_MutexLock lock(*m_entry); + float seekpos = position - m_entry->m_begin; + if(seekpos < 0) + seekpos = 0; + seekpos += m_entry->m_skip; + m_handle->setPitch(1.0f); + m_handle->seek(seekpos); + + return true; } diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/intern/audaspace/intern/AUD_SequencerHandle.h index 881bbdd43dc..306df4a84b9 100644 --- a/intern/audaspace/intern/AUD_SequencerHandle.h +++ b/intern/audaspace/intern/AUD_SequencerHandle.h @@ -51,6 +51,9 @@ private: /// The 3D handle in the read device. boost::shared_ptr<AUD_I3DHandle> m_3dhandle; + /// Whether the sound is playable. + bool m_valid; + /// The last read status from the entry. int m_status; @@ -63,6 +66,18 @@ private: /// The read device this handle is played on. AUD_ReadDevice& m_device; + /** + * Starts playing back the handle. + */ + void start(); + + /** + * Updates the handle state depending on position. + * \param position Current playback position in seconds. + * \return Whether the handle is valid. + */ + bool updatePosition(float position); + public: /** * Creates a new sequenced handle. @@ -99,8 +114,9 @@ public: /** * Seeks the handle to a specific time position. * \param position The time to seek to. + * \return Whether the handle is valid. */ - void seek(float position); + bool seek(float position); }; #endif //__AUD_SEQUENCERHANDLE_H__ |