Merge pull request #8911 from davidkelly/dk/agentAvatarAudioArtifacts

Dk/agent avatar audio artifacts
This commit is contained in:
Howard Stearns 2016-10-26 09:56:43 -07:00 committed by GitHub
commit 5d42e7a5e6
2 changed files with 35 additions and 21 deletions

View file

@ -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);
} }
}); });
} }

View file

@ -81,7 +81,8 @@ 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;
EntityTreeHeadlessViewer _entityViewer; EntityTreeHeadlessViewer _entityViewer;
@ -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