4
0
mirror of https://github.com/QuasarApp/SoundBand.git synced 2025-05-04 02:59:34 +00:00

add chronoTime

This commit is contained in:
Andrei Yankovich 2017-12-17 01:23:38 +03:00
parent d69006103e
commit 17dabbaf6b
10 changed files with 220 additions and 72 deletions

@ -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

@ -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

@ -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;

@ -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