mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-28 21:31:12 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into toulouse
This commit is contained in:
commit
c10607a06d
4 changed files with 51 additions and 40 deletions
|
@ -943,9 +943,6 @@ bool processRandomSwitchStateMachineNode(AnimNode::Pointer node, const QJsonObje
|
||||||
}
|
}
|
||||||
|
|
||||||
auto randomStatePtr = std::make_shared<AnimRandomSwitch::RandomSwitchState>(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum, priority, resume);
|
auto randomStatePtr = std::make_shared<AnimRandomSwitch::RandomSwitchState>(id, iter->second, interpTarget, interpDuration, interpTypeEnum, easingTypeEnum, priority, resume);
|
||||||
if (priority > 0.0f) {
|
|
||||||
smNode->addToPrioritySum(priority);
|
|
||||||
}
|
|
||||||
assert(randomStatePtr);
|
assert(randomStatePtr);
|
||||||
|
|
||||||
if (!interpTargetVar.isEmpty()) {
|
if (!interpTargetVar.isEmpty()) {
|
||||||
|
|
|
@ -27,22 +27,35 @@ const AnimPoseVec& AnimRandomSwitch::evaluate(const AnimVariantMap& animVars, co
|
||||||
AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState;
|
AnimRandomSwitch::RandomSwitchState::Pointer desiredState = _currentState;
|
||||||
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) {
|
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1 || animVars.lookup(_triggerRandomSwitchVar, false)) {
|
||||||
|
|
||||||
// get a random number and decide which motion to choose.
|
// filter states different to the last random state and with priorities.
|
||||||
bool currentStateHasPriority = false;
|
bool currentStateHasPriority = false;
|
||||||
float dice = randFloatInRange(0.0f, 1.0f);
|
std::vector<RandomSwitchState::Pointer> randomStatesToConsider;
|
||||||
float lowerBound = 0.0f;
|
randomStatesToConsider.reserve(_randomStates.size());
|
||||||
for (const RandomSwitchState::Pointer& randState : _randomStates) {
|
float totalPriorities = 0.0f;
|
||||||
|
for (size_t i = 0; i < _randomStates.size(); i++) {
|
||||||
|
auto randState = _randomStates[i];
|
||||||
if (randState->getPriority() > 0.0f) {
|
if (randState->getPriority() > 0.0f) {
|
||||||
float upperBound = lowerBound + (randState->getPriority() / _totalPriorities);
|
bool isRepeatingClip = _children[randState->getChildIndex()]->getID() == _lastPlayedState;
|
||||||
if ((dice > lowerBound) && (dice < upperBound)) {
|
if (!isRepeatingClip) {
|
||||||
desiredState = randState;
|
randomStatesToConsider.push_back(randState);
|
||||||
|
totalPriorities += randState->getPriority();
|
||||||
}
|
}
|
||||||
lowerBound = upperBound;
|
|
||||||
|
|
||||||
// this indicates if the curent state is one that can be selected randomly, or is one that was transitioned to by the random duration timer.
|
// this indicates if the curent state is one that can be selected randomly, or is one that was transitioned to by the random duration timer.
|
||||||
currentStateHasPriority = currentStateHasPriority || (_currentState == randState);
|
currentStateHasPriority = currentStateHasPriority || (_currentState == randState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// get a random number and decide which motion to choose.
|
||||||
|
float dice = randFloatInRange(0.0f, 1.0f);
|
||||||
|
float lowerBound = 0.0f;
|
||||||
|
for (size_t i = 0; i < randomStatesToConsider.size(); i++) {
|
||||||
|
auto randState = randomStatesToConsider[i];
|
||||||
|
float upperBound = lowerBound + (randState->getPriority() / totalPriorities);
|
||||||
|
if ((dice > lowerBound) && (dice < upperBound)) {
|
||||||
|
desiredState = randState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lowerBound = upperBound;
|
||||||
|
}
|
||||||
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) {
|
if (abs(_randomSwitchEvaluationCount - context.getEvaluationCount()) > 1) {
|
||||||
_duringInterp = false;
|
_duringInterp = false;
|
||||||
switchRandomState(animVars, context, desiredState, _duringInterp);
|
switchRandomState(animVars, context, desiredState, _duringInterp);
|
||||||
|
@ -155,8 +168,8 @@ void AnimRandomSwitch::addState(RandomSwitchState::Pointer randomState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const AnimContext& context, RandomSwitchState::Pointer desiredState, bool shouldInterp) {
|
void AnimRandomSwitch::switchRandomState(const AnimVariantMap& animVars, const AnimContext& context, RandomSwitchState::Pointer desiredState, bool shouldInterp) {
|
||||||
|
|
||||||
auto nextStateNode = _children[desiredState->getChildIndex()];
|
auto nextStateNode = _children[desiredState->getChildIndex()];
|
||||||
|
_lastPlayedState = nextStateNode->getID();
|
||||||
if (shouldInterp) {
|
if (shouldInterp) {
|
||||||
|
|
||||||
const float FRAMES_PER_SECOND = 30.0f;
|
const float FRAMES_PER_SECOND = 30.0f;
|
||||||
|
|
|
@ -143,7 +143,6 @@ protected:
|
||||||
void setTransitionVar(const QString& transitionVar) { _transitionVar = transitionVar; }
|
void setTransitionVar(const QString& transitionVar) { _transitionVar = transitionVar; }
|
||||||
void setTriggerTimeMin(float triggerTimeMin) { _triggerTimeMin = triggerTimeMin; }
|
void setTriggerTimeMin(float triggerTimeMin) { _triggerTimeMin = triggerTimeMin; }
|
||||||
void setTriggerTimeMax(float triggerTimeMax) { _triggerTimeMax = triggerTimeMax; }
|
void setTriggerTimeMax(float triggerTimeMax) { _triggerTimeMax = triggerTimeMax; }
|
||||||
void addToPrioritySum(float priority) { _totalPriorities += priority; }
|
|
||||||
|
|
||||||
void addState(RandomSwitchState::Pointer randomState);
|
void addState(RandomSwitchState::Pointer randomState);
|
||||||
|
|
||||||
|
@ -164,7 +163,6 @@ protected:
|
||||||
float _alpha = 0.0f;
|
float _alpha = 0.0f;
|
||||||
AnimPoseVec _prevPoses;
|
AnimPoseVec _prevPoses;
|
||||||
AnimPoseVec _nextPoses;
|
AnimPoseVec _nextPoses;
|
||||||
float _totalPriorities { 0.0f };
|
|
||||||
|
|
||||||
RandomSwitchState::Pointer _currentState;
|
RandomSwitchState::Pointer _currentState;
|
||||||
RandomSwitchState::Pointer _previousState;
|
RandomSwitchState::Pointer _previousState;
|
||||||
|
@ -179,6 +177,7 @@ protected:
|
||||||
float _randomSwitchTimeMin { 10.0f };
|
float _randomSwitchTimeMin { 10.0f };
|
||||||
float _randomSwitchTimeMax { 20.0f };
|
float _randomSwitchTimeMax { 20.0f };
|
||||||
float _randomSwitchTime { 0.0f };
|
float _randomSwitchTime { 0.0f };
|
||||||
|
QString _lastPlayedState;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// no copies
|
// no copies
|
||||||
|
|
|
@ -170,27 +170,21 @@ static void channelDownmix(int16_t* source, int16_t* dest, int numSamples) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float computeLoudness(int16_t* samples, int numSamples, int numChannels, bool& isClipping) {
|
static bool detectClipping(int16_t* samples, int numSamples, int numChannels) {
|
||||||
|
|
||||||
const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS
|
const int32_t CLIPPING_THRESHOLD = 32392; // -0.1 dBFS
|
||||||
const int32_t CLIPPING_DETECTION = 3; // consecutive samples over threshold
|
const int CLIPPING_DETECTION = 3; // consecutive samples over threshold
|
||||||
|
|
||||||
float scale = numSamples ? 1.0f / numSamples : 0.0f;
|
bool isClipping = false;
|
||||||
|
|
||||||
int32_t loudness = 0;
|
|
||||||
isClipping = false;
|
|
||||||
|
|
||||||
if (numChannels == 2) {
|
if (numChannels == 2) {
|
||||||
int32_t oversLeft = 0;
|
int oversLeft = 0;
|
||||||
int32_t oversRight = 0;
|
int oversRight = 0;
|
||||||
|
|
||||||
for (int i = 0; i < numSamples/2; i++) {
|
for (int i = 0; i < numSamples/2; i++) {
|
||||||
int32_t left = std::abs((int32_t)samples[2*i+0]);
|
int32_t left = std::abs((int32_t)samples[2*i+0]);
|
||||||
int32_t right = std::abs((int32_t)samples[2*i+1]);
|
int32_t right = std::abs((int32_t)samples[2*i+1]);
|
||||||
|
|
||||||
loudness += left;
|
|
||||||
loudness += right;
|
|
||||||
|
|
||||||
if (left > CLIPPING_THRESHOLD) {
|
if (left > CLIPPING_THRESHOLD) {
|
||||||
isClipping |= (++oversLeft >= CLIPPING_DETECTION);
|
isClipping |= (++oversLeft >= CLIPPING_DETECTION);
|
||||||
} else {
|
} else {
|
||||||
|
@ -203,13 +197,11 @@ static float computeLoudness(int16_t* samples, int numSamples, int numChannels,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32_t overs = 0;
|
int overs = 0;
|
||||||
|
|
||||||
for (int i = 0; i < numSamples; i++) {
|
for (int i = 0; i < numSamples; i++) {
|
||||||
int32_t sample = std::abs((int32_t)samples[i]);
|
int32_t sample = std::abs((int32_t)samples[i]);
|
||||||
|
|
||||||
loudness += sample;
|
|
||||||
|
|
||||||
if (sample > CLIPPING_THRESHOLD) {
|
if (sample > CLIPPING_THRESHOLD) {
|
||||||
isClipping |= (++overs >= CLIPPING_DETECTION);
|
isClipping |= (++overs >= CLIPPING_DETECTION);
|
||||||
} else {
|
} else {
|
||||||
|
@ -218,6 +210,17 @@ static float computeLoudness(int16_t* samples, int numSamples, int numChannels,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isClipping;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float computeLoudness(int16_t* samples, int numSamples) {
|
||||||
|
|
||||||
|
float scale = numSamples ? 1.0f / numSamples : 0.0f;
|
||||||
|
|
||||||
|
int32_t loudness = 0;
|
||||||
|
for (int i = 0; i < numSamples; i++) {
|
||||||
|
loudness += std::abs((int32_t)samples[i]);
|
||||||
|
}
|
||||||
return (float)loudness * scale;
|
return (float)loudness * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1404,6 +1407,15 @@ void AudioClient::handleMicAudioInput() {
|
||||||
|
|
||||||
_inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired);
|
_inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired);
|
||||||
|
|
||||||
|
// detect clipping on the raw input
|
||||||
|
bool isClipping = detectClipping(inputAudioSamples.get(), inputSamplesRequired, _inputFormat.channelCount());
|
||||||
|
if (isClipping) {
|
||||||
|
_timeSinceLastClip = 0.0f;
|
||||||
|
} else if (_timeSinceLastClip >= 0.0f) {
|
||||||
|
_timeSinceLastClip += AudioConstants::NETWORK_FRAME_SECS;
|
||||||
|
}
|
||||||
|
isClipping = (_timeSinceLastClip >= 0.0f) && (_timeSinceLastClip < 2.0f); // 2 second hold time
|
||||||
|
|
||||||
#if defined(WEBRTC_ENABLED)
|
#if defined(WEBRTC_ENABLED)
|
||||||
if (_isAECEnabled) {
|
if (_isAECEnabled) {
|
||||||
processWebrtcNearEnd(inputAudioSamples.get(), inputSamplesRequired / _inputFormat.channelCount(),
|
processWebrtcNearEnd(inputAudioSamples.get(), inputSamplesRequired / _inputFormat.channelCount(),
|
||||||
|
@ -1411,9 +1423,7 @@ void AudioClient::handleMicAudioInput() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// detect loudness and clipping on the raw input
|
float loudness = computeLoudness(inputAudioSamples.get(), inputSamplesRequired);
|
||||||
bool isClipping = false;
|
|
||||||
float loudness = computeLoudness(inputAudioSamples.get(), inputSamplesRequired, _inputFormat.channelCount(), isClipping);
|
|
||||||
_lastRawInputLoudness = loudness;
|
_lastRawInputLoudness = loudness;
|
||||||
|
|
||||||
// envelope detection
|
// envelope detection
|
||||||
|
@ -1421,14 +1431,6 @@ void AudioClient::handleMicAudioInput() {
|
||||||
loudness += tc * (_lastSmoothedRawInputLoudness - loudness);
|
loudness += tc * (_lastSmoothedRawInputLoudness - loudness);
|
||||||
_lastSmoothedRawInputLoudness = loudness;
|
_lastSmoothedRawInputLoudness = loudness;
|
||||||
|
|
||||||
// clipping indicator
|
|
||||||
if (isClipping) {
|
|
||||||
_timeSinceLastClip = 0.0f;
|
|
||||||
} else if (_timeSinceLastClip >= 0.0f) {
|
|
||||||
_timeSinceLastClip += AudioConstants::NETWORK_FRAME_SECS;
|
|
||||||
}
|
|
||||||
isClipping = (_timeSinceLastClip >= 0.0f) && (_timeSinceLastClip < 2.0f); // 2 second hold time
|
|
||||||
|
|
||||||
emit inputLoudnessChanged(_lastSmoothedRawInputLoudness, isClipping);
|
emit inputLoudnessChanged(_lastSmoothedRawInputLoudness, isClipping);
|
||||||
|
|
||||||
if (!_muted) {
|
if (!_muted) {
|
||||||
|
|
Loading…
Reference in a new issue