Added frame computation and JS hooks

This commit is contained in:
Atlante45 2014-09-23 11:01:21 -07:00
parent c4105f61b5
commit 13a5dbf489
5 changed files with 75 additions and 9 deletions

View file

@ -625,6 +625,32 @@ qint64 AvatarData::playerLength() {
return _player->getRecording()->getLength(); return _player->getRecording()->getLength();
} }
int AvatarData::playerCurrentFrame() {
if (!_player) {
return 0;
}
if (QThread::currentThread() != thread()) {
int result;
QMetaObject::invokeMethod(this, "playerCurrentFrame", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, result));
return result;
}
return _player->getCurrentFrame();
}
int AvatarData::playerFrameNumber() {
if (!_player) {
return 0;
}
if (QThread::currentThread() != thread()) {
int result;
QMetaObject::invokeMethod(this, "playerFrameNumber", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, result));
return result;
}
return _player->getRecording()->getFrameNumber();
}
void AvatarData::loadRecording(QString filename) { void AvatarData::loadRecording(QString filename) {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "loadRecording", Qt::BlockingQueuedConnection, QMetaObject::invokeMethod(this, "loadRecording", Qt::BlockingQueuedConnection,
@ -649,6 +675,18 @@ void AvatarData::startPlaying() {
_player->startPlaying(); _player->startPlaying();
} }
void AvatarData::setPlayerFrame(int frame) {
if (_player) {
_player->setCurrentFrame(frame);
}
}
void AvatarData::setPlayerTime(qint64 time) {
if (_player) {
_player->setCurrentTime(time);
}
}
void AvatarData::setPlayFromCurrentLocation(bool playFromCurrentLocation) { void AvatarData::setPlayFromCurrentLocation(bool playFromCurrentLocation) {
if (_player) { if (_player) {
_player->setPlayFromCurrentLocation(playFromCurrentLocation); _player->setPlayFromCurrentLocation(playFromCurrentLocation);

View file

@ -298,8 +298,13 @@ public slots:
bool isPlaying(); bool isPlaying();
qint64 playerElapsed(); qint64 playerElapsed();
qint64 playerLength(); qint64 playerLength();
int playerCurrentFrame();
int playerFrameNumber();
void loadRecording(QString filename); void loadRecording(QString filename);
void startPlaying(); void startPlaying();
void setPlayerFrame(int frame);
void setPlayerTime(qint64 time);
void setPlayFromCurrentLocation(bool playFromCurrentLocation); void setPlayFromCurrentLocation(bool playFromCurrentLocation);
void setPlayerLoop(bool loop); void setPlayerLoop(bool loop);
void setPlayerUseDisplayName(bool useDisplayName); void setPlayerUseDisplayName(bool useDisplayName);

View file

@ -9,6 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <AudioRingBuffer.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <NodeList.h> #include <NodeList.h>
#include <StreamUtils.h> #include <StreamUtils.h>
@ -224,6 +225,9 @@ void Player::setCurrentFrame(int currentFrame) {
_currentFrame = currentFrame; _currentFrame = currentFrame;
_timerOffset = _recording->getFrameTimestamp(_currentFrame); _timerOffset = _recording->getFrameTimestamp(_currentFrame);
_timer.restart();
setAudionInjectorPosition();
} }
void Player::setCurrentTime(qint64 currentTime) { void Player::setCurrentTime(qint64 currentTime) {
@ -232,15 +236,14 @@ void Player::setCurrentTime(qint64 currentTime) {
return; return;
} }
_timerOffset = currentTime;
// Find correct frame // Find correct frame
int bestGuess = 0;
int lowestBound = 0; int lowestBound = 0;
int highestBound = _recording->getFrameNumber() - 1; int highestBound = _recording->getFrameNumber() - 1;
while (_recording->getFrameTimestamp(bestGuess) <= _timerOffset && int bestGuess = 0;
_recording->getFrameTimestamp(bestGuess + 1) > _timerOffset) { while (!(_recording->getFrameTimestamp(bestGuess) <= currentTime &&
if (_recording->getFrameTimestamp(bestGuess) < _timerOffset) { _recording->getFrameTimestamp(bestGuess + 1) > currentTime)) {
if (_recording->getFrameTimestamp(bestGuess) <= currentTime) {
lowestBound = bestGuess; lowestBound = bestGuess;
} else { } else {
highestBound = bestGuess; highestBound = bestGuess;
@ -248,9 +251,24 @@ void Player::setCurrentTime(qint64 currentTime) {
bestGuess = lowestBound + bestGuess = lowestBound +
(highestBound - lowestBound) * (highestBound - lowestBound) *
(_timerOffset - _recording->getFrameTimestamp(lowestBound)) / (float)(currentTime - _recording->getFrameTimestamp(lowestBound)) /
(_recording->getFrameTimestamp(highestBound) - _recording->getFrameTimestamp(lowestBound)); (float)(_recording->getFrameTimestamp(highestBound) - _recording->getFrameTimestamp(lowestBound));
} }
_currentFrame = bestGuess;
_timerOffset = _recording->getFrameTimestamp(bestGuess);
_timer.restart();
setAudionInjectorPosition();
}
void Player::setAudionInjectorPosition() {
int MSEC_PER_SEC = 1000;
int SAMPLE_SIZE = 2; // 16 bits
int CHANNEL_COUNT = 1;
int FRAME_SIZE = SAMPLE_SIZE * CHANNEL_COUNT;
int currentAudioFrame = elapsed() * FRAME_SIZE * (SAMPLE_RATE / MSEC_PER_SEC);
_injector->setCurrentSendPosition(currentAudioFrame);
} }
void Player::setPlayFromCurrentLocation(bool playFromCurrentLocation) { void Player::setPlayFromCurrentLocation(bool playFromCurrentLocation) {

View file

@ -33,6 +33,7 @@ public:
qint64 elapsed() const; qint64 elapsed() const;
RecordingPointer getRecording() const { return _recording; } RecordingPointer getRecording() const { return _recording; }
int getCurrentFrame() const { return _currentFrame; }
public slots: public slots:
void startPlaying(); void startPlaying();
@ -55,6 +56,7 @@ private:
void setupAudioThread(); void setupAudioThread();
void cleanupAudioThread(); void cleanupAudioThread();
void loopRecording(); void loopRecording();
void setAudionInjectorPosition();
bool computeCurrentFrame(); bool computeCurrentFrame();
QElapsedTimer _timer; QElapsedTimer _timer;

View file

@ -9,6 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <AudioRingBuffer.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <NetworkAccessManager.h> #include <NetworkAccessManager.h>
#include <NodeList.h> #include <NodeList.h>
@ -60,6 +61,9 @@ qint32 Recording::getFrameTimestamp(int i) const {
if (i >= _timestamps.size()) { if (i >= _timestamps.size()) {
return getLength(); return getLength();
} }
if (i < 0) {
return 0;
}
return _timestamps[i]; return _timestamps[i];
} }
@ -770,7 +774,6 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr
fileStream >> audioArray; fileStream >> audioArray;
// Cut down audio if necessary // Cut down audio if necessary
int SAMPLE_RATE = 48000; // 48 kHz
int SAMPLE_SIZE = 2; // 16 bits int SAMPLE_SIZE = 2; // 16 bits
int MSEC_PER_SEC = 1000; int MSEC_PER_SEC = 1000;
int audioLength = recording->getLength() * SAMPLE_SIZE * (SAMPLE_RATE / MSEC_PER_SEC); int audioLength = recording->getLength() * SAMPLE_SIZE * (SAMPLE_RATE / MSEC_PER_SEC);