diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index d5e1c59d7a..31c135fd58 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -96,6 +96,7 @@ void AudioInjector::injectAudio() { packetStream << radius; // pack 255 for attenuation byte + int volumeOptionOffset = injectAudioPacket.size(); quint8 volume = MAX_INJECTOR_VOLUME * _options.getVolume(); packetStream << volume; @@ -118,6 +119,8 @@ void AudioInjector::injectAudio() { memcpy(injectAudioPacket.data() + orientationOptionOffset, &_options.getOrientation(), sizeof(_options.getOrientation())); + volume = MAX_INJECTOR_VOLUME * _options.getVolume(); + memcpy(injectAudioPacket.data() + volumeOptionOffset, &volume, sizeof(volume)); // resize the QByteArray to the right size injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 126da654ae..ef7083e3bf 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -652,13 +652,25 @@ void AvatarData::startPlaying() { _player->startPlaying(); } -void AvatarData::setPlayerFrame(int frame) { +void AvatarData::setPlayerVolume(float volume) { + if (_player) { + _player->setVolume(volume); + } +} + +void AvatarData::setPlayerAudioOffset(int audioOffset) { + if (_player) { + _player->setAudioOffset(audioOffset); + } +} + +void AvatarData::setPlayerFrame(unsigned int frame) { if (_player) { _player->setCurrentFrame(frame); } } -void AvatarData::setPlayerTime(qint64 time) { +void AvatarData::setPlayerTime(unsigned int time) { if (_player) { _player->setCurrentTime(time); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 9b28fdc258..1fd4052974 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -100,8 +100,6 @@ enum KeyState { DELETE_KEY_DOWN }; -const glm::vec3 vec3Zero(0.0f); - class QDataStream; class AttachmentData; @@ -304,8 +302,10 @@ public slots: void loadRecording(QString filename); void startPlaying(); - void setPlayerFrame(int frame); - void setPlayerTime(qint64 time); + void setPlayerVolume(float volume); + void setPlayerAudioOffset(int audioOffset); + void setPlayerFrame(unsigned int frame); + void setPlayerTime(unsigned int time); void setPlayFromCurrentLocation(bool playFromCurrentLocation); void setPlayerLoop(bool loop); void setPlayerUseDisplayName(bool useDisplayName); diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 2540d7d004..35a822f11b 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -17,13 +17,16 @@ #include "AvatarData.h" #include "Player.h" +static const int INVALID_FRAME = -1; + Player::Player(AvatarData* avatar) : - _recording(new Recording()), - _currentFrame(-1), - _frameInterpolationFactor(0.0f), - _pausedFrame(-1), - _timerOffset(0), _avatar(avatar), + _recording(new Recording()), + _currentFrame(INVALID_FRAME), + _frameInterpolationFactor(0.0f), + _pausedFrame(INVALID_FRAME), + _timerOffset(0), + _audioOffset(0), _audioThread(NULL), _playFromCurrentPosition(true), _loop(false), @@ -33,8 +36,6 @@ Player::Player(AvatarData* avatar) : _useSkeletonURL(true) { _timer.invalidate(); - _options.setLoop(false); - _options.setVolume(1.0f); } bool Player::isPlaying() const { @@ -42,7 +43,7 @@ bool Player::isPlaying() const { } bool Player::isPaused() const { - return (_pausedFrame != -1); + return (_pausedFrame != INVALID_FRAME); } qint64 Player::elapsed() const { @@ -122,7 +123,7 @@ void Player::startPlaying() { _timer.start(); setCurrentFrame(_pausedFrame); - _pausedFrame = -1; + _pausedFrame = INVALID_FRAME; } } @@ -130,7 +131,7 @@ void Player::stopPlaying() { if (!isPlaying()) { return; } - _pausedFrame = -1; + _pausedFrame = INVALID_FRAME; _timer.invalidate(); cleanupAudioThread(); _avatar->clearJointsData(); @@ -201,12 +202,12 @@ void Player::loadFromFile(const QString& file) { } readRecordingFromFile(_recording, file); - _pausedFrame = -1; + _pausedFrame = INVALID_FRAME; } void Player::loadRecording(RecordingPointer recording) { _recording = recording; - _pausedFrame = -1; + _pausedFrame = INVALID_FRAME; } void Player::play() { @@ -253,6 +254,9 @@ void Player::play() { HeadData* head = const_cast(_avatar->getHeadData()); if (head) { + // Make sure fake faceshift connection doesn't get turned off + _avatar->setForceFaceshiftConnected(true); + QVector blendCoef(currentFrame.getBlendshapeCoefficients().size()); for (int i = 0; i < currentFrame.getBlendshapeCoefficients().size(); ++i) { blendCoef[i] = glm::mix(currentFrame.getBlendshapeCoefficients()[i], @@ -293,8 +297,8 @@ void Player::play() { _injector->setOptions(_options); } -void Player::setCurrentFrame(int currentFrame) { - if (_recording && (currentFrame < 0 || currentFrame >= _recording->getFrameNumber())) { +void Player::setCurrentFrame(unsigned int currentFrame) { + if (_recording && currentFrame >= _recording->getFrameNumber()) { stopPlaying(); return; } @@ -306,12 +310,12 @@ void Player::setCurrentFrame(int currentFrame) { _timer.start(); setAudionInjectorPosition(); } else { - _pausedFrame = currentFrame; + _pausedFrame = _currentFrame; } } -void Player::setCurrentTime(qint64 currentTime) { - if (currentTime < 0 || currentTime >= _recording->getLength()) { +void Player::setCurrentTime(unsigned int currentTime) { + if (currentTime >= _recording->getLength()) { stopPlaying(); return; } @@ -355,6 +359,18 @@ void Player::setCurrentTime(qint64 currentTime) { } } +void Player::setVolume(float volume) { + _options.setVolume(volume); + if (_injector) { + _injector->setOptions(_options); + } + qDebug() << "New volume: " << volume; +} + +void Player::setAudioOffset(int audioOffset) { + _audioOffset = audioOffset; +} + void Player::setAudionInjectorPosition() { int MSEC_PER_SEC = 1000; int SAMPLE_SIZE = 2; // 16 bits @@ -370,14 +386,19 @@ void Player::setPlayFromCurrentLocation(bool playFromCurrentLocation) { bool Player::computeCurrentFrame() { if (!isPlaying()) { - _currentFrame = -1; + _currentFrame = INVALID_FRAME; return false; } if (_currentFrame < 0) { _currentFrame = 0; } - qint64 elapsed = Player::elapsed(); + quint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength()); + while(_currentFrame >= 0 && + _recording->getFrameTimestamp(_currentFrame) > elapsed) { + --_currentFrame; + } + while (_currentFrame < _recording->getFrameNumber() && _recording->getFrameTimestamp(_currentFrame) < elapsed) { ++_currentFrame; diff --git a/libraries/avatars/src/Player.h b/libraries/avatars/src/Player.h index 5db56d725a..043fcc4a25 100644 --- a/libraries/avatars/src/Player.h +++ b/libraries/avatars/src/Player.h @@ -44,8 +44,11 @@ public slots: void loadRecording(RecordingPointer recording); void play(); - void setCurrentFrame(int currentFrame); - void setCurrentTime(qint64 currentTime); + void setCurrentFrame(unsigned int currentFrame); + void setCurrentTime(unsigned int currentTime); + + void setVolume(float volume); + void setAudioOffset(int audioOffset); void setPlayFromCurrentLocation(bool playFromCurrentPosition); void setLoop(bool loop) { _loop = loop; } @@ -61,19 +64,20 @@ private: void setAudionInjectorPosition(); bool computeCurrentFrame(); - QElapsedTimer _timer; + AvatarData* _avatar; RecordingPointer _recording; int _currentFrame; float _frameInterpolationFactor; int _pausedFrame; - qint64 _timerOffset; + + QElapsedTimer _timer; + int _timerOffset; + int _audioOffset; + QThread* _audioThread; QSharedPointer _injector; AudioInjectorOptions _options; - AvatarData* _avatar; - QThread* _audioThread; - RecordingContext _currentContext; bool _playFromCurrentPosition; bool _loop;