Add Chromium-only Blender WebEngine parity work
This commit is contained in:
266
blender-5.2.0/extern/audaspace/src/sequence/AnimateableProperty.cpp
vendored
Normal file
266
blender-5.2.0/extern/audaspace/src/sequence/AnimateableProperty.cpp
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/AnimateableProperty.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <mutex>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
AnimateableProperty::AnimateableProperty(int count) :
|
||||
Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
|
||||
{
|
||||
std::memset(Buffer::getBuffer(), 0, count * sizeof(float));
|
||||
}
|
||||
|
||||
AnimateableProperty::AnimateableProperty(int count, float value) :
|
||||
Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
|
||||
{
|
||||
sample_t* buf = Buffer::getBuffer();
|
||||
|
||||
for(int i = 0; i < count; i++)
|
||||
buf[i] = value;
|
||||
}
|
||||
|
||||
void AnimateableProperty::updateUnknownCache(int start, int end)
|
||||
{
|
||||
float* buf = Buffer::getBuffer();
|
||||
|
||||
// we could do a better interpolation than zero order, but that doesn't work with Blender's animation system
|
||||
// as frames are only written when changing, so to support jumps, we need zero order interpolation here.
|
||||
for(int i = start; i <= end; i++)
|
||||
std::memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
|
||||
}
|
||||
|
||||
AnimateableProperty::~AnimateableProperty()
|
||||
{
|
||||
}
|
||||
|
||||
int AnimateableProperty::getCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
void AnimateableProperty::write(const float* data)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_isAnimated = false;
|
||||
m_unknown.clear();
|
||||
std::memcpy(Buffer::getBuffer(), data, m_count * sizeof(float));
|
||||
}
|
||||
|
||||
void AnimateableProperty::writeConstantRange(const float* data, int position_start, int position_end)
|
||||
{
|
||||
int pos = getSize() / (sizeof(float) * m_count);
|
||||
|
||||
assureSize(position_end * m_count * sizeof(float), true);
|
||||
float* buffer = Buffer::getBuffer();
|
||||
|
||||
// if we were not animated yet, use the new constant value as the
|
||||
// first/default value to fill in the unknown parts
|
||||
if (!m_isAnimated)
|
||||
{
|
||||
std::memcpy(buffer, data, m_count * sizeof(float));
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
for(int i = position_start; i < position_end; i++)
|
||||
{
|
||||
std::memcpy(buffer + i * m_count, data, m_count * sizeof(float));
|
||||
}
|
||||
|
||||
m_isAnimated = true;
|
||||
|
||||
updateUnknownAfterWrite(pos, position_start, position_end - position_start);
|
||||
}
|
||||
|
||||
void AnimateableProperty::write(const float* data, int position, int count)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
int pos = getSize() / (sizeof(float) * m_count);
|
||||
|
||||
if(!m_isAnimated)
|
||||
pos = 0;
|
||||
|
||||
m_isAnimated = true;
|
||||
|
||||
assureSize((count + position) * m_count * sizeof(float), true);
|
||||
|
||||
float* buf = Buffer::getBuffer();
|
||||
|
||||
std::memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
|
||||
|
||||
updateUnknownAfterWrite(pos, position, count);
|
||||
}
|
||||
|
||||
void AnimateableProperty::updateUnknownAfterWrite(int pos, int position, int count)
|
||||
{
|
||||
// have to fill up space between?
|
||||
if(pos < position)
|
||||
{
|
||||
m_unknown.push_back(Unknown(pos, position - 1));
|
||||
|
||||
// if the buffer was not animated before, we copy the previous static value
|
||||
if(pos == 0)
|
||||
pos = 1;
|
||||
|
||||
updateUnknownCache(pos, position - 1);
|
||||
}
|
||||
// otherwise it's not at the end, let's check if some unknown part got filled
|
||||
else
|
||||
{
|
||||
bool erased = false;
|
||||
|
||||
for(auto it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++)
|
||||
{
|
||||
erased = false;
|
||||
|
||||
// unknown area before position
|
||||
if(it->end < position)
|
||||
continue;
|
||||
|
||||
// we're after the new area, let's stop
|
||||
if(it->start >= position + count)
|
||||
break;
|
||||
|
||||
// we have an intersection, now 4 cases:
|
||||
// the start is included
|
||||
if(position <= it->start)
|
||||
{
|
||||
// the end is included
|
||||
if(position + count > it->end)
|
||||
{
|
||||
// simply delete
|
||||
it = m_unknown.erase(it);
|
||||
erased = true;
|
||||
}
|
||||
// the end is excluded, a second part remains
|
||||
else
|
||||
{
|
||||
// update second part
|
||||
it->start = position + count;
|
||||
updateUnknownCache(it->start, it->end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// start is excluded, a first part remains
|
||||
else
|
||||
{
|
||||
// the end is included
|
||||
if(position + count > it->end)
|
||||
{
|
||||
// update first part
|
||||
it->end = position - 1;
|
||||
}
|
||||
// the end is excluded, a second part remains
|
||||
else
|
||||
{
|
||||
// add another item and update both parts
|
||||
m_unknown.insert(it, Unknown(it->start, position - 1));
|
||||
it->start = position + count;
|
||||
updateUnknownCache(it->start, it->end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateableProperty::read(float position, float* out)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(!m_isAnimated)
|
||||
{
|
||||
std::memcpy(out, Buffer::getBuffer(), m_count * sizeof(float));
|
||||
return;
|
||||
}
|
||||
|
||||
int last = getSize() / (sizeof(float) * m_count) - 1;
|
||||
float t = position - std::floor(position);
|
||||
|
||||
if(position >= last)
|
||||
{
|
||||
position = last;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
if(position < 0)
|
||||
{
|
||||
position = 0;
|
||||
t = 0;
|
||||
}
|
||||
|
||||
if(t == 0)
|
||||
{
|
||||
std::memcpy(out, Buffer::getBuffer() + int(std::floor(position)) * m_count, m_count * sizeof(float));
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = int(std::floor(position)) * m_count;
|
||||
float t2 = t * t;
|
||||
float t3 = t2 * t;
|
||||
float m0, m1;
|
||||
float* p0;
|
||||
float* p1 = Buffer::getBuffer() + pos;
|
||||
float* p2;
|
||||
float* p3;
|
||||
last *= m_count;
|
||||
|
||||
if(pos == 0)
|
||||
p0 = p1;
|
||||
else
|
||||
p0 = p1 - m_count;
|
||||
|
||||
p2 = p1 + m_count;
|
||||
if(pos + m_count == last)
|
||||
p3 = p2;
|
||||
else
|
||||
p3 = p2 + m_count;
|
||||
|
||||
for(int i = 0; i < m_count; i++)
|
||||
{
|
||||
m0 = (p2[i] - p0[i]) / 2.0f;
|
||||
m1 = (p3[i] - p1[i]) / 2.0f;
|
||||
|
||||
out[i] = (2 * t3 - 3 * t2 + 1) * p1[i] + (-2 * t3 + 3 * t2) * p2[i] + (t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float AnimateableProperty::readSingle(float position)
|
||||
{
|
||||
assert(m_count == 1);
|
||||
float value;
|
||||
read(position, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool AnimateableProperty::isAnimated() const
|
||||
{
|
||||
return m_isAnimated;
|
||||
}
|
||||
|
||||
const Buffer& AnimateableProperty::getBuffer()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
35
blender-5.2.0/extern/audaspace/src/sequence/Double.cpp
vendored
Normal file
35
blender-5.2.0/extern/audaspace/src/sequence/Double.cpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/Double.h"
|
||||
#include "sequence/DoubleReader.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
Double::Double(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
|
||||
m_sound1(sound1), m_sound2(sound2)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> Double::createReader()
|
||||
{
|
||||
std::shared_ptr<IReader> reader1 = m_sound1->createReader();
|
||||
std::shared_ptr<IReader> reader2 = m_sound2->createReader();
|
||||
|
||||
return std::shared_ptr<IReader>(new DoubleReader(reader1, reader2));
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
102
blender-5.2.0/extern/audaspace/src/sequence/DoubleReader.cpp
vendored
Normal file
102
blender-5.2.0/extern/audaspace/src/sequence/DoubleReader.cpp
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/DoubleReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
DoubleReader::DoubleReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
|
||||
m_reader1(reader1), m_reader2(reader2), m_finished1(false)
|
||||
{
|
||||
Specs s1, s2;
|
||||
s1 = reader1->getSpecs();
|
||||
s2 = reader2->getSpecs();
|
||||
}
|
||||
|
||||
DoubleReader::~DoubleReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool DoubleReader::isSeekable() const
|
||||
{
|
||||
return m_reader1->isSeekable() && m_reader2->isSeekable();
|
||||
}
|
||||
|
||||
void DoubleReader::seek(int position)
|
||||
{
|
||||
m_reader1->seek(position);
|
||||
|
||||
int pos1 = m_reader1->getPosition();
|
||||
|
||||
if((m_finished1 = (pos1 < position)))
|
||||
m_reader2->seek(position - pos1);
|
||||
else
|
||||
m_reader2->seek(0);
|
||||
}
|
||||
|
||||
int DoubleReader::getLength() const
|
||||
{
|
||||
int len1 = m_reader1->getLength();
|
||||
int len2 = m_reader2->getLength();
|
||||
if(len1 < 0 || len2 < 0)
|
||||
return -1;
|
||||
return len1 + len2;
|
||||
}
|
||||
|
||||
int DoubleReader::getPosition() const
|
||||
{
|
||||
return m_reader1->getPosition() + m_reader2->getPosition();
|
||||
}
|
||||
|
||||
Specs DoubleReader::getSpecs() const
|
||||
{
|
||||
return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
|
||||
}
|
||||
|
||||
void DoubleReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
{
|
||||
eos = false;
|
||||
|
||||
if(!m_finished1)
|
||||
{
|
||||
int len = length;
|
||||
|
||||
m_reader1->read(len, m_finished1, buffer);
|
||||
|
||||
if(len < length)
|
||||
{
|
||||
Specs specs1, specs2;
|
||||
specs1 = m_reader1->getSpecs();
|
||||
specs2 = m_reader2->getSpecs();
|
||||
if(AUD_COMPARE_SPECS(specs1, specs2))
|
||||
{
|
||||
int len2 = length - len;
|
||||
m_reader2->read(len2, eos, buffer + specs1.channels * len);
|
||||
length = len + len2;
|
||||
}
|
||||
else
|
||||
length = len;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_reader2->read(length, eos, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
36
blender-5.2.0/extern/audaspace/src/sequence/PingPong.cpp
vendored
Normal file
36
blender-5.2.0/extern/audaspace/src/sequence/PingPong.cpp
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/PingPong.h"
|
||||
#include "sequence/DoubleReader.h"
|
||||
#include "fx/ReverseReader.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
PingPong::PingPong(std::shared_ptr<ISound> sound) :
|
||||
Effect(sound)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> PingPong::createReader()
|
||||
{
|
||||
std::shared_ptr<IReader> reader = getReader();
|
||||
std::shared_ptr<IReader> reader2 = std::shared_ptr<IReader>(new ReverseReader(getReader()));
|
||||
|
||||
return std::shared_ptr<IReader>(new DoubleReader(reader, reader2));
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
113
blender-5.2.0/extern/audaspace/src/sequence/Sequence.cpp
vendored
Normal file
113
blender-5.2.0/extern/audaspace/src/sequence/Sequence.cpp
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/Sequence.h"
|
||||
#include "sequence/SequenceReader.h"
|
||||
#include "sequence/SequenceData.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
Sequence::Sequence(Specs specs, float fps, bool muted)
|
||||
{
|
||||
m_sequence = std::shared_ptr<SequenceData>(new SequenceData(specs, fps, muted));
|
||||
}
|
||||
|
||||
Specs Sequence::getSpecs()
|
||||
{
|
||||
return m_sequence->getSpecs();
|
||||
}
|
||||
|
||||
void Sequence::setSpecs(Specs specs)
|
||||
{
|
||||
m_sequence->setSpecs(specs);
|
||||
}
|
||||
|
||||
float Sequence::getFPS() const
|
||||
{
|
||||
return m_sequence->getFPS();
|
||||
}
|
||||
|
||||
void Sequence::setFPS(float fps)
|
||||
{
|
||||
m_sequence->setFPS(fps);
|
||||
}
|
||||
|
||||
void Sequence::mute(bool muted)
|
||||
{
|
||||
m_sequence->mute(muted);
|
||||
}
|
||||
|
||||
bool Sequence::isMuted() const
|
||||
{
|
||||
return m_sequence->isMuted();
|
||||
}
|
||||
|
||||
float Sequence::getSpeedOfSound() const
|
||||
{
|
||||
return m_sequence->getSpeedOfSound();
|
||||
}
|
||||
|
||||
void Sequence::setSpeedOfSound(float speed)
|
||||
{
|
||||
m_sequence->setSpeedOfSound(speed);
|
||||
}
|
||||
|
||||
float Sequence::getDopplerFactor() const
|
||||
{
|
||||
return m_sequence->getDopplerFactor();
|
||||
}
|
||||
|
||||
void Sequence::setDopplerFactor(float factor)
|
||||
{
|
||||
m_sequence->setDopplerFactor(factor);
|
||||
}
|
||||
|
||||
DistanceModel Sequence::getDistanceModel() const
|
||||
{
|
||||
return m_sequence->getDistanceModel();
|
||||
}
|
||||
|
||||
void Sequence::setDistanceModel(DistanceModel model)
|
||||
{
|
||||
m_sequence->setDistanceModel(model);
|
||||
}
|
||||
|
||||
AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type)
|
||||
{
|
||||
return m_sequence->getAnimProperty(type);
|
||||
}
|
||||
|
||||
std::shared_ptr<SequenceEntry> Sequence::add(std::shared_ptr<ISound> sound, double begin, double end, double skip)
|
||||
{
|
||||
return m_sequence->add(sound, m_sequence, begin, end, skip);
|
||||
}
|
||||
|
||||
void Sequence::remove(std::shared_ptr<SequenceEntry> entry)
|
||||
{
|
||||
m_sequence->remove(entry);
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> Sequence::createQualityReader(ResampleQuality quality)
|
||||
{
|
||||
return std::shared_ptr<IReader>(new SequenceReader(m_sequence, quality));
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> Sequence::createReader()
|
||||
{
|
||||
return std::shared_ptr<IReader>(new SequenceReader(m_sequence));
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
172
blender-5.2.0/extern/audaspace/src/sequence/SequenceData.cpp
vendored
Normal file
172
blender-5.2.0/extern/audaspace/src/sequence/SequenceData.cpp
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/SequenceData.h"
|
||||
#include "sequence/SequenceReader.h"
|
||||
#include "sequence/SequenceEntry.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
SequenceData::SequenceData(Specs specs, float fps, bool muted) :
|
||||
m_specs(specs),
|
||||
m_status(0),
|
||||
m_entry_status(0),
|
||||
m_id(0),
|
||||
m_muted(muted),
|
||||
m_fps(fps),
|
||||
m_speed_of_sound(343.3f),
|
||||
m_doppler_factor(1),
|
||||
m_distance_model(DISTANCE_MODEL_INVERSE_CLAMPED),
|
||||
m_volume(1, 1.0f),
|
||||
m_location(3),
|
||||
m_orientation(4)
|
||||
{
|
||||
Quaternion q;
|
||||
m_orientation.write(q.get());
|
||||
float f = 1;
|
||||
m_volume.write(&f);
|
||||
}
|
||||
|
||||
SequenceData::~SequenceData()
|
||||
{
|
||||
}
|
||||
|
||||
void SequenceData::lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void SequenceData::unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
Specs SequenceData::getSpecs()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
return m_specs;
|
||||
}
|
||||
|
||||
void SequenceData::setSpecs(Specs specs)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_specs = specs;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceData::getFPS() const
|
||||
{
|
||||
return m_fps;
|
||||
}
|
||||
|
||||
void SequenceData::setFPS(float fps)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_fps = fps;
|
||||
}
|
||||
|
||||
void SequenceData::mute(bool muted)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_muted = muted;
|
||||
}
|
||||
|
||||
bool SequenceData::isMuted() const
|
||||
{
|
||||
return m_muted;
|
||||
}
|
||||
|
||||
float SequenceData::getSpeedOfSound() const
|
||||
{
|
||||
return m_speed_of_sound;
|
||||
}
|
||||
|
||||
void SequenceData::setSpeedOfSound(float speed)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_speed_of_sound = speed;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceData::getDopplerFactor() const
|
||||
{
|
||||
return m_doppler_factor;
|
||||
}
|
||||
|
||||
void SequenceData::setDopplerFactor(float factor)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_doppler_factor = factor;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
DistanceModel SequenceData::getDistanceModel() const
|
||||
{
|
||||
return m_distance_model;
|
||||
}
|
||||
|
||||
void SequenceData::setDistanceModel(DistanceModel model)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_distance_model = model;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case AP_VOLUME:
|
||||
return &m_volume;
|
||||
case AP_LOCATION:
|
||||
return &m_location;
|
||||
case AP_ORIENTATION:
|
||||
return &m_orientation;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SequenceEntry> SequenceData::add(std::shared_ptr<ISound> sound, std::shared_ptr<SequenceData> sequence_data, double begin, double end, double skip)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
std::shared_ptr<SequenceEntry> entry = std::shared_ptr<SequenceEntry>(new SequenceEntry(sound, begin, end, skip, sequence_data, m_id++));
|
||||
|
||||
m_entries.push_back(entry);
|
||||
m_entry_status++;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void SequenceData::remove(std::shared_ptr<SequenceEntry> entry)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_entries.remove(entry);
|
||||
m_entry_status++;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
257
blender-5.2.0/extern/audaspace/src/sequence/SequenceEntry.cpp
vendored
Normal file
257
blender-5.2.0/extern/audaspace/src/sequence/SequenceEntry.cpp
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/SequenceEntry.h"
|
||||
#include "sequence/SequenceReader.h"
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, double begin, double end, double skip, std::shared_ptr<SequenceData> sequence_data, int id) :
|
||||
m_status(0),
|
||||
m_pos_status(1),
|
||||
m_sound_status(0),
|
||||
m_id(id),
|
||||
m_sound(sound),
|
||||
m_begin(begin),
|
||||
m_end(end),
|
||||
m_skip(skip),
|
||||
m_sequence_data(sequence_data),
|
||||
m_muted(false),
|
||||
m_relative(true),
|
||||
m_volume_max(1.0f),
|
||||
m_volume_min(0),
|
||||
m_distance_max(std::numeric_limits<float>::max()),
|
||||
m_distance_reference(1.0f),
|
||||
m_attenuation(1.0f),
|
||||
m_cone_angle_outer(360),
|
||||
m_cone_angle_inner(360),
|
||||
m_cone_volume_outer(0),
|
||||
m_volume(1, 1.0f),
|
||||
m_pitch(1, 1.0f),
|
||||
m_location(3),
|
||||
m_orientation(4)
|
||||
{
|
||||
Quaternion q;
|
||||
m_orientation.write(q.get());
|
||||
float f = 1;
|
||||
m_volume.write(&f);
|
||||
m_pitch.write(&f);
|
||||
}
|
||||
|
||||
SequenceEntry::~SequenceEntry()
|
||||
{
|
||||
}
|
||||
|
||||
void SequenceEntry::lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void SequenceEntry::unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
std::shared_ptr<ISound> SequenceEntry::getSound()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
return m_sound;
|
||||
}
|
||||
|
||||
void SequenceEntry::setSound(std::shared_ptr<ISound> sound)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(m_sound.get() != sound.get())
|
||||
{
|
||||
m_sound = sound;
|
||||
m_sound_status++;
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceEntry::move(double begin, double end, double skip)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(m_begin != begin || m_skip != skip || m_end != end)
|
||||
{
|
||||
m_begin = begin;
|
||||
m_skip = skip;
|
||||
m_end = end;
|
||||
m_pos_status++;
|
||||
}
|
||||
}
|
||||
|
||||
bool SequenceEntry::isMuted()
|
||||
{
|
||||
return m_muted;
|
||||
}
|
||||
|
||||
void SequenceEntry::mute(bool mute)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_muted = mute;
|
||||
}
|
||||
|
||||
int SequenceEntry::getID() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
AnimateableProperty* SequenceEntry::getAnimProperty(AnimateablePropertyType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case AP_VOLUME:
|
||||
return &m_volume;
|
||||
case AP_PITCH:
|
||||
return &m_pitch;
|
||||
case AP_PANNING:
|
||||
return &m_panning;
|
||||
case AP_LOCATION:
|
||||
return &m_location;
|
||||
case AP_ORIENTATION:
|
||||
return &m_orientation;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SequenceEntry::isRelative()
|
||||
{
|
||||
return m_relative;
|
||||
}
|
||||
|
||||
void SequenceEntry::setRelative(bool relative)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(m_relative != relative)
|
||||
{
|
||||
m_relative = relative;
|
||||
m_status++;
|
||||
}
|
||||
}
|
||||
|
||||
float SequenceEntry::getVolumeMaximum()
|
||||
{
|
||||
return m_volume_max;
|
||||
}
|
||||
|
||||
void SequenceEntry::setVolumeMaximum(float volume)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_volume_max = volume;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getVolumeMinimum()
|
||||
{
|
||||
return m_volume_min;
|
||||
}
|
||||
|
||||
void SequenceEntry::setVolumeMinimum(float volume)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_volume_min = volume;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getDistanceMaximum()
|
||||
{
|
||||
return m_distance_max;
|
||||
}
|
||||
|
||||
void SequenceEntry::setDistanceMaximum(float distance)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_distance_max = distance;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getDistanceReference()
|
||||
{
|
||||
return m_distance_reference;
|
||||
}
|
||||
|
||||
void SequenceEntry::setDistanceReference(float distance)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_distance_reference = distance;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getAttenuation()
|
||||
{
|
||||
return m_attenuation;
|
||||
}
|
||||
|
||||
void SequenceEntry::setAttenuation(float factor)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_attenuation = factor;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getConeAngleOuter()
|
||||
{
|
||||
return m_cone_angle_outer;
|
||||
}
|
||||
|
||||
void SequenceEntry::setConeAngleOuter(float angle)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_cone_angle_outer = angle;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getConeAngleInner()
|
||||
{
|
||||
return m_cone_angle_inner;
|
||||
}
|
||||
|
||||
void SequenceEntry::setConeAngleInner(float angle)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_cone_angle_inner = angle;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
float SequenceEntry::getConeVolumeOuter()
|
||||
{
|
||||
return m_cone_volume_outer;
|
||||
}
|
||||
|
||||
void SequenceEntry::setConeVolumeOuter(float volume)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
m_cone_volume_outer = volume;
|
||||
m_status++;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
282
blender-5.2.0/extern/audaspace/src/sequence/SequenceHandle.cpp
vendored
Normal file
282
blender-5.2.0/extern/audaspace/src/sequence/SequenceHandle.cpp
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
#define POSITION_EPSILON (1.0 / static_cast<double>(RATE_48000))
|
||||
|
||||
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(double 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 - POSITION_EPSILON >= 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 + POSITION_EPSILON >= 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 + POSITION_EPSILON >= m_entry->m_begin && position - POSITION_EPSILON <= 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(double 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(double 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);
|
||||
|
||||
double seek_frame = (position - m_entry->m_begin) * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
if(seek_frame < 0)
|
||||
seek_frame = 0;
|
||||
|
||||
seek_frame += m_entry->m_skip * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
AnimateableProperty* pitch_property = m_entry->getAnimProperty(AP_PITCH);
|
||||
|
||||
double target_frame = 0;
|
||||
|
||||
if(pitch_property != nullptr)
|
||||
{
|
||||
int frame_start = (m_entry->m_begin - m_entry->m_skip) * m_entry->m_sequence_data->getFPS();
|
||||
|
||||
for(int i = 0; seek_frame > 0; i++)
|
||||
{
|
||||
float pitch;
|
||||
pitch_property->read(frame_start + i, &pitch);
|
||||
const double factor = seek_frame > 1.0 ? 1.0 : seek_frame;
|
||||
target_frame += pitch * factor;
|
||||
seek_frame--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_frame = seek_frame;
|
||||
}
|
||||
|
||||
double seekpos = target_frame / m_entry->m_sequence_data->getFPS();
|
||||
|
||||
m_handle->setPitch(1.0f);
|
||||
m_handle->seek(seekpos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
117
blender-5.2.0/extern/audaspace/src/sequence/SequenceHandle.h
vendored
Normal file
117
blender-5.2.0/extern/audaspace/src/sequence/SequenceHandle.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Audaspace.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
class ReadDevice;
|
||||
class IHandle;
|
||||
class I3DHandle;
|
||||
class SequenceEntry;
|
||||
|
||||
/**
|
||||
* Represents a playing sequenced entry.
|
||||
*/
|
||||
class SequenceHandle
|
||||
{
|
||||
private:
|
||||
/// The entry this handle belongs to.
|
||||
std::shared_ptr<SequenceEntry> m_entry;
|
||||
|
||||
/// The handle in the read device.
|
||||
std::shared_ptr<IHandle> m_handle;
|
||||
|
||||
/// The 3D handle in the read device.
|
||||
std::shared_ptr<I3DHandle> m_3dhandle;
|
||||
|
||||
/// Whether the sound is playable.
|
||||
bool m_valid;
|
||||
|
||||
/// The last read status from the entry.
|
||||
int m_status;
|
||||
|
||||
/// The last position status from the entry.
|
||||
int m_pos_status;
|
||||
|
||||
/// The last sound status from the entry.
|
||||
int m_sound_status;
|
||||
|
||||
/// The read device this handle is played on.
|
||||
ReadDevice& m_device;
|
||||
|
||||
// delete copy constructor and operator=
|
||||
SequenceHandle(const SequenceHandle&) = delete;
|
||||
SequenceHandle& operator=(const SequenceHandle&) = delete;
|
||||
|
||||
/**
|
||||
* 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(double position);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new sequenced handle.
|
||||
* \param entry The entry this handle plays.
|
||||
* \param device The read device to play on.
|
||||
*/
|
||||
SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device);
|
||||
|
||||
/**
|
||||
* Destroys the handle.
|
||||
*/
|
||||
~SequenceHandle();
|
||||
|
||||
/**
|
||||
* Compares whether this handle is playing the same entry as supplied.
|
||||
* \param entry The entry to compare to.
|
||||
* \return Whether the entries ID is smaller, equal or bigger.
|
||||
*/
|
||||
int compare(std::shared_ptr<SequenceEntry> entry) const;
|
||||
|
||||
/**
|
||||
* Stops playing back the handle.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Updates the handle for playback.
|
||||
* \param position The current time during playback.
|
||||
* \param frame The current frame during playback.
|
||||
* \param fps The animation frames per second.
|
||||
*/
|
||||
void update(double position, float frame, float fps);
|
||||
|
||||
/**
|
||||
* Seeks the handle to a specific time position.
|
||||
* \param position The time to seek to.
|
||||
* \return Whether the handle is valid.
|
||||
*/
|
||||
bool seek(double position);
|
||||
};
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
197
blender-5.2.0/extern/audaspace/src/sequence/SequenceReader.cpp
vendored
Normal file
197
blender-5.2.0/extern/audaspace/src/sequence/SequenceReader.cpp
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/SequenceReader.h"
|
||||
#include "sequence/SequenceData.h"
|
||||
#include "Exception.h"
|
||||
#include "SequenceHandle.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <cmath>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
SequenceReader::SequenceReader(std::shared_ptr<SequenceData> sequence, ResampleQuality quality) :
|
||||
m_position(0), m_device(sequence->m_specs), m_sequence(sequence), m_status(0), m_entry_status(0)
|
||||
{
|
||||
m_device.setQuality(quality);
|
||||
}
|
||||
|
||||
SequenceReader::~SequenceReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool SequenceReader::isSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SequenceReader::seek(int position)
|
||||
{
|
||||
if(position < 0)
|
||||
return;
|
||||
|
||||
m_position = position;
|
||||
|
||||
for(auto& handle : m_handles)
|
||||
{
|
||||
handle->seek(position / (double)m_sequence->m_specs.rate);
|
||||
}
|
||||
}
|
||||
|
||||
int SequenceReader::getLength() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SequenceReader::getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
Specs SequenceReader::getSpecs() const
|
||||
{
|
||||
return m_sequence->m_specs;
|
||||
}
|
||||
|
||||
void SequenceReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
{
|
||||
std::lock_guard<ILockable> lock(*m_sequence);
|
||||
|
||||
if(m_sequence->m_status != m_status)
|
||||
{
|
||||
m_device.changeSpecs(m_sequence->m_specs);
|
||||
m_device.setSpeedOfSound(m_sequence->m_speed_of_sound);
|
||||
m_device.setDistanceModel(m_sequence->m_distance_model);
|
||||
m_device.setDopplerFactor(m_sequence->m_doppler_factor);
|
||||
|
||||
m_status = m_sequence->m_status;
|
||||
}
|
||||
|
||||
if(m_sequence->m_entry_status != m_entry_status)
|
||||
{
|
||||
std::list<std::shared_ptr<SequenceHandle> > handles;
|
||||
|
||||
auto hit = m_handles.begin();
|
||||
auto eit = m_sequence->m_entries.begin();
|
||||
|
||||
int result;
|
||||
std::shared_ptr<SequenceHandle> handle;
|
||||
|
||||
while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
|
||||
{
|
||||
handle = *hit;
|
||||
std::shared_ptr<SequenceEntry> entry = *eit;
|
||||
|
||||
result = handle->compare(entry);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(entry, m_device));
|
||||
handles.push_back(handle);
|
||||
}
|
||||
catch(Exception&)
|
||||
{
|
||||
}
|
||||
eit++;
|
||||
}
|
||||
else if(result == 0)
|
||||
{
|
||||
handles.push_back(handle);
|
||||
hit++;
|
||||
eit++;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->stop();
|
||||
hit++;
|
||||
}
|
||||
}
|
||||
|
||||
while(hit != m_handles.end())
|
||||
{
|
||||
(*hit)->stop();
|
||||
hit++;
|
||||
}
|
||||
|
||||
while(eit != m_sequence->m_entries.end())
|
||||
{
|
||||
try
|
||||
{
|
||||
handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(*eit, m_device));
|
||||
handles.push_back(handle);
|
||||
}
|
||||
catch(Exception&)
|
||||
{
|
||||
}
|
||||
eit++;
|
||||
}
|
||||
|
||||
m_handles = handles;
|
||||
|
||||
m_entry_status = m_sequence->m_entry_status;
|
||||
}
|
||||
|
||||
Specs specs = m_sequence->m_specs;
|
||||
int pos = 0;
|
||||
double time = double(m_position) / double(specs.rate);
|
||||
float volume, frame;
|
||||
int len, cfra;
|
||||
Vector3 v, v2;
|
||||
Quaternion q;
|
||||
|
||||
while(pos < length)
|
||||
{
|
||||
frame = time * m_sequence->m_fps;
|
||||
cfra = int(std::floor(frame));
|
||||
|
||||
len = int(std::ceil((cfra + 1) / m_sequence->m_fps * specs.rate)) - m_position - pos;
|
||||
len = std::min(length - pos, len);
|
||||
len = std::max(len, 1);
|
||||
|
||||
for(auto& handle : m_handles)
|
||||
{
|
||||
handle->update(time, frame, m_sequence->m_fps);
|
||||
}
|
||||
|
||||
m_sequence->m_volume.read(frame, &volume);
|
||||
if(m_sequence->m_muted)
|
||||
volume = 0.0f;
|
||||
m_device.setVolume(volume);
|
||||
|
||||
m_sequence->m_orientation.read(frame, q.get());
|
||||
m_device.setListenerOrientation(q);
|
||||
m_sequence->m_location.read(frame, v.get());
|
||||
m_device.setListenerLocation(v);
|
||||
m_sequence->m_location.read(frame + 1, v2.get());
|
||||
v2 -= v;
|
||||
m_device.setListenerVelocity(v2 * m_sequence->m_fps);
|
||||
|
||||
m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
|
||||
|
||||
pos += len;
|
||||
time += double(len) / double(specs.rate);
|
||||
}
|
||||
|
||||
m_position += length;
|
||||
|
||||
eos = false;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
35
blender-5.2.0/extern/audaspace/src/sequence/Superpose.cpp
vendored
Normal file
35
blender-5.2.0/extern/audaspace/src/sequence/Superpose.cpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/Superpose.h"
|
||||
#include "sequence/SuperposeReader.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
Superpose::Superpose(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
|
||||
m_sound1(sound1), m_sound2(sound2)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> Superpose::createReader()
|
||||
{
|
||||
std::shared_ptr<IReader> reader1 = m_sound1->createReader();
|
||||
std::shared_ptr<IReader> reader2 = m_sound2->createReader();
|
||||
|
||||
return std::shared_ptr<IReader>(new SuperposeReader(reader1, reader2));
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
95
blender-5.2.0/extern/audaspace/src/sequence/SuperposeReader.cpp
vendored
Normal file
95
blender-5.2.0/extern/audaspace/src/sequence/SuperposeReader.cpp
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* 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 "sequence/SuperposeReader.h"
|
||||
#include "Exception.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
SuperposeReader::SuperposeReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
|
||||
m_reader1(reader1), m_reader2(reader2)
|
||||
{
|
||||
}
|
||||
|
||||
SuperposeReader::~SuperposeReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool SuperposeReader::isSeekable() const
|
||||
{
|
||||
return m_reader1->isSeekable() && m_reader2->isSeekable();
|
||||
}
|
||||
|
||||
void SuperposeReader::seek(int position)
|
||||
{
|
||||
m_reader1->seek(position);
|
||||
m_reader2->seek(position);
|
||||
}
|
||||
|
||||
int SuperposeReader::getLength() const
|
||||
{
|
||||
int len1 = m_reader1->getLength();
|
||||
int len2 = m_reader2->getLength();
|
||||
if((len1 < 0) || (len2 < 0))
|
||||
return -1;
|
||||
return std::max(len1, len2);
|
||||
}
|
||||
|
||||
int SuperposeReader::getPosition() const
|
||||
{
|
||||
int pos1 = m_reader1->getPosition();
|
||||
int pos2 = m_reader2->getPosition();
|
||||
return std::max(pos1, pos2);
|
||||
}
|
||||
|
||||
Specs SuperposeReader::getSpecs() const
|
||||
{
|
||||
return m_reader1->getSpecs();
|
||||
}
|
||||
|
||||
void SuperposeReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
{
|
||||
Specs specs = m_reader1->getSpecs();
|
||||
Specs s2 = m_reader2->getSpecs();
|
||||
if(!AUD_COMPARE_SPECS(specs, s2))
|
||||
AUD_THROW(StateException, "Two readers with different specifiactions cannot be superposed.");
|
||||
|
||||
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
|
||||
m_buffer.assureSize(length * samplesize);
|
||||
|
||||
int len1 = length;
|
||||
m_reader1->read(len1, eos, buffer);
|
||||
|
||||
if(len1 < length)
|
||||
std::memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
|
||||
|
||||
int len2 = length;
|
||||
bool eos2;
|
||||
sample_t* buf = m_buffer.getBuffer();
|
||||
m_reader2->read(len2, eos2, buf);
|
||||
|
||||
for(int i = 0; i < len2 * specs.channels; i++)
|
||||
buffer[i] += buf[i];
|
||||
|
||||
length = std::max(len1, len2);
|
||||
eos &= eos2;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
||||
Reference in New Issue
Block a user