From 64ba5b4f1488828a4e8b6626b4560b25231c63a3 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 23 Nov 2015 09:42:34 -0800 Subject: [PATCH] Cleaning up old recording files --- interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/MyAvatar.cpp | 1 - libraries/avatars/src/Player.cpp | 443 ------------------- libraries/avatars/src/Player.h | 94 ---- libraries/avatars/src/Recorder.cpp | 147 ------ libraries/avatars/src/Recorder.h | 57 --- libraries/avatars/src/Recording.cpp | 663 ---------------------------- libraries/avatars/src/Recording.h | 131 ------ 8 files changed, 1537 deletions(-) delete mode 100644 libraries/avatars/src/Player.cpp delete mode 100644 libraries/avatars/src/Player.h delete mode 100644 libraries/avatars/src/Recorder.cpp delete mode 100644 libraries/avatars/src/Recorder.h delete mode 100644 libraries/avatars/src/Recording.cpp delete mode 100644 libraries/avatars/src/Recording.h diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index bfa32b8223..f0f77cfd20 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -40,7 +40,6 @@ #include "Menu.h" #include "ModelReferential.h" #include "Physics.h" -#include "Recorder.h" #include "Util.h" #include "world.h" #include "InterfaceLogging.h" diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c446eba514..cac60b2381 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -49,7 +49,6 @@ #include "ModelReferential.h" #include "MyAvatar.h" #include "Physics.h" -#include "Recorder.h" #include "Util.h" #include "InterfaceLogging.h" #include "DebugDraw.h" diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp deleted file mode 100644 index 31efb4cd9c..0000000000 --- a/libraries/avatars/src/Player.cpp +++ /dev/null @@ -1,443 +0,0 @@ -// -// Player.cpp -// -// -// Created by Clement on 9/17/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -#if 0 -#include -#include -#include -#include - -#include "AvatarData.h" -#include "AvatarLogging.h" -#include "Player.h" - -static const int INVALID_FRAME = -1; - -Player::Player(AvatarData* avatar) : - _avatar(avatar), - _recording(new Recording()), - _currentFrame(INVALID_FRAME), - _frameInterpolationFactor(0.0f), - _pausedFrame(INVALID_FRAME), - _timerOffset(0), - _audioOffset(0), - _audioThread(NULL), - _playFromCurrentPosition(true), - _loop(false), - _useAttachments(true), - _useDisplayName(true), - _useHeadURL(true), - _useSkeletonURL(true) -{ - _timer.invalidate(); -} - -bool Player::isPlaying() const { - return _timer.isValid(); -} - -bool Player::isPaused() const { - return (_pausedFrame != INVALID_FRAME); -} - -qint64 Player::elapsed() const { - if (isPlaying()) { - return _timerOffset + _timer.elapsed(); - } else if (isPaused()) { - return _timerOffset; - } else { - return 0; - } -} - -void Player::startPlaying() { - if (!_recording || _recording->getFrameNumber() <= 1) { - return; - } - - if (!isPaused()) { - _currentContext.globalTimestamp = usecTimestampNow(); - _currentContext.domain = DependencyManager::get()->getDomainHandler().getHostname(); - _currentContext.position = _avatar->getPosition(); - _currentContext.orientation = _avatar->getOrientation(); - _currentContext.scale = _avatar->getTargetScale(); - _currentContext.headModel = _avatar->getFaceModelURL().toString(); - _currentContext.skeletonModel = _avatar->getSkeletonModelURL().toString(); - _currentContext.displayName = _avatar->getDisplayName(); - _currentContext.attachments = _avatar->getAttachmentData(); - - _currentContext.orientationInv = glm::inverse(_currentContext.orientation); - - RecordingContext& context = _recording->getContext(); - if (_useAttachments) { - _avatar->setAttachmentData(context.attachments); - } - if (_useDisplayName) { - _avatar->setDisplayName(context.displayName); - } - if (_useHeadURL) { - _avatar->setFaceModelURL(context.headModel); - } - if (_useSkeletonURL) { - _avatar->setSkeletonModelURL(context.skeletonModel); - } - - bool wantDebug = false; - if (wantDebug) { - qCDebug(avatars) << "Player::startPlaying(): Recording Context"; - qCDebug(avatars) << "Domain:" << _currentContext.domain; - qCDebug(avatars) << "Position:" << _currentContext.position; - qCDebug(avatars) << "Orientation:" << _currentContext.orientation; - qCDebug(avatars) << "Scale:" << _currentContext.scale; - qCDebug(avatars) << "Head URL:" << _currentContext.headModel; - qCDebug(avatars) << "Skeleton URL:" << _currentContext.skeletonModel; - qCDebug(avatars) << "Display Name:" << _currentContext.displayName; - qCDebug(avatars) << "Num Attachments:" << _currentContext.attachments.size(); - - for (int i = 0; i < _currentContext.attachments.size(); ++i) { - qCDebug(avatars) << "Model URL:" << _currentContext.attachments[i].modelURL; - qCDebug(avatars) << "Joint Name:" << _currentContext.attachments[i].jointName; - qCDebug(avatars) << "Translation:" << _currentContext.attachments[i].translation; - qCDebug(avatars) << "Rotation:" << _currentContext.attachments[i].rotation; - qCDebug(avatars) << "Scale:" << _currentContext.attachments[i].scale; - } - } - - // Fake faceshift connection - _avatar->setForceFaceTrackerConnected(true); - - qCDebug(avatars) << "Recorder::startPlaying()"; - setupAudioThread(); - _currentFrame = 0; - _timerOffset = 0; - _timer.start(); - } else { - qCDebug(avatars) << "Recorder::startPlaying(): Unpause"; - setupAudioThread(); - _timer.start(); - - setCurrentFrame(_pausedFrame); - _pausedFrame = INVALID_FRAME; - } -} - -void Player::stopPlaying() { - if (!isPlaying()) { - return; - } - _pausedFrame = INVALID_FRAME; - _timer.invalidate(); - cleanupAudioThread(); - _avatar->clearJointsData(); - - // Turn off fake face tracker connection - _avatar->setForceFaceTrackerConnected(false); - - if (_useAttachments) { - _avatar->setAttachmentData(_currentContext.attachments); - } - if (_useDisplayName) { - _avatar->setDisplayName(_currentContext.displayName); - } - if (_useHeadURL) { - _avatar->setFaceModelURL(_currentContext.headModel); - } - if (_useSkeletonURL) { - _avatar->setSkeletonModelURL(_currentContext.skeletonModel); - } - - qCDebug(avatars) << "Recorder::stopPlaying()"; -} - -void Player::pausePlayer() { - _timerOffset = elapsed(); - _timer.invalidate(); - cleanupAudioThread(); - - _pausedFrame = _currentFrame; - qCDebug(avatars) << "Recorder::pausePlayer()"; -} - -void Player::setupAudioThread() { - _audioThread = new QThread(); - _audioThread->setObjectName("Player Audio Thread"); - _options.position = _avatar->getPosition(); - _options.orientation = _avatar->getOrientation(); - _options.stereo = _recording->numberAudioChannel() == 2; - - _injector.reset(new AudioInjector(_recording->getAudioData(), _options), &QObject::deleteLater); - _injector->moveToThread(_audioThread); - _audioThread->start(); - QMetaObject::invokeMethod(_injector.data(), "injectAudio", Qt::QueuedConnection); -} - -void Player::cleanupAudioThread() { - _injector->stop(); - QObject::connect(_injector.data(), &AudioInjector::finished, - _injector.data(), &AudioInjector::deleteLater); - QObject::connect(_injector.data(), &AudioInjector::destroyed, - _audioThread, &QThread::quit); - QObject::connect(_audioThread, &QThread::finished, - _audioThread, &QThread::deleteLater); - _injector.clear(); - _audioThread = NULL; -} - -void Player::loopRecording() { - cleanupAudioThread(); - setupAudioThread(); - _currentFrame = 0; - _timerOffset = 0; - _timer.restart(); -} - -void Player::loadFromFile(const QString& file) { - if (_recording) { - _recording->clear(); - } else { - _recording = QSharedPointer(); - } - readRecordingFromFile(_recording, file); - - _pausedFrame = INVALID_FRAME; -} - -void Player::loadRecording(RecordingPointer recording) { - _recording = recording; - _pausedFrame = INVALID_FRAME; -} - -void Player::play() { - computeCurrentFrame(); - if (_currentFrame < 0 || (_currentFrame >= _recording->getFrameNumber() - 2)) { // -2 because of interpolation - if (_loop) { - loopRecording(); - } else { - stopPlaying(); - } - return; - } - - const RecordingContext* context = &_recording->getContext(); - if (_playFromCurrentPosition) { - context = &_currentContext; - } - const RecordingFrame& currentFrame = _recording->getFrame(_currentFrame); - const RecordingFrame& nextFrame = _recording->getFrame(_currentFrame + 1); - - glm::vec3 translation = glm::mix(currentFrame.getTranslation(), - nextFrame.getTranslation(), - _frameInterpolationFactor); - _avatar->setPosition(context->position + context->orientation * translation); - - glm::quat rotation = safeMix(currentFrame.getRotation(), - nextFrame.getRotation(), - _frameInterpolationFactor); - _avatar->setOrientation(context->orientation * rotation); - - float scale = glm::mix(currentFrame.getScale(), - nextFrame.getScale(), - _frameInterpolationFactor); - _avatar->setTargetScale(context->scale * scale); - - // Joint array playback - // FIXME: THis is still using a deprecated path to assign the joint orientation since setting the full RawJointData array doesn't - // work for Avatar. We need to fix this working with the animation team - const auto& prevJointArray = currentFrame.getJointArray(); - const auto& nextJointArray = currentFrame.getJointArray(); - QVector jointArray(prevJointArray.size()); - QVector jointRotations(prevJointArray.size()); // FIXME: remove once the setRawJointData is fixed - QVector jointTranslations(prevJointArray.size()); // FIXME: remove once the setRawJointData is fixed - - for (int i = 0; i < jointArray.size(); i++) { - const auto& prevJoint = prevJointArray[i]; - const auto& nextJoint = nextJointArray[i]; - auto& joint = jointArray[i]; - - // Rotation - joint.rotationSet = prevJoint.rotationSet || nextJoint.rotationSet; - if (joint.rotationSet) { - joint.rotation = safeMix(prevJoint.rotation, nextJoint.rotation, _frameInterpolationFactor); - jointRotations[i] = joint.rotation; // FIXME: remove once the setRawJointData is fixed - } - - joint.translationSet = prevJoint.translationSet || nextJoint.translationSet; - if (joint.translationSet) { - joint.translation = glm::mix(prevJoint.translation, nextJoint.translation, _frameInterpolationFactor); - jointTranslations[i] = joint.translation; // FIXME: remove once the setRawJointData is fixed - } - } - - // _avatar->setRawJointData(jointArray); // FIXME: Enable once the setRawJointData is fixed - _avatar->setJointRotations(jointRotations); // FIXME: remove once the setRawJointData is fixed - // _avatar->setJointTranslations(jointTranslations); // FIXME: remove once the setRawJointData is fixed - - HeadData* head = const_cast(_avatar->getHeadData()); - if (head) { - // Make sure fake face tracker connection doesn't get turned off - _avatar->setForceFaceTrackerConnected(true); - - QVector blendCoef(currentFrame.getBlendshapeCoefficients().size()); - for (int i = 0; i < currentFrame.getBlendshapeCoefficients().size(); ++i) { - blendCoef[i] = glm::mix(currentFrame.getBlendshapeCoefficients()[i], - nextFrame.getBlendshapeCoefficients()[i], - _frameInterpolationFactor); - } - head->setBlendshapeCoefficients(blendCoef); - - float leanSideways = glm::mix(currentFrame.getLeanSideways(), - nextFrame.getLeanSideways(), - _frameInterpolationFactor); - head->setLeanSideways(leanSideways); - - float leanForward = glm::mix(currentFrame.getLeanForward(), - nextFrame.getLeanForward(), - _frameInterpolationFactor); - head->setLeanForward(leanForward); - - glm::quat headRotation = safeMix(currentFrame.getHeadRotation(), - nextFrame.getHeadRotation(), - _frameInterpolationFactor); - glm::vec3 eulers = glm::degrees(safeEulerAngles(headRotation)); - head->setFinalPitch(eulers.x); - head->setFinalYaw(eulers.y); - head->setFinalRoll(eulers.z); - - - glm::vec3 lookAt = glm::mix(currentFrame.getLookAtPosition(), - nextFrame.getLookAtPosition(), - _frameInterpolationFactor); - head->setLookAtPosition(context->position + context->orientation * lookAt); - } else { - qCDebug(avatars) << "WARNING: Player couldn't find head data."; - } - - _options.position = _avatar->getPosition(); - _options.orientation = _avatar->getOrientation(); - _injector->setOptions(_options); -} - -void Player::setCurrentFrame(int currentFrame) { - if (_recording && currentFrame >= _recording->getFrameNumber()) { - stopPlaying(); - return; - } - - _currentFrame = currentFrame; - _timerOffset = _recording->getFrameTimestamp(_currentFrame); - - if (isPlaying()) { - _timer.start(); - setAudioInjectorPosition(); - } else { - _pausedFrame = _currentFrame; - } -} - -void Player::setCurrentTime(int currentTime) { - if (currentTime >= _recording->getLength()) { - stopPlaying(); - return; - } - - // Find correct frame - int lowestBound = 0; - int highestBound = _recording->getFrameNumber() - 1; - while (lowestBound + 1 != highestBound) { - assert(lowestBound < highestBound); - - int bestGuess = lowestBound + - (highestBound - lowestBound) * - (float)(currentTime - _recording->getFrameTimestamp(lowestBound)) / - (float)(_recording->getFrameTimestamp(highestBound) - _recording->getFrameTimestamp(lowestBound)); - - if (_recording->getFrameTimestamp(bestGuess) <= currentTime) { - if (currentTime < _recording->getFrameTimestamp(bestGuess + 1)) { - lowestBound = bestGuess; - highestBound = bestGuess + 1; - } else { - lowestBound = bestGuess + 1; - } - } else { - if (_recording->getFrameTimestamp(bestGuess - 1) <= currentTime) { - lowestBound = bestGuess - 1; - highestBound = bestGuess; - } else { - highestBound = bestGuess - 1; - } - } - } - - setCurrentFrame(lowestBound); -} - -void Player::setVolume(float volume) { - _options.volume = volume; - if (_injector) { - _injector->setOptions(_options); - } - qCDebug(avatars) << "New volume: " << volume; -} - -void Player::setAudioOffset(int audioOffset) { - _audioOffset = audioOffset; -} - -void Player::setAudioInjectorPosition() { - int MSEC_PER_SEC = 1000; - int FRAME_SIZE = sizeof(AudioConstants::AudioSample) * _recording->numberAudioChannel(); - int currentAudioFrame = elapsed() * FRAME_SIZE * (AudioConstants::SAMPLE_RATE / MSEC_PER_SEC); - _injector->setCurrentSendOffset(currentAudioFrame); -} - -void Player::setPlayFromCurrentLocation(bool playFromCurrentLocation) { - _playFromCurrentPosition = playFromCurrentLocation; -} - -bool Player::computeCurrentFrame() { - if (!isPlaying()) { - _currentFrame = INVALID_FRAME; - return false; - } - if (_currentFrame < 0) { - _currentFrame = 0; - } - - qint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength()); - while (_currentFrame < _recording->getFrameNumber() && - _recording->getFrameTimestamp(_currentFrame) < elapsed) { - ++_currentFrame; - } - - while(_currentFrame > 0 && - _recording->getFrameTimestamp(_currentFrame) > elapsed) { - --_currentFrame; - } - - if (_currentFrame == _recording->getFrameNumber() - 1) { - --_currentFrame; - _frameInterpolationFactor = 1.0f; - } else { - qint64 currentTimestamps = _recording->getFrameTimestamp(_currentFrame); - qint64 nextTimestamps = _recording->getFrameTimestamp(_currentFrame + 1); - _frameInterpolationFactor = (float)(elapsed - currentTimestamps) / - (float)(nextTimestamps - currentTimestamps); - } - - if (_frameInterpolationFactor < 0.0f || _frameInterpolationFactor > 1.0f) { - _frameInterpolationFactor = 0.0f; - qCDebug(avatars) << "Invalid frame interpolation value: overriding"; - } - return true; -} - -#endif diff --git a/libraries/avatars/src/Player.h b/libraries/avatars/src/Player.h deleted file mode 100644 index 558ff309e6..0000000000 --- a/libraries/avatars/src/Player.h +++ /dev/null @@ -1,94 +0,0 @@ -// -// Player.h -// -// -// Created by Clement on 9/17/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Player_h -#define hifi_Player_h - -#include - -#if 0 -#include - -#include - -#include "Recording.h" - -class AvatarData; -class Player; - -typedef QSharedPointer PlayerPointer; -typedef QWeakPointer WeakPlayerPointer; - -/// Plays back a recording -class Player { -public: - Player(AvatarData* avatar); - - bool isPlaying() const; - bool isPaused() const; - qint64 elapsed() const; - - RecordingPointer getRecording() const { return _recording; } - int getCurrentFrame() const { return _currentFrame; } - -public slots: - void startPlaying(); - void stopPlaying(); - void pausePlayer(); - void loadFromFile(const QString& file); - void loadRecording(RecordingPointer recording); - void play(); - - void setCurrentFrame(int currentFrame); - void setCurrentTime(int currentTime); - - void setVolume(float volume); - void setAudioOffset(int audioOffset); - - void setPlayFromCurrentLocation(bool playFromCurrentPosition); - void setLoop(bool loop) { _loop = loop; } - void useAttachements(bool useAttachments) { _useAttachments = useAttachments; } - void useDisplayName(bool useDisplayName) { _useDisplayName = useDisplayName; } - void useHeadModel(bool useHeadURL) { _useHeadURL = useHeadURL; } - void useSkeletonModel(bool useSkeletonURL) { _useSkeletonURL = useSkeletonURL; } - -private: - void setupAudioThread(); - void cleanupAudioThread(); - void loopRecording(); - void setAudioInjectorPosition(); - bool computeCurrentFrame(); - - AvatarData* _avatar; - RecordingPointer _recording; - int _currentFrame; - float _frameInterpolationFactor; - int _pausedFrame; - - QElapsedTimer _timer; - int _timerOffset; - int _audioOffset; - - QThread* _audioThread; - QSharedPointer _injector; - AudioInjectorOptions _options; - - RecordingContext _currentContext; - bool _playFromCurrentPosition; - bool _loop; - bool _useAttachments; - bool _useDisplayName; - bool _useHeadURL; - bool _useSkeletonURL; -}; -#endif - -#endif // hifi_Player_h diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp deleted file mode 100644 index 343302d472..0000000000 --- a/libraries/avatars/src/Recorder.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// -// Recorder.cpp -// -// -// Created by Clement on 8/7/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -#if 0 -#include -#include -#include - -#include "AvatarData.h" -#include "AvatarLogging.h" -#include "Recorder.h" - -Recorder::Recorder(AvatarData* avatar) : - _recording(new Recording()), - _avatar(avatar) -{ - _timer.invalidate(); -} - -bool Recorder::isRecording() const { - return _timer.isValid(); -} - -qint64 Recorder::elapsed() const { - if (isRecording()) { - return _timer.elapsed(); - } else { - return 0; - } -} - -void Recorder::startRecording() { - qCDebug(avatars) << "Recorder::startRecording()"; - _recording->clear(); - - RecordingContext& context = _recording->getContext(); - context.globalTimestamp = usecTimestampNow(); - context.domain = DependencyManager::get()->getDomainHandler().getHostname(); - context.position = _avatar->getPosition(); - context.orientation = _avatar->getOrientation(); - context.scale = _avatar->getTargetScale(); - context.headModel = _avatar->getFaceModelURL().toString(); - context.skeletonModel = _avatar->getSkeletonModelURL().toString(); - context.displayName = _avatar->getDisplayName(); - context.attachments = _avatar->getAttachmentData(); - - context.orientationInv = glm::inverse(context.orientation); - - bool wantDebug = false; - if (wantDebug) { - qCDebug(avatars) << "Recorder::startRecording(): Recording Context"; - qCDebug(avatars) << "Global timestamp:" << context.globalTimestamp; - qCDebug(avatars) << "Domain:" << context.domain; - qCDebug(avatars) << "Position:" << context.position; - qCDebug(avatars) << "Orientation:" << context.orientation; - qCDebug(avatars) << "Scale:" << context.scale; - qCDebug(avatars) << "Head URL:" << context.headModel; - qCDebug(avatars) << "Skeleton URL:" << context.skeletonModel; - qCDebug(avatars) << "Display Name:" << context.displayName; - qCDebug(avatars) << "Num Attachments:" << context.attachments.size(); - - for (int i = 0; i < context.attachments.size(); ++i) { - qCDebug(avatars) << "Model URL:" << context.attachments[i].modelURL; - qCDebug(avatars) << "Joint Name:" << context.attachments[i].jointName; - qCDebug(avatars) << "Translation:" << context.attachments[i].translation; - qCDebug(avatars) << "Rotation:" << context.attachments[i].rotation; - qCDebug(avatars) << "Scale:" << context.attachments[i].scale; - } - } - - _timer.start(); - record(); -} - -void Recorder::stopRecording() { - qCDebug(avatars) << "Recorder::stopRecording()"; - _timer.invalidate(); - - qCDebug(avatars).nospace() << "Recorded " << _recording->getFrameNumber() << " during " << _recording->getLength() << " msec (" << _recording->getFrameNumber() / (_recording->getLength() / 1000.0f) << " fps)"; -} - -void Recorder::saveToFile(const QString& file) { - if (_recording->isEmpty()) { - qCDebug(avatars) << "Cannot save recording to file, recording is empty."; - } - - writeRecordingToFile(_recording, file); -} - -void Recorder::record() { - if (isRecording()) { - const RecordingContext& context = _recording->getContext(); - RecordingFrame frame; - frame.setBlendshapeCoefficients(_avatar->getHeadData()->getBlendshapeCoefficients()); - - // Capture the full skeleton joint data - auto& jointData = _avatar->getRawJointData(); - frame.setJointArray(jointData); - - frame.setTranslation(context.orientationInv * (_avatar->getPosition() - context.position)); - frame.setRotation(context.orientationInv * _avatar->getOrientation()); - frame.setScale(_avatar->getTargetScale() / context.scale); - - const HeadData* head = _avatar->getHeadData(); - if (head) { - glm::vec3 rotationDegrees = glm::vec3(head->getFinalPitch(), - head->getFinalYaw(), - head->getFinalRoll()); - frame.setHeadRotation(glm::quat(glm::radians(rotationDegrees))); - frame.setLeanForward(head->getLeanForward()); - frame.setLeanSideways(head->getLeanSideways()); - glm::vec3 relativeLookAt = context.orientationInv * - (head->getLookAtPosition() - context.position); - frame.setLookAtPosition(relativeLookAt); - } - - bool wantDebug = false; - if (wantDebug) { - qCDebug(avatars) << "Recording frame #" << _recording->getFrameNumber(); - qCDebug(avatars) << "Blendshapes:" << frame.getBlendshapeCoefficients().size(); - qCDebug(avatars) << "JointArray:" << frame.getJointArray().size(); - qCDebug(avatars) << "Translation:" << frame.getTranslation(); - qCDebug(avatars) << "Rotation:" << frame.getRotation(); - qCDebug(avatars) << "Scale:" << frame.getScale(); - qCDebug(avatars) << "Head rotation:" << frame.getHeadRotation(); - qCDebug(avatars) << "Lean Forward:" << frame.getLeanForward(); - qCDebug(avatars) << "Lean Sideways:" << frame.getLeanSideways(); - qCDebug(avatars) << "LookAtPosition:" << frame.getLookAtPosition(); - } - - _recording->addFrame(_timer.elapsed(), frame); - } -} - -void Recorder::recordAudio(const QByteArray& audioByteArray) { - _recording->addAudioPacket(audioByteArray); -} -#endif diff --git a/libraries/avatars/src/Recorder.h b/libraries/avatars/src/Recorder.h deleted file mode 100644 index 15bffcec8b..0000000000 --- a/libraries/avatars/src/Recorder.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// Recorder.h -// libraries/avatars/src -// -// Created by Clement on 8/7/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Recorder_h -#define hifi_Recorder_h - -#include - -#if 0 -#include "Recording.h" - -template -class QSharedPointer; - -class AttachmentData; -class AvatarData; -class Recorder; -class Recording; - -typedef QSharedPointer RecorderPointer; -typedef QWeakPointer WeakRecorderPointer; - -/// Records a recording -class Recorder : public QObject { - Q_OBJECT -public: - Recorder(AvatarData* avatar); - - bool isRecording() const; - qint64 elapsed() const; - - RecordingPointer getRecording() const { return _recording; } - -public slots: - void startRecording(); - void stopRecording(); - void saveToFile(const QString& file); - void record(); - void recordAudio(const QByteArray& audioArray); - -private: - QElapsedTimer _timer; - RecordingPointer _recording; - - AvatarData* _avatar; -}; -#endif - -#endif // hifi_Recorder_h diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp deleted file mode 100644 index 884ed495be..0000000000 --- a/libraries/avatars/src/Recording.cpp +++ /dev/null @@ -1,663 +0,0 @@ -// -// Recording.cpp -// -// -// Created by Clement on 9/17/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#if 0 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "AvatarData.h" -#include "AvatarLogging.h" -#include "Recording.h" - -// HFR file format magic number (Inspired by PNG) -// (decimal) 17 72 70 82 13 10 26 10 -// (hexadecimal) 11 48 46 52 0d 0a 1a 0a -// (ASCII C notation) \021 H F R \r \n \032 \n -static const int MAGIC_NUMBER_SIZE = 8; -static const char MAGIC_NUMBER[MAGIC_NUMBER_SIZE] = {17, 72, 70, 82, 13, 10, 26, 10}; -// Version (Major, Minor) -static const QPair VERSION(0, 2); - -int SCALE_RADIX = 10; -int BLENDSHAPE_RADIX = 15; -int LEAN_RADIX = 7; - -void RecordingFrame::setBlendshapeCoefficients(QVector blendshapeCoefficients) { - _blendshapeCoefficients = blendshapeCoefficients; -} - -int Recording::getLength() const { - if (_timestamps.isEmpty()) { - return 0; - } - return _timestamps.last(); -} - -qint32 Recording::getFrameTimestamp(int i) const { - if (i >= _timestamps.size()) { - return getLength(); - } - if (i < 0) { - return 0; - } - return _timestamps[i]; -} - -const RecordingFrame& Recording::getFrame(int i) const { - assert(i < _timestamps.size()); - return _frames[i]; -} - - -int Recording::numberAudioChannel() const { - // Check for stereo audio - float MSEC_PER_SEC = 1000.0f; - float channelLength = ((float)getLength() / MSEC_PER_SEC) * AudioConstants::SAMPLE_RATE * - sizeof(AudioConstants::AudioSample); - return glm::round((float)getAudioData().size() / channelLength); -} - -void Recording::addFrame(int timestamp, RecordingFrame &frame) { - _timestamps << timestamp; - _frames << frame; -} - -void Recording::clear() { - _timestamps.clear(); - _frames.clear(); - _audioData.clear(); -} - -void writeVec3(QDataStream& stream, const glm::vec3& value) { - unsigned char buffer[sizeof(value)]; - memcpy(buffer, &value, sizeof(value)); - stream.writeRawData(reinterpret_cast(buffer), sizeof(value)); -} - -bool readVec3(QDataStream& stream, glm::vec3& value) { - unsigned char buffer[sizeof(value)]; - stream.readRawData(reinterpret_cast(buffer), sizeof(value)); - memcpy(&value, buffer, sizeof(value)); - return true; -} - -void writeQuat(QDataStream& stream, const glm::quat& value) { - unsigned char buffer[256]; - int writtenToBuffer = packOrientationQuatToBytes(buffer, value); - stream.writeRawData(reinterpret_cast(buffer), writtenToBuffer); -} - -bool readQuat(QDataStream& stream, glm::quat& value) { - int quatByteSize = 4 * 2; // 4 floats * 2 bytes - unsigned char buffer[256]; - stream.readRawData(reinterpret_cast(buffer), quatByteSize); - int readFromBuffer = unpackOrientationQuatFromBytes(buffer, value); - if (readFromBuffer != quatByteSize) { - return false; - } - return true; -} - -bool readFloat(QDataStream& stream, float& value, int radix) { - int floatByteSize = 2; // 1 floats * 2 bytes - int16_t buffer[256]; - stream.readRawData(reinterpret_cast(buffer), floatByteSize); - int readFromBuffer = unpackFloatScalarFromSignedTwoByteFixed(buffer, &value, radix); - if (readFromBuffer != floatByteSize) { - return false; - } - return true; -} - -void writeRecordingToFile(RecordingPointer recording, const QString& filename) { - if (!recording || recording->getFrameNumber() < 1) { - qCDebug(avatars) << "Can't save empty recording"; - return; - } - - QElapsedTimer timer; - QFile file(filename); - if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)){ - qCDebug(avatars) << "Couldn't open " << filename; - return; - } - timer.start(); - qCDebug(avatars) << "Writing recording to " << filename << "."; - - QDataStream fileStream(&file); - - // HEADER - file.write(MAGIC_NUMBER, MAGIC_NUMBER_SIZE); // Magic number - fileStream << VERSION; // File format version - const qint64 dataOffsetPos = file.pos(); - fileStream << (quint16)0; // Save two empty bytes for the data offset - const qint64 dataLengthPos = file.pos(); - fileStream << (quint32)0; // Save four empty bytes for the data offset - const quint64 crc16Pos = file.pos(); - fileStream << (quint16)0; // Save two empty bytes for the CRC-16 - - - // METADATA - // TODO - - - - // Write data offset - quint16 dataOffset = file.pos(); - file.seek(dataOffsetPos); - fileStream << dataOffset; - file.seek(dataOffset); - - // CONTEXT - RecordingContext& context = recording->getContext(); - // Global Timestamp - fileStream << context.globalTimestamp; - // Domain - fileStream << context.domain; - // Position - writeVec3(fileStream, context.position); - // Orientation - writeQuat(fileStream, context.orientation); - // Scale - fileStream << context.scale; - // Head model - fileStream << context.headModel; - // Skeleton model - fileStream << context.skeletonModel; - // Display name - fileStream << context.displayName; - // Attachements - fileStream << (quint8)context.attachments.size(); - foreach (AttachmentData data, context.attachments) { - // Model - fileStream << data.modelURL.toString(); - // Joint name - fileStream << data.jointName; - // Position - writeVec3(fileStream, data.translation); - // Orientation - writeQuat(fileStream, data.rotation); - // Scale - fileStream << data.scale; - } - - // RECORDING - fileStream << recording->_timestamps; - - QBitArray mask; - quint32 numBlendshapes = 0; - quint32 numJoints = 0; - - for (int i = 0; i < recording->_timestamps.size(); ++i) { - mask.fill(false); - int maskIndex = 0; - QByteArray buffer; - QDataStream stream(&buffer, QIODevice::WriteOnly); - RecordingFrame& previousFrame = recording->_frames[(i != 0) ? i - 1 : i]; - RecordingFrame& frame = recording->_frames[i]; - - // Blendshape Coefficients - if (i == 0) { - numBlendshapes = frame.getBlendshapeCoefficients().size(); - stream << numBlendshapes; - mask.resize(mask.size() + numBlendshapes); - } - for (quint32 j = 0; j < numBlendshapes; ++j) { - if (i == 0 || - frame._blendshapeCoefficients[j] != previousFrame._blendshapeCoefficients[j]) { - stream << frame.getBlendshapeCoefficients()[j]; - mask.setBit(maskIndex); - } - ++maskIndex; - } - - const auto& jointArray = frame.getJointArray(); - if (i == 0) { - numJoints = jointArray.size(); - stream << numJoints; - // 2 fields per joints - mask.resize(mask.size() + numJoints * 2); - } - for (quint32 j = 0; j < numJoints; j++) { - const auto& joint = jointArray[j]; - if (true) { //(joint.rotationSet) { - writeQuat(stream, joint.rotation); - mask.setBit(maskIndex); - } - maskIndex++; - if (joint.translationSet) { - writeVec3(stream, joint.translation); - mask.setBit(maskIndex); - } - maskIndex++; - } - - // Translation - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._translation != previousFrame._translation) { - writeVec3(stream, frame._translation); - mask.setBit(maskIndex); - } - maskIndex++; - - // Rotation - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._rotation != previousFrame._rotation) { - writeQuat(stream, frame._rotation); - mask.setBit(maskIndex); - } - maskIndex++; - - // Scale - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._scale != previousFrame._scale) { - stream << frame._scale; - mask.setBit(maskIndex); - } - maskIndex++; - - // Head Rotation - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._headRotation != previousFrame._headRotation) { - writeQuat(stream, frame._headRotation); - mask.setBit(maskIndex); - } - maskIndex++; - - // Lean Sideways - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._leanSideways != previousFrame._leanSideways) { - stream << frame._leanSideways; - mask.setBit(maskIndex); - } - maskIndex++; - - // Lean Forward - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._leanForward != previousFrame._leanForward) { - stream << frame._leanForward; - mask.setBit(maskIndex); - } - maskIndex++; - - // LookAt Position - if (i == 0) { - mask.resize(mask.size() + 1); - } - if (i == 0 || frame._lookAtPosition != previousFrame._lookAtPosition) { - writeVec3(stream, frame._lookAtPosition); - mask.setBit(maskIndex); - } - maskIndex++; - - fileStream << mask; - fileStream << buffer; - } - - fileStream << recording->getAudioData(); - - qint64 writingTime = timer.restart(); - // Write data length and CRC-16 - quint32 dataLength = file.pos() - dataOffset; - file.seek(dataOffset); // Go to beginning of data for checksum - quint16 crc16 = qChecksum(file.readAll().constData(), dataLength); - - file.seek(dataLengthPos); - fileStream << dataLength; - file.seek(crc16Pos); - fileStream << crc16; - file.seek(dataOffset + dataLength); - - bool wantDebug = true; - if (wantDebug) { - qCDebug(avatars) << "[DEBUG] WRITE recording"; - qCDebug(avatars) << "Header:"; - qCDebug(avatars) << "File Format version:" << VERSION; - qCDebug(avatars) << "Data length:" << dataLength; - qCDebug(avatars) << "Data offset:" << dataOffset; - qCDebug(avatars) << "CRC-16:" << crc16; - - qCDebug(avatars) << "Context block:"; - qCDebug(avatars) << "Global timestamp:" << context.globalTimestamp; - qCDebug(avatars) << "Domain:" << context.domain; - qCDebug(avatars) << "Position:" << context.position; - qCDebug(avatars) << "Orientation:" << context.orientation; - qCDebug(avatars) << "Scale:" << context.scale; - qCDebug(avatars) << "Head Model:" << context.headModel; - qCDebug(avatars) << "Skeleton Model:" << context.skeletonModel; - qCDebug(avatars) << "Display Name:" << context.displayName; - qCDebug(avatars) << "Num Attachments:" << context.attachments.size(); - for (int i = 0; i < context.attachments.size(); ++i) { - qCDebug(avatars) << "Model URL:" << context.attachments[i].modelURL; - qCDebug(avatars) << "Joint Name:" << context.attachments[i].jointName; - qCDebug(avatars) << "Translation:" << context.attachments[i].translation; - qCDebug(avatars) << "Rotation:" << context.attachments[i].rotation; - qCDebug(avatars) << "Scale:" << context.attachments[i].scale; - } - - qCDebug(avatars) << "Recording:"; - qCDebug(avatars) << "Total frames:" << recording->getFrameNumber(); - qCDebug(avatars) << "Audio array:" << recording->getAudioData().size(); - } - - qint64 checksumTime = timer.elapsed(); - qCDebug(avatars) << "Wrote" << file.size() << "bytes in" << writingTime + checksumTime << "ms. (" << checksumTime << "ms for checksum)"; -} - -RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename) { - QByteArray byteArray; - QUrl url(filename); - QElapsedTimer timer; - timer.start(); // timer used for debug informations (download/parsing time) - - // Aquire the data and place it in byteArray - // Return if data unavailable - if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") { - // Download file if necessary - qCDebug(avatars) << "Downloading recording at" << url; - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest = QNetworkRequest(url); - networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); - QNetworkReply* reply = networkAccessManager.get(networkRequest); - QEventLoop loop; - QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); - loop.exec(); // wait for file - if (reply->error() != QNetworkReply::NoError) { - qCDebug(avatars) << "Error while downloading recording: " << reply->error(); - reply->deleteLater(); - return recording; - } - byteArray = reply->readAll(); - reply->deleteLater(); - // print debug + restart timer - qCDebug(avatars) << "Downloaded " << byteArray.size() << " bytes in " << timer.restart() << " ms."; - } else { - // If local file, just read it. - qCDebug(avatars) << "Reading recording from " << filename << "."; - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)){ - qCDebug(avatars) << "Could not open local file: " << url; - return recording; - } - byteArray = file.readAll(); - file.close(); - } - - if (!filename.endsWith(".hfr") && !filename.endsWith(".HFR")) { - qCDebug(avatars) << "File extension not recognized"; - } - - // Reset the recording passed in the arguments - if (!recording) { - recording = QSharedPointer::create(); - } - - QDataStream fileStream(byteArray); - - // HEADER - QByteArray magicNumber(MAGIC_NUMBER, MAGIC_NUMBER_SIZE); - if (!byteArray.startsWith(magicNumber)) { - qCDebug(avatars) << "ERROR: This is not a .HFR file. (Magic Number incorrect)"; - return recording; - } - fileStream.skipRawData(MAGIC_NUMBER_SIZE); - - QPair version; - fileStream >> version; // File format version - if (version != VERSION && version != QPair(0,1)) { - qCDebug(avatars) << "ERROR: This file format version is not supported."; - return recording; - } - - quint16 dataOffset = 0; - fileStream >> dataOffset; - quint32 dataLength = 0; - fileStream >> dataLength; - quint16 crc16 = 0; - fileStream >> crc16; - - - // Check checksum - quint16 computedCRC16 = qChecksum(byteArray.constData() + dataOffset, dataLength); - if (computedCRC16 != crc16) { - qCDebug(avatars) << "Checksum does not match. Bailling!"; - recording.clear(); - return recording; - } - - // METADATA - // TODO - - - - // CONTEXT - RecordingContext& context = recording->getContext(); - // Global Timestamp - fileStream >> context.globalTimestamp; - // Domain - fileStream >> context.domain; - // Position - if (!readVec3(fileStream, context.position)) { - qCDebug(avatars) << "Couldn't read file correctly. (Invalid vec3)"; - recording.clear(); - return recording; - } - // Orientation - if (!readQuat(fileStream, context.orientation)) { - qCDebug(avatars) << "Couldn't read file correctly. (Invalid quat)"; - recording.clear(); - return recording; - } - - // Scale - if (version == QPair(0,1)) { - readFloat(fileStream, context.scale, SCALE_RADIX); - } else { - fileStream >> context.scale; - } - // Head model - fileStream >> context.headModel; - // Skeleton model - fileStream >> context.skeletonModel; - // Display Name - fileStream >> context.displayName; - - // Attachements - quint8 numAttachments = 0; - fileStream >> numAttachments; - for (int i = 0; i < numAttachments; ++i) { - AttachmentData data; - // Model - QString modelURL; - fileStream >> modelURL; - data.modelURL = modelURL; - // Joint name - fileStream >> data.jointName; - // Translation - if (!readVec3(fileStream, data.translation)) { - qCDebug(avatars) << "Couldn't read attachment correctly. (Invalid vec3)"; - continue; - } - // Rotation - if (!readQuat(fileStream, data.rotation)) { - qCDebug(avatars) << "Couldn't read attachment correctly. (Invalid quat)"; - continue; - } - - // Scale - if (version == QPair(0,1)) { - readFloat(fileStream, data.scale, SCALE_RADIX); - } else { - fileStream >> data.scale; - } - context.attachments << data; - } - - quint32 numBlendshapes = 0; - quint32 numJoints = 0; - // RECORDING - fileStream >> recording->_timestamps; - - for (int i = 0; i < recording->_timestamps.size(); ++i) { - QBitArray mask; - QByteArray buffer; - QDataStream stream(&buffer, QIODevice::ReadOnly); - RecordingFrame frame; - RecordingFrame& previousFrame = (i == 0) ? frame : recording->_frames.last(); - - fileStream >> mask; - fileStream >> buffer; - int maskIndex = 0; - - // Blendshape Coefficients - if (i == 0) { - stream >> numBlendshapes; - } - frame._blendshapeCoefficients.resize(numBlendshapes); - for (quint32 j = 0; j < numBlendshapes; ++j) { - if (!mask[maskIndex++]) { - frame._blendshapeCoefficients[j] = previousFrame._blendshapeCoefficients[j]; - } else if (version == QPair(0,1)) { - readFloat(stream, frame._blendshapeCoefficients[j], BLENDSHAPE_RADIX); - } else { - stream >> frame._blendshapeCoefficients[j]; - } - } - // Joint Array - if (i == 0) { - stream >> numJoints; - } - - frame._jointArray.resize(numJoints); - for (quint32 j = 0; j < numJoints; ++j) { - auto& joint = frame._jointArray[2]; - - if (mask[maskIndex++] && readQuat(stream, joint.rotation)) { - joint.rotationSet = true; - } else { - joint.rotationSet = false; - } - - if (mask[maskIndex++] || readVec3(stream, joint.translation)) { - joint.translationSet = true; - } else { - joint.translationSet = false; - } - } - - if (!mask[maskIndex++] || !readVec3(stream, frame._translation)) { - frame._translation = previousFrame._translation; - } - - if (!mask[maskIndex++] || !readQuat(stream, frame._rotation)) { - frame._rotation = previousFrame._rotation; - } - - if (!mask[maskIndex++]) { - frame._scale = previousFrame._scale; - } else if (version == QPair(0,1)) { - readFloat(stream, frame._scale, SCALE_RADIX); - } else { - stream >> frame._scale; - } - - if (!mask[maskIndex++] || !readQuat(stream, frame._headRotation)) { - frame._headRotation = previousFrame._headRotation; - } - - if (!mask[maskIndex++]) { - frame._leanSideways = previousFrame._leanSideways; - } else if (version == QPair(0,1)) { - readFloat(stream, frame._leanSideways, LEAN_RADIX); - } else { - stream >> frame._leanSideways; - } - - if (!mask[maskIndex++]) { - frame._leanForward = previousFrame._leanForward; - } else if (version == QPair(0,1)) { - readFloat(stream, frame._leanForward, LEAN_RADIX); - } else { - stream >> frame._leanForward; - } - - if (!mask[maskIndex++] || !readVec3(stream, frame._lookAtPosition)) { - frame._lookAtPosition = previousFrame._lookAtPosition; - } - - recording->_frames << frame; - } - - QByteArray audioArray; - fileStream >> audioArray; - recording->addAudioPacket(audioArray); - - bool wantDebug = true; - if (wantDebug) { - qCDebug(avatars) << "[DEBUG] READ recording"; - qCDebug(avatars) << "Header:"; - qCDebug(avatars) << "File Format version:" << VERSION; - qCDebug(avatars) << "Data length:" << dataLength; - qCDebug(avatars) << "Data offset:" << dataOffset; - qCDebug(avatars) << "CRC-16:" << crc16; - - qCDebug(avatars) << "Context block:"; - qCDebug(avatars) << "Global timestamp:" << context.globalTimestamp; - qCDebug(avatars) << "Domain:" << context.domain; - qCDebug(avatars) << "Position:" << context.position; - qCDebug(avatars) << "Orientation:" << context.orientation; - qCDebug(avatars) << "Scale:" << context.scale; - qCDebug(avatars) << "Head Model:" << context.headModel; - qCDebug(avatars) << "Skeleton Model:" << context.skeletonModel; - qCDebug(avatars) << "Display Name:" << context.displayName; - qCDebug(avatars) << "Num Attachments:" << numAttachments; - for (int i = 0; i < numAttachments; ++i) { - qCDebug(avatars) << "Model URL:" << context.attachments[i].modelURL; - qCDebug(avatars) << "Joint Name:" << context.attachments[i].jointName; - qCDebug(avatars) << "Translation:" << context.attachments[i].translation; - qCDebug(avatars) << "Rotation:" << context.attachments[i].rotation; - qCDebug(avatars) << "Scale:" << context.attachments[i].scale; - } - - qCDebug(avatars) << "Recording:"; - qCDebug(avatars) << "Total frames:" << recording->getFrameNumber(); - qCDebug(avatars) << "Audio array:" << recording->getAudioData().size(); - - } - - qCDebug(avatars) << "Read " << byteArray.size() << " bytes in " << timer.elapsed() << " ms."; - return recording; -} - -#endif diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h deleted file mode 100644 index a5829b1e2f..0000000000 --- a/libraries/avatars/src/Recording.h +++ /dev/null @@ -1,131 +0,0 @@ -// -// Recording.h -// -// -// Created by Clement on 9/17/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Recording_h -#define hifi_Recording_h - -#if 0 - -#include -#include - -#include -#include - -template -class QSharedPointer; - -class AttachmentData; -class Recording; -class RecordingFrame; -class Sound; -class JointData; - -typedef QSharedPointer RecordingPointer; - -/// Stores recordings static data -class RecordingContext { -public: - quint64 globalTimestamp; - QString domain; - glm::vec3 position; - glm::quat orientation; - float scale; - QString headModel; - QString skeletonModel; - QString displayName; - QVector attachments; - - // This avoids recomputation every frame while recording. - glm::quat orientationInv; -}; - -/// Stores a recording -class Recording { -public: - bool isEmpty() const { return _timestamps.isEmpty(); } - int getLength() const; // in ms - - RecordingContext& getContext() { return _context; } - int getFrameNumber() const { return _frames.size(); } - qint32 getFrameTimestamp(int i) const; - const RecordingFrame& getFrame(int i) const; - const QByteArray& getAudioData() const { return _audioData; } - int numberAudioChannel() const; - -protected: - void addFrame(int timestamp, RecordingFrame& frame); - void addAudioPacket(const QByteArray& byteArray) { _audioData.append(byteArray); } - void clear(); - -private: - RecordingContext _context; - QVector _timestamps; - QVector _frames; - - QByteArray _audioData; - - friend class Recorder; - friend class Player; - friend void writeRecordingToFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, - const QByteArray& byteArray); -}; - -/// Stores the different values associated to one recording frame -class RecordingFrame { -public: - QVector getBlendshapeCoefficients() const { return _blendshapeCoefficients; } - QVector getJointArray() const { return _jointArray; } - glm::vec3 getTranslation() const { return _translation; } - glm::quat getRotation() const { return _rotation; } - float getScale() const { return _scale; } - glm::quat getHeadRotation() const { return _headRotation; } - float getLeanSideways() const { return _leanSideways; } - float getLeanForward() const { return _leanForward; } - glm::vec3 getLookAtPosition() const { return _lookAtPosition; } - -protected: - void setBlendshapeCoefficients(QVector blendshapeCoefficients); - void setJointArray(const QVector& jointArray) { _jointArray = jointArray; } - void setTranslation(const glm::vec3& translation) { _translation = translation; } - void setRotation(const glm::quat& rotation) { _rotation = rotation; } - void setScale(float scale) { _scale = scale; } - void setHeadRotation(glm::quat headRotation) { _headRotation = headRotation; } - void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } - void setLeanForward(float leanForward) { _leanForward = leanForward; } - void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } - -private: - QVector _blendshapeCoefficients; - QVector _jointArray; - - glm::vec3 _translation; - glm::quat _rotation; - float _scale; - glm::quat _headRotation; - float _leanSideways; - float _leanForward; - glm::vec3 _lookAtPosition; - - friend class Recorder; - friend void writeRecordingToFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, - const QByteArray& byteArray); -}; - -void writeRecordingToFile(RecordingPointer recording, const QString& filename); -RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename); -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); -#endif -#endif // hifi_Recording_h