mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 22:07:03 +02:00
Rolling my own 100hz timer
Starting with the simplest possible thing - just sleep for 10000 microseconds. Can make it adaptive if need be.
This commit is contained in:
parent
b4c064a538
commit
b58c36cb12
2 changed files with 54 additions and 15 deletions
|
@ -15,6 +15,7 @@
|
|||
#include <QtNetwork/QNetworkDiskCache>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QThread>
|
||||
|
||||
#include <AssetClient.h>
|
||||
#include <AvatarHashMap.h>
|
||||
|
@ -48,6 +49,18 @@
|
|||
|
||||
static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 10;
|
||||
|
||||
// this should send a signal every 10ms, with pretty good precision
|
||||
void AvatarAudioTimer::start() {
|
||||
qDebug() << "AvatarAudioTimer::start called";
|
||||
const int TARGET_INTERVAL_USEC = 10000; // 10ms
|
||||
while (!_quit) {
|
||||
// simplest possible timer
|
||||
usleep(TARGET_INTERVAL_USEC);
|
||||
emit avatarTick();
|
||||
}
|
||||
qDebug() << "AvatarAudioTimer is finished";
|
||||
}
|
||||
|
||||
Agent::Agent(ReceivedMessage& message) :
|
||||
ThreadedAssignment(message),
|
||||
_entityEditSender(),
|
||||
|
@ -121,7 +134,6 @@ void Agent::handleAudioPacket(QSharedPointer<ReceivedMessage> message) {
|
|||
_receivedAudioStream.parseData(*message);
|
||||
|
||||
_lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness();
|
||||
|
||||
_receivedAudioStream.clearBuffer();
|
||||
}
|
||||
|
||||
|
@ -372,11 +384,15 @@ void Agent::executeScript() {
|
|||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||
|
||||
DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());
|
||||
|
||||
_avatarAudioTimer = new QTimer(this);
|
||||
_avatarAudioTimer->setTimerType(Qt::PreciseTimer);
|
||||
connect(_avatarAudioTimer, SIGNAL(timeout()), this, SLOT(processAgentAvatarAndAudio()));
|
||||
_avatarAudioTimer->start(10);
|
||||
|
||||
qDebug() << "Connecting avatarAudioTimer and starting...";
|
||||
AvatarAudioTimer* audioTimerWorker = new AvatarAudioTimer();
|
||||
audioTimerWorker->moveToThread(&_avatarAudioTimerThread);
|
||||
connect(audioTimerWorker, &AvatarAudioTimer::avatarTick, this, &Agent::processAgentAvatarAndAudio);
|
||||
connect(this, &Agent::startAvatarAudioTimer, audioTimerWorker, &AvatarAudioTimer::start);
|
||||
connect(this, &Agent::stopAvatarAudioTimer, audioTimerWorker, &AvatarAudioTimer::stop);
|
||||
connect(&_avatarAudioTimerThread, &QThread::finished, audioTimerWorker, &QObject::deleteLater);
|
||||
_avatarAudioTimerThread.start();
|
||||
|
||||
// wire up our additional agent related processing to the update signal
|
||||
//QObject::connect(_scriptEngine.get(), &ScriptEngine::update, this, &Agent::processAgentAvatarAndAudio);
|
||||
|
@ -406,6 +422,10 @@ void Agent::setIsAvatar(bool isAvatar) {
|
|||
|
||||
// start the timers
|
||||
_avatarIdentityTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS);
|
||||
|
||||
// tell the audiotimer worker to start working
|
||||
emit startAvatarAudioTimer();
|
||||
|
||||
}
|
||||
|
||||
if (!_isAvatar) {
|
||||
|
@ -428,7 +448,7 @@ void Agent::sendAvatarIdentityPacket() {
|
|||
void Agent::processAgentAvatarAndAudio() {
|
||||
if (!_scriptEngine->isFinished() && _isAvatar) {
|
||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||
const int SCRIPT_AUDIO_BUFFER_SAMPLES = AudioConstants::SAMPLE_RATE / 100;//SCRIPT_FPS + 0.5;
|
||||
const int SCRIPT_AUDIO_BUFFER_SAMPLES = AudioConstants::SAMPLE_RATE / 100 + 0.5;
|
||||
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
||||
|
||||
QByteArray avatarByteArray = scriptedAvatar->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
|
@ -513,16 +533,15 @@ void Agent::processAgentAvatarAndAudio() {
|
|||
audioPacket->writePrimitive(headOrientation);
|
||||
|
||||
// encode it
|
||||
QByteArray decodedBuffer(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
||||
QByteArray encodedBuffer;
|
||||
if (_encoder) {
|
||||
if(_encoder) {
|
||||
QByteArray decodedBuffer(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
||||
QByteArray encodedBuffer;
|
||||
_encoder->encode(decodedBuffer, encodedBuffer);
|
||||
audioPacket->write(encodedBuffer.data(), encodedBuffer.size());
|
||||
} else {
|
||||
audioPacket->write(decodedBuffer.data(), decodedBuffer.size());
|
||||
audioPacket->write(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples*sizeof(int16_t));
|
||||
}
|
||||
|
||||
// write the raw audio data
|
||||
audioPacket->write(encodedBuffer.data(), encodedBuffer.size());
|
||||
}
|
||||
|
||||
// write audio packet to AudioMixer nodes
|
||||
|
@ -558,6 +577,9 @@ void Agent::aboutToFinish() {
|
|||
// cleanup the AudioInjectorManager (and any still running injectors)
|
||||
DependencyManager::destroy<AudioInjectorManager>();
|
||||
|
||||
emit stopAvatarAudioTimer();
|
||||
_avatarAudioTimerThread.quit();
|
||||
|
||||
// cleanup codec & encoder
|
||||
if (_codec && _encoder) {
|
||||
_codec->releaseEncoder(_encoder);
|
||||
|
|
|
@ -32,6 +32,20 @@
|
|||
#include "MixedAudioStream.h"
|
||||
|
||||
|
||||
class AvatarAudioTimer : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void avatarTick();
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
void stop() { _quit = true; }
|
||||
|
||||
private:
|
||||
bool _quit { false };
|
||||
};
|
||||
|
||||
class Agent : public ThreadedAssignment {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -60,6 +74,7 @@ public:
|
|||
public slots:
|
||||
void run() override;
|
||||
void playAvatarSound(SharedSoundPointer avatarSound) { setAvatarSound(avatarSound); }
|
||||
void processAgentAvatarAndAudio();
|
||||
|
||||
private slots:
|
||||
void requestScript();
|
||||
|
@ -71,9 +86,11 @@ private slots:
|
|||
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
void processAgentAvatarAndAudio();
|
||||
void nodeActivated(SharedNodePointer activatedNode);
|
||||
|
||||
signals:
|
||||
void startAvatarAudioTimer();
|
||||
void stopAvatarAudioTimer();
|
||||
private:
|
||||
void negotiateAudioFormat();
|
||||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
@ -102,7 +119,7 @@ private:
|
|||
CodecPluginPointer _codec;
|
||||
QString _selectedCodecName;
|
||||
Encoder* _encoder { nullptr };
|
||||
QTimer* _avatarAudioTimer;
|
||||
QThread _avatarAudioTimerThread;
|
||||
};
|
||||
|
||||
#endif // hifi_Agent_h
|
||||
|
|
Loading…
Reference in a new issue