mirror of
https://github.com/QuasarApp/SoundBand.git
synced 2025-05-04 02:59:34 +00:00
add chronoTime
This commit is contained in:
parent
d69006103e
commit
17dabbaf6b
@ -32,7 +32,8 @@ SOURCES += \
|
||||
../sync/song.cpp \
|
||||
../sync/sync.cpp \
|
||||
servermodel.cpp \
|
||||
songmodel.cpp
|
||||
songmodel.cpp \
|
||||
../sync/chronotime.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@ -44,7 +45,8 @@ HEADERS += \
|
||||
../sync/song.h \
|
||||
../sync/sync.h \
|
||||
servermodel.h \
|
||||
songmodel.h
|
||||
songmodel.h \
|
||||
../sync/chronotime.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "ETcpSocket.h"
|
||||
#include "exaptions.h"
|
||||
#include "config.h"
|
||||
|
||||
ETcpSocket::ETcpSocket()
|
||||
{
|
||||
@ -23,7 +22,10 @@ ETcpSocket::ETcpSocket(const QString& address, int port){
|
||||
}
|
||||
|
||||
void ETcpSocket::init(){
|
||||
array=new QByteArray;
|
||||
array = new QByteArray;
|
||||
fSynced = false;
|
||||
differenceTime = 0;
|
||||
|
||||
connect(source,SIGNAL(connected()),this,SLOT(connected_()));
|
||||
connect(source,SIGNAL(disconnected()),this,SLOT(disconnected_()));
|
||||
connect(source,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(error_(QAbstractSocket::SocketError)));
|
||||
@ -59,11 +61,77 @@ void ETcpSocket::stateChanged_(QAbstractSocket::SocketState socketState){
|
||||
|
||||
void ETcpSocket::readReady_(){
|
||||
bool sizewrite=array->isEmpty();
|
||||
//while(source->bytesAvailable())
|
||||
array->append(source->readAll());
|
||||
QDataStream stream(array,QIODevice::ReadOnly);
|
||||
if(sizewrite)
|
||||
stream>>size;
|
||||
if(sizewrite){
|
||||
stream >> size;
|
||||
switch (size) {
|
||||
case CALIBRATION_SENDER:{
|
||||
milliseconds ms;
|
||||
stream >> ms;
|
||||
|
||||
milliseconds range = ChronoTime::now() - ms;
|
||||
|
||||
QByteArray cArray;
|
||||
QDataStream stream(&cArray,QIODevice::ReadWrite);
|
||||
|
||||
if(range < MIN_DIFFERENCE){
|
||||
stream << CALIBRATION_RECEIVER_DONE;
|
||||
fSynced = true;
|
||||
|
||||
}else{
|
||||
stream << CALIBRATION_RECEIVER;
|
||||
stream << range;
|
||||
|
||||
}
|
||||
|
||||
source->write(cArray);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
case CALIBRATION_RECEIVER:{
|
||||
ping = ChronoTime::now() - lastTime;
|
||||
milliseconds ms;
|
||||
stream >> ms;
|
||||
|
||||
differenceTime += ms + ping / 2;
|
||||
|
||||
QByteArray cArray;
|
||||
QDataStream stream(&cArray,QIODevice::ReadWrite);
|
||||
stream << CALIBRATION_SENDER;
|
||||
stream << milliseconds(ChronoTime::now() + differenceTime);
|
||||
|
||||
lastTime = ChronoTime::now();
|
||||
source->write(cArray);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
case CALIBRATION_RECEIVER_DONE:{
|
||||
|
||||
QByteArray cArray;
|
||||
QDataStream stream(&cArray,QIODevice::ReadWrite);
|
||||
stream << CALIBRATION_SENDER_DONE;
|
||||
|
||||
stream << milliseconds(-differenceTime);
|
||||
fSynced = true;
|
||||
|
||||
source->write(cArray);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
case CALIBRATION_SENDER_DONE:{
|
||||
|
||||
stream >> differenceTime;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#ifdef QT_DEBUG
|
||||
qDebug()<<"messae size:"<<size;
|
||||
qDebug()<<"message package size:"<<array->size();
|
||||
@ -77,7 +145,6 @@ void ETcpSocket::readReady_(){
|
||||
}else{
|
||||
emit donwload(array->size(),size);
|
||||
}
|
||||
// emit ReadReady(this);
|
||||
}
|
||||
|
||||
QString ETcpSocket::name() const{
|
||||
@ -112,12 +179,21 @@ QString ETcpSocket::toStringTcp(){
|
||||
return source->peerAddress().toString();
|
||||
}
|
||||
|
||||
milliseconds ETcpSocket::getDifferenceTime() const{
|
||||
return differenceTime;
|
||||
}
|
||||
|
||||
bool ETcpSocket::isSynced()const{
|
||||
return fSynced;
|
||||
}
|
||||
|
||||
bool ETcpSocket::Write(const QByteArray&data){
|
||||
if(source->state()==QTcpSocket::ConnectedState){
|
||||
QByteArray array;
|
||||
QDataStream stream(&array,QIODevice::ReadWrite);
|
||||
stream<<qint32(0);
|
||||
//stream<<data;
|
||||
|
||||
stream << qint32(0);
|
||||
|
||||
array.append(data);
|
||||
stream.device()->seek(0);
|
||||
stream<<qint32(array.size());
|
||||
@ -133,6 +209,19 @@ bool ETcpSocket::Write(const QByteArray&data){
|
||||
return false;
|
||||
}
|
||||
|
||||
void ETcpSocket::calibration(){
|
||||
if(!fSynced){
|
||||
QByteArray cArray;
|
||||
QDataStream stream(&cArray,QIODevice::ReadWrite);
|
||||
stream << CALIBRATION_SENDER;
|
||||
stream << milliseconds(ChronoTime::now());
|
||||
lastTime = ChronoTime::now();
|
||||
|
||||
source->write(cArray);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ETcpSocket::~ETcpSocket()
|
||||
{
|
||||
for(QByteArray*i:ReadyStack){
|
||||
|
@ -4,6 +4,14 @@
|
||||
#include <QTcpServer>
|
||||
#include <QList>
|
||||
#include <QDataStream>
|
||||
#include "chronotime.h"
|
||||
|
||||
#define CALIBRATION_SENDER qint32(-1)
|
||||
#define CALIBRATION_RECEIVER qint32(-2)
|
||||
#define CALIBRATION_SENDER_DONE qint32(-3)
|
||||
#define CALIBRATION_RECEIVER_DONE qint32(-4)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ETcpSocket class
|
||||
@ -25,6 +33,8 @@
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class ETcpSocket:public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -35,6 +45,17 @@ private:
|
||||
qint32 size;
|
||||
QList<QByteArray*> ReadyStack;
|
||||
void init();
|
||||
/**
|
||||
* @brief differenceTime - local time difference in milliseconds
|
||||
* on milliseconds
|
||||
*/
|
||||
milliseconds differenceTime;
|
||||
/**
|
||||
* @brief fSynced - whether a time difference was found.
|
||||
*/
|
||||
bool fSynced;
|
||||
milliseconds lastTime;
|
||||
milliseconds ping;
|
||||
|
||||
private slots:
|
||||
void connected_();
|
||||
@ -70,6 +91,25 @@ public:
|
||||
* @return true if all done else false.
|
||||
*/
|
||||
bool Write(const QByteArray&);
|
||||
|
||||
/**
|
||||
* @brief getDifferenceTime
|
||||
* @return Difference Time of remoute node.
|
||||
*/
|
||||
milliseconds getDifferenceTime()const;
|
||||
|
||||
/**
|
||||
* @brief isSynced
|
||||
* @return
|
||||
*/
|
||||
bool isSynced()const;
|
||||
|
||||
/**
|
||||
* @brief calibration - will calculate the difference in time between the connected node
|
||||
* and the current node.
|
||||
*/
|
||||
void calibration();
|
||||
|
||||
~ETcpSocket();
|
||||
public slots:
|
||||
/**
|
||||
@ -126,6 +166,7 @@ signals:
|
||||
*/
|
||||
void StateChanged(ETcpSocket*,QAbstractSocket::SocketState socketState);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // CLIENT_H
|
||||
|
31
sync/chronotime.cpp
Normal file
31
sync/chronotime.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "chronotime.h"
|
||||
#include <QDebug>
|
||||
|
||||
ChronoTime::ChronoTime()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* information about chrono
|
||||
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
|
||||
*/
|
||||
|
||||
milliseconds ChronoTime::now(){
|
||||
auto tim = std::chrono::system_clock::now();
|
||||
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
|
||||
auto epoh = mc.time_since_epoch();
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << epoh.count();
|
||||
#endif
|
||||
return epoh.count();
|
||||
}
|
||||
|
||||
Clock ChronoTime::from(const milliseconds& mc){
|
||||
std::chrono::milliseconds dur(mc);
|
||||
return Clock(dur);
|
||||
}
|
||||
|
||||
milliseconds ChronoTime::abs(milliseconds number){
|
||||
return (number << 1) >> 1;
|
||||
}
|
35
sync/chronotime.h
Normal file
35
sync/chronotime.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef CHRONOTIME_H
|
||||
#define CHRONOTIME_H
|
||||
#include <chrono>
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @brief Time_point on nanosecunds (uint64_t)
|
||||
*/
|
||||
typedef long long milliseconds;
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
|
||||
|
||||
class ChronoTime
|
||||
{
|
||||
public:
|
||||
ChronoTime();
|
||||
/**
|
||||
* @brief now - get now time on microsecunds
|
||||
* @return - count of microsecunds
|
||||
*/
|
||||
static milliseconds now();
|
||||
/**
|
||||
* @brief from cast to chrono secunds
|
||||
* @param mcrs microseconds of uint_64
|
||||
* @return microseconds of chrono
|
||||
*/
|
||||
static Clock from(const milliseconds &mcrs);
|
||||
|
||||
/**
|
||||
* @brief abs
|
||||
* @return module of numver
|
||||
*/
|
||||
static milliseconds abs(milliseconds number);
|
||||
};
|
||||
|
||||
#endif // CHRONOTIME_H
|
@ -20,6 +20,6 @@
|
||||
#define DEEP_SCANER_INTERVAL 10000 // 10 sec
|
||||
|
||||
// sync
|
||||
#define MIN_DIFFERENCE 100 // millisec
|
||||
#define MIN_DIFFERENCE 10 // millisec
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
@ -71,12 +71,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class feedbackError:public std::exception
|
||||
{
|
||||
public:
|
||||
QString what(){
|
||||
return QObject::tr("Could not create synchronization confirmation packet.");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // EXAPTIONS_H
|
||||
|
@ -3,12 +3,7 @@
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @brief Time_point on nanosecunds (uint64_t)
|
||||
*/
|
||||
typedef quint64 milliseconds;
|
||||
#include "chronotime.h"
|
||||
|
||||
namespace syncLib {
|
||||
|
||||
@ -23,7 +18,7 @@ struct Syncer
|
||||
*/
|
||||
milliseconds seek;
|
||||
/**
|
||||
* @brief run when is play media file (int)
|
||||
* @brief run when is play media file (milliseconds)
|
||||
*/
|
||||
milliseconds run;
|
||||
};
|
||||
|
@ -41,10 +41,6 @@ Sync::Sync(const QString address, int port, const QString &datadir):
|
||||
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(endPlay(QMediaPlayer::State)));
|
||||
}
|
||||
|
||||
int Sync::abs(int number) const{
|
||||
return (number << 1) >> 1;
|
||||
}
|
||||
|
||||
bool Sync::findHeader(const Song &song){
|
||||
|
||||
for(SongHeader & header: playList){
|
||||
@ -179,26 +175,6 @@ bool Sync::load(const SongHeader &song,Song &result){
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* information about chrono
|
||||
* https://stackoverflow.com/questions/31255486/c-how-do-i-convert-a-stdchronotime-point-to-long-and-back
|
||||
*/
|
||||
|
||||
milliseconds Sync::now(){
|
||||
auto tim = std::chrono::system_clock::now();
|
||||
auto mc = std::chrono::time_point_cast<std::chrono::milliseconds>(tim);
|
||||
auto epoh = mc.time_since_epoch();
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << epoh.count();
|
||||
#endif
|
||||
return epoh.count();
|
||||
}
|
||||
|
||||
Clock Sync::from(const milliseconds& mc){
|
||||
std::chrono::milliseconds dur(mc);
|
||||
return Clock(dur);
|
||||
}
|
||||
|
||||
bool Sync::play(const SongHeader &header, const Syncer *syncdata){
|
||||
|
||||
if(!header.isValid()){
|
||||
@ -296,13 +272,16 @@ void Sync::jump(const qint64 seek){
|
||||
}
|
||||
|
||||
bool Sync::sync(const Syncer &sync){
|
||||
milliseconds sync_time = sync.run - now();
|
||||
milliseconds sync_time = sync.run - ChronoTime::now();
|
||||
if(sync_time > MAX_SYNC_TIME && sync_time <= 0)
|
||||
return false;
|
||||
Clock run_time = from(sync.run);
|
||||
|
||||
Clock run_time = ChronoTime::from(sync.run);
|
||||
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
} while (std::chrono::high_resolution_clock::now() < run_time);
|
||||
|
||||
player->setPosition(sync.seek);
|
||||
return true;
|
||||
}
|
||||
@ -348,14 +327,14 @@ bool Sync::createPackage(Type type, package &pac){
|
||||
|
||||
if(type & TypePackage::t_sync && fbroadcaster){
|
||||
|
||||
pac.playdata.run = now() + SYNC_TIME;
|
||||
pac.playdata.run = ChronoTime::now() + SYNC_TIME;
|
||||
pac.playdata.seek = player->position() + SYNC_TIME;
|
||||
|
||||
}
|
||||
|
||||
if( type & TypePackage::t_feedback && !fbroadcaster){
|
||||
|
||||
pac.playdata.run = now();
|
||||
pac.playdata.run = ChronoTime::now();
|
||||
pac.playdata.seek = player->position();
|
||||
|
||||
}
|
||||
@ -467,7 +446,7 @@ void Sync::packageRender(ETcpSocket *socket){
|
||||
return ;
|
||||
}
|
||||
|
||||
unsigned int diff = abs(static_cast<unsigned int>(player->position() - (pkg.getPlayData().seek + (now() - pkg.getPlayData().run))));
|
||||
unsigned int diff = ChronoTime::abs(player->position() - (pkg.getPlayData().seek + (ChronoTime::now() - pkg.getPlayData().run)));
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << "diff " << socket->name() <<": " << diff;
|
||||
|
18
sync/sync.h
18
sync/sync.h
@ -13,7 +13,6 @@ class QSqlQuery;
|
||||
class QBuffer;
|
||||
namespace syncLib {
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Clock;
|
||||
|
||||
class Node;
|
||||
|
||||
@ -37,11 +36,6 @@ private:
|
||||
LocalScanner deepScaner;
|
||||
int port;
|
||||
QString dataBaseName;
|
||||
/**
|
||||
* @brief abs
|
||||
* @return module of numver
|
||||
*/
|
||||
int abs(int number)const;
|
||||
|
||||
/**
|
||||
* @brief findHeader set curent song if playList have playng song
|
||||
@ -87,17 +81,7 @@ private:
|
||||
* @return song drom local database.
|
||||
*/
|
||||
Song fromDataBase(const int id);
|
||||
/**
|
||||
* @brief now - get now time on microsecunds
|
||||
* @return - count of microsecunds
|
||||
*/
|
||||
milliseconds now();
|
||||
/**
|
||||
* @brief from cast to chrono secunds
|
||||
* @param mcrs microseconds of uint_64
|
||||
* @return microseconds of chrono
|
||||
*/
|
||||
Clock from(const milliseconds &mcrs);
|
||||
|
||||
/**
|
||||
* @brief createPackage - Create a package that shows current state of the node
|
||||
* @param type - Type of an answer
|
||||
|
Loading…
x
Reference in New Issue
Block a user