Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/audaspace/src/sequence/SequenceHandle.cpp')
-rw-r--r--extern/audaspace/src/sequence/SequenceHandle.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp
new file mode 100644
index 00000000000..140b1fbd94a
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceHandle.cpp
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "SequenceHandle.h"
+#include "sequence/SequenceEntry.h"
+#include "devices/ReadDevice.h"
+#include "Exception.h"
+
+#include <mutex>
+
+#define KEEP_TIME 10
+
+AUD_NAMESPACE_BEGIN
+
+void SequenceHandle::start()
+{
+ // we already tried to start, aborting
+ if(!m_valid)
+ return;
+
+ // in case the sound is playing, we need to stop first
+ stop();
+
+ std::lock_guard<ILockable> lock(*m_entry);
+
+ // let's try playing
+ if(m_entry->m_sound.get())
+ {
+ try
+ {
+ m_handle = m_device.play(m_entry->m_sound, true);
+ m_3dhandle = std::dynamic_pointer_cast<I3DHandle>(m_handle);
+ }
+ catch(Exception&)
+ {
+ // handle stays invalid in case we get an exception
+ }
+
+ // 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 SequenceHandle::updatePosition(float position)
+{
+ std::lock_guard<ILockable> 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;
+}
+
+SequenceHandle::SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device) :
+ m_entry(entry),
+ m_valid(true),
+ m_status(0),
+ m_pos_status(0),
+ m_sound_status(0),
+ m_device(device)
+{
+}
+
+SequenceHandle::~SequenceHandle()
+{
+ stop();
+}
+
+int SequenceHandle::compare(std::shared_ptr<SequenceEntry> entry) const
+{
+ if(m_entry->getID() < entry->getID())
+ return -1;
+ else if(m_entry->getID() == entry->getID())
+ return 0;
+ return 1;
+}
+
+void SequenceHandle::stop()
+{
+ if(m_handle.get())
+ m_handle->stop();
+ m_handle = nullptr;
+ m_3dhandle = nullptr;
+}
+
+void SequenceHandle::update(float position, float frame, float fps)
+{
+ if(m_sound_status != m_entry->m_sound_status)
+ {
+ // 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;
+
+ // stop whatever sound has been playing
+ stop();
+
+ // seek starts and seeks to the correct position
+ if(!seek(position))
+ // no handle, aborting
+ return;
+ }
+ else
+ {
+ if(!m_valid)
+ // invalid, aborting
+ return;
+
+ if(m_handle.get())
+ {
+ // we have a handle, let's update the position
+ if(!updatePosition(position))
+ // lost handle, aborting
+ return;
+ }
+ else
+ {
+ // we don't have a handle, let's see if we can start
+ if(!seek(position))
+ return;
+ }
+ }
+
+ std::lock_guard<ILockable> lock(*m_entry);
+ if(m_pos_status != m_entry->m_pos_status)
+ {
+ m_pos_status = m_entry->m_pos_status;
+
+ // position changed, need to seek
+ if(!seek(position))
+ // lost handle, aborting
+ return;
+ }
+
+ // so far everything alright and handle is there, let's keep going
+
+ if(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);
+
+ m_status = m_entry->m_status;
+ }
+
+ 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);
+ SoftwareDevice::setPanning(m_handle.get(), value);
+
+ Vector3 v, v2;
+ Quaternion q;
+
+ m_entry->m_orientation.read(frame, q.get());
+ m_3dhandle->setOrientation(q);
+ m_entry->m_location.read(frame, v.get());
+ m_3dhandle->setLocation(v);
+ m_entry->m_location.read(frame + 1, v2.get());
+ v2 -= v;
+ m_3dhandle->setVelocity(v2 * fps);
+
+ if(m_entry->m_muted)
+ m_handle->setVolume(0);
+}
+
+bool SequenceHandle::seek(float position)
+{
+ if(!m_valid)
+ // sound not valid, aborting
+ return false;
+
+ if(!updatePosition(position))
+ // no handle, aborting
+ return false;
+
+ std::lock_guard<ILockable> 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;
+}
+
+AUD_NAMESPACE_END