mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:49:24 +02:00
Merge pull request #8911 from davidkelly/dk/agentAvatarAudioArtifacts
Dk/agent avatar audio artifacts
This commit is contained in:
commit
5d42e7a5e6
2 changed files with 35 additions and 21 deletions
|
@ -361,10 +361,6 @@ void Agent::executeScript() {
|
||||||
// register ourselves to the script engine
|
// register ourselves to the script engine
|
||||||
_scriptEngine->registerGlobalObject("Agent", this);
|
_scriptEngine->registerGlobalObject("Agent", this);
|
||||||
|
|
||||||
// FIXME -we shouldn't be calling this directly, it's normally called by run(), not sure why
|
|
||||||
// viewers would need this called.
|
|
||||||
//_scriptEngine->init(); // must be done before we set up the viewers
|
|
||||||
|
|
||||||
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
_scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
||||||
|
|
||||||
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor);
|
||||||
|
@ -478,9 +474,24 @@ void Agent::processAgentAvatar() {
|
||||||
nodeList->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer);
|
nodeList->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void Agent::flushEncoder() {
|
||||||
|
_flushEncoder = false;
|
||||||
|
static QByteArray zeros(AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL, 0);
|
||||||
|
static QByteArray encodedZeros;
|
||||||
|
if (_encoder) {
|
||||||
|
_encoder->encode(zeros, encodedZeros);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Agent::processAgentAvatarAudio() {
|
void Agent::processAgentAvatarAudio() {
|
||||||
if (_isAvatar && (_isListeningToAudioStream || _avatarSound)) {
|
if (_isAvatar && (_isListeningToAudioStream || _avatarSound)) {
|
||||||
|
// after sound is done playing, encoder has a bit of state in it,
|
||||||
|
// and needs some 0s to forget or you get a little click next time
|
||||||
|
// you play something
|
||||||
|
if (_flushEncoder) {
|
||||||
|
flushEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
// if we have an avatar audio stream then send it out to our audio-mixer
|
// if we have an avatar audio stream then send it out to our audio-mixer
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
bool silentFrame = true;
|
bool silentFrame = true;
|
||||||
|
@ -513,6 +524,7 @@ void Agent::processAgentAvatarAudio() {
|
||||||
// and our sent bytes back to zero
|
// and our sent bytes back to zero
|
||||||
_avatarSound.clear();
|
_avatarSound.clear();
|
||||||
_numAvatarSoundSentBytes = 0;
|
_numAvatarSoundSentBytes = 0;
|
||||||
|
_flushEncoder = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,14 +541,16 @@ void Agent::processAgentAvatarAudio() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write the codec
|
||||||
|
audioPacket->writeString(_selectedCodecName);
|
||||||
|
|
||||||
// write the number of silent samples so the audio-mixer can uphold timing
|
// write the number of silent samples so the audio-mixer can uphold timing
|
||||||
audioPacket->writePrimitive(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
|
audioPacket->writePrimitive(numAvailableSamples);
|
||||||
|
|
||||||
// use the orientation and position of this avatar for the source of this audio
|
// use the orientation and position of this avatar for the source of this audio
|
||||||
audioPacket->writePrimitive(scriptedAvatar->getPosition());
|
audioPacket->writePrimitive(scriptedAvatar->getPosition());
|
||||||
glm::quat headOrientation = scriptedAvatar->getHeadOrientation();
|
glm::quat headOrientation = scriptedAvatar->getHeadOrientation();
|
||||||
audioPacket->writePrimitive(headOrientation);
|
audioPacket->writePrimitive(headOrientation);
|
||||||
|
|
||||||
} else if (nextSoundOutput) {
|
} else if (nextSoundOutput) {
|
||||||
|
|
||||||
// write the codec
|
// write the codec
|
||||||
|
@ -550,30 +564,28 @@ void Agent::processAgentAvatarAudio() {
|
||||||
glm::quat headOrientation = scriptedAvatar->getHeadOrientation();
|
glm::quat headOrientation = scriptedAvatar->getHeadOrientation();
|
||||||
audioPacket->writePrimitive(headOrientation);
|
audioPacket->writePrimitive(headOrientation);
|
||||||
|
|
||||||
|
QByteArray decodedBuffer(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
||||||
|
QByteArray encodedBuffer;
|
||||||
// encode it
|
// encode it
|
||||||
if(_encoder) {
|
if(_encoder) {
|
||||||
QByteArray decodedBuffer(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
|
||||||
QByteArray encodedBuffer;
|
|
||||||
_encoder->encode(decodedBuffer, encodedBuffer);
|
_encoder->encode(decodedBuffer, encodedBuffer);
|
||||||
audioPacket->write(encodedBuffer.data(), encodedBuffer.size());
|
} else {
|
||||||
} else {
|
encodedBuffer = decodedBuffer;
|
||||||
audioPacket->write(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
|
||||||
}
|
}
|
||||||
|
audioPacket->write(encodedBuffer.constData(), encodedBuffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// write audio packet to AudioMixer nodes
|
// write audio packet to AudioMixer nodes
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
nodeList->eachNode([this, &nodeList, &audioPacket](const SharedNodePointer& node) {
|
nodeList->eachNode([this, &nodeList, &audioPacket](const SharedNodePointer& node) {
|
||||||
// only send to nodes of type AudioMixer
|
// only send to nodes of type AudioMixer
|
||||||
if (node->getType() == NodeType::AudioMixer) {
|
if (node->getType() == NodeType::AudioMixer) {
|
||||||
// pack sequence number
|
// pack sequence number
|
||||||
quint16 sequence = _outgoingScriptAudioSequenceNumbers[node->getUUID()]++;
|
quint16 sequence = _outgoingScriptAudioSequenceNumbers[node->getUUID()]++;
|
||||||
audioPacket->seek(0);
|
audioPacket->seek(0);
|
||||||
audioPacket->writePrimitive(sequence);
|
audioPacket->writePrimitive(sequence);
|
||||||
|
// send audio packet
|
||||||
// send audio packet
|
nodeList->sendUnreliablePacket(*audioPacket, *node);
|
||||||
nodeList->sendUnreliablePacket(*audioPacket, *node);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
void negotiateAudioFormat();
|
void negotiateAudioFormat();
|
||||||
void selectAudioFormat(const QString& selectedCodecName);
|
void selectAudioFormat(const QString& selectedCodecName);
|
||||||
|
void flushEncoder();
|
||||||
|
|
||||||
std::unique_ptr<ScriptEngine> _scriptEngine;
|
std::unique_ptr<ScriptEngine> _scriptEngine;
|
||||||
EntityEditPacketSender _entityEditSender;
|
EntityEditPacketSender _entityEditSender;
|
||||||
|
@ -107,6 +108,7 @@ private:
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
Encoder* _encoder { nullptr };
|
Encoder* _encoder { nullptr };
|
||||||
QThread _avatarAudioTimerThread;
|
QThread _avatarAudioTimerThread;
|
||||||
|
bool _flushEncoder { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Agent_h
|
#endif // hifi_Agent_h
|
||||||
|
|
Loading…
Reference in a new issue