Move the source
This commit is contained in:
parent
40b699e0a5
commit
d3059b608a
11 changed files with 339 additions and 185 deletions
|
@ -355,6 +355,7 @@ HEADERS += src/buffer.h \
|
||||||
src/global.h \
|
src/global.h \
|
||||||
src/multicolorled.h \
|
src/multicolorled.h \
|
||||||
src/protocol.h \
|
src/protocol.h \
|
||||||
|
src/recorder/jamcontroller.h \
|
||||||
src/server.h \
|
src/server.h \
|
||||||
src/serverlist.h \
|
src/serverlist.h \
|
||||||
src/serverlogging.h \
|
src/serverlogging.h \
|
||||||
|
@ -454,6 +455,7 @@ SOURCES += src/buffer.cpp \
|
||||||
src/client.cpp \
|
src/client.cpp \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
src/protocol.cpp \
|
src/protocol.cpp \
|
||||||
|
src/recorder/jamcontroller.cpp \
|
||||||
src/server.cpp \
|
src/server.cpp \
|
||||||
src/serverlist.cpp \
|
src/serverlist.cpp \
|
||||||
src/serverlogging.cpp \
|
src/serverlogging.cpp \
|
||||||
|
|
0
src/recorder/creaperproject.cpp
Executable file → Normal file
0
src/recorder/creaperproject.cpp
Executable file → Normal file
0
src/recorder/creaperproject.h
Executable file → Normal file
0
src/recorder/creaperproject.h
Executable file → Normal file
0
src/recorder/cwavestream.cpp
Executable file → Normal file
0
src/recorder/cwavestream.cpp
Executable file → Normal file
0
src/recorder/cwavestream.h
Executable file → Normal file
0
src/recorder/cwavestream.h
Executable file → Normal file
171
src/recorder/jamcontroller.cpp
Executable file
171
src/recorder/jamcontroller.cpp
Executable file
|
@ -0,0 +1,171 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* Copyright (c) 2020
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* pljones
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#include "jamcontroller.h"
|
||||||
|
|
||||||
|
using namespace recorder;
|
||||||
|
|
||||||
|
CJamController::CJamController() :
|
||||||
|
bRecorderInitialised ( false ),
|
||||||
|
bEnableRecording ( false ),
|
||||||
|
strRecordingDir ( "" ),
|
||||||
|
pthJamRecorder ( nullptr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CJamController::RequestNewRecording()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( bRecorderInitialised && bEnableRecording )
|
||||||
|
{
|
||||||
|
emit RestartRecorder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CJamController::SetEnableRecording ( bool bNewEnableRecording, bool isRunning )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( bRecorderInitialised )
|
||||||
|
{
|
||||||
|
// note that this block executes regardless of whether
|
||||||
|
// what appears to be a change is being applied, to ensure
|
||||||
|
// the requested state is the result
|
||||||
|
bEnableRecording = bNewEnableRecording;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
// TODO we should use the ConsoleWriterFactory() instead of qInfo()
|
||||||
|
qInfo() << "Recording state" << ( bEnableRecording ? "enabled" : "disabled" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( !bEnableRecording )
|
||||||
|
{
|
||||||
|
emit StopRecorder();
|
||||||
|
}
|
||||||
|
else if ( !isRunning )
|
||||||
|
{
|
||||||
|
// This dirty hack is for the GUI. It doesn't care.
|
||||||
|
emit StopRecorder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CJamController::SetRecordingDir ( QString newRecordingDir,
|
||||||
|
int iServerFrameSizeSamples )
|
||||||
|
{
|
||||||
|
if ( bRecorderInitialised && pthJamRecorder != nullptr )
|
||||||
|
{
|
||||||
|
// We have a thread and we want to start a new one.
|
||||||
|
// We only want one running.
|
||||||
|
// This could take time, unfortunately.
|
||||||
|
// Hopefully changing recording directory will NOT happen during a long jam...
|
||||||
|
emit EndRecorderThread();
|
||||||
|
pthJamRecorder->wait();
|
||||||
|
pthJamRecorder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !newRecordingDir.isEmpty() )
|
||||||
|
{
|
||||||
|
pJamRecorder = new recorder::CJamRecorder ( newRecordingDir, iServerFrameSizeSamples );
|
||||||
|
strRecorderErrMsg = pJamRecorder->Init();
|
||||||
|
bRecorderInitialised = ( strRecorderErrMsg == QString::null );
|
||||||
|
bEnableRecording = bRecorderInitialised;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is the only time this is ever true - UI needs to handle it
|
||||||
|
strRecorderErrMsg = QString::null;
|
||||||
|
bRecorderInitialised = false;
|
||||||
|
bEnableRecording = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bRecorderInitialised )
|
||||||
|
{
|
||||||
|
strRecordingDir = newRecordingDir;
|
||||||
|
|
||||||
|
pthJamRecorder = new QThread();
|
||||||
|
pJamRecorder->moveToThread ( pthJamRecorder );
|
||||||
|
pthJamRecorder->setObjectName ( "Jamulus::JamRecorder" );
|
||||||
|
|
||||||
|
// QT signals
|
||||||
|
QObject::connect ( pthJamRecorder, &QThread::finished,
|
||||||
|
pJamRecorder, &QObject::deleteLater );
|
||||||
|
|
||||||
|
QObject::connect( QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
|
pJamRecorder, &CJamRecorder::OnAboutToQuit,
|
||||||
|
Qt::ConnectionType::BlockingQueuedConnection );
|
||||||
|
|
||||||
|
// from the controller to the recorder
|
||||||
|
QObject::connect( this, &CJamController::RestartRecorder,
|
||||||
|
pJamRecorder, &CJamRecorder::OnTriggerSession );
|
||||||
|
|
||||||
|
QObject::connect( this, &CJamController::StopRecorder,
|
||||||
|
pJamRecorder, &CJamRecorder::OnEnd );
|
||||||
|
|
||||||
|
QObject::connect( this, &CJamController::EndRecorderThread,
|
||||||
|
pJamRecorder, &CJamRecorder::OnAboutToQuit,
|
||||||
|
Qt::ConnectionType::BlockingQueuedConnection );
|
||||||
|
|
||||||
|
// from the server to the recorder
|
||||||
|
QObject::connect( this, &CJamController::Stopped,
|
||||||
|
pJamRecorder, &CJamRecorder::OnEnd );
|
||||||
|
|
||||||
|
QObject::connect( this, &CJamController::ClientDisconnected,
|
||||||
|
pJamRecorder, &CJamRecorder::OnDisconnected );
|
||||||
|
|
||||||
|
qRegisterMetaType<CVector<int16_t>> ( "CVector<int16_t>" );
|
||||||
|
QObject::connect( this, &CJamController::AudioFrame,
|
||||||
|
pJamRecorder, &CJamRecorder::OnFrame );
|
||||||
|
|
||||||
|
// from the recorder to the server
|
||||||
|
QObject::connect ( pJamRecorder, &CJamRecorder::RecordingSessionStarted,
|
||||||
|
this, &CJamController::RecordingSessionStarted );
|
||||||
|
|
||||||
|
pthJamRecorder->start();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strRecordingDir = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ERecorderState CJamController::GetRecorderState()
|
||||||
|
{
|
||||||
|
// return recorder state
|
||||||
|
if ( bRecorderInitialised )
|
||||||
|
{
|
||||||
|
if ( bEnableRecording )
|
||||||
|
{
|
||||||
|
return RS_RECORDING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RS_NOT_ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RS_NOT_INITIALISED;
|
||||||
|
}
|
||||||
|
}
|
77
src/recorder/jamcontroller.h
Executable file
77
src/recorder/jamcontroller.h
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
/******************************************************************************\
|
||||||
|
* Copyright (c) 2020
|
||||||
|
*
|
||||||
|
* Author(s):
|
||||||
|
* pljones
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "jamrecorder.h"
|
||||||
|
|
||||||
|
namespace recorder {
|
||||||
|
|
||||||
|
class CJamController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CJamController();
|
||||||
|
|
||||||
|
bool GetRecorderInitialised() { return bRecorderInitialised; }
|
||||||
|
QString GetRecorderErrMsg() { return strRecorderErrMsg; }
|
||||||
|
bool GetRecordingEnabled() { return bEnableRecording; }
|
||||||
|
void RequestNewRecording();
|
||||||
|
void SetEnableRecording ( bool bNewEnableRecording, bool isRunning );
|
||||||
|
QString GetRecordingDir() { return strRecordingDir; }
|
||||||
|
void SetRecordingDir ( QString newRecordingDir,
|
||||||
|
int iServerFrameSizeSamples );
|
||||||
|
ERecorderState GetRecorderState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CServer* pServer;
|
||||||
|
|
||||||
|
bool bRecorderInitialised;
|
||||||
|
bool bEnableRecording;
|
||||||
|
QString strRecordingDir;
|
||||||
|
QThread* pthJamRecorder;
|
||||||
|
|
||||||
|
CJamRecorder* pJamRecorder;
|
||||||
|
QString strRecorderErrMsg;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void RestartRecorder();
|
||||||
|
void StopRecorder();
|
||||||
|
void RecordingSessionStarted ( QString sessionDir );
|
||||||
|
void EndRecorderThread();
|
||||||
|
void Stopped();
|
||||||
|
void ClientDisconnected ( int iChID );
|
||||||
|
void AudioFrame ( const int iChID,
|
||||||
|
const QString stChName,
|
||||||
|
const CHostAddress RecHostAddr,
|
||||||
|
const int iNumAudChan,
|
||||||
|
const CVector<int16_t> vecsData );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(int16_t)
|
41
src/recorder/jamrecorder.cpp
Executable file → Normal file
41
src/recorder/jamrecorder.cpp
Executable file → Normal file
|
@ -304,8 +304,7 @@ QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString
|
||||||
* @param server Server object emiting signals
|
* @param server Server object emiting signals
|
||||||
* @return QString::null on success else the failure reason
|
* @return QString::null on success else the failure reason
|
||||||
*/
|
*/
|
||||||
QString CJamRecorder::Init( const CServer* server,
|
QString CJamRecorder::Init()
|
||||||
const int _iServerFrameSizeSamples )
|
|
||||||
{
|
{
|
||||||
QString errmsg = QString::null;
|
QString errmsg = QString::null;
|
||||||
QFileInfo fi ( recordBaseDir.absolutePath() );
|
QFileInfo fi ( recordBaseDir.absolutePath() );
|
||||||
|
@ -314,51 +313,31 @@ QString CJamRecorder::Init( const CServer* server,
|
||||||
if ( !fi.exists() && !QDir().mkpath ( recordBaseDir.absolutePath() ) )
|
if ( !fi.exists() && !QDir().mkpath ( recordBaseDir.absolutePath() ) )
|
||||||
{
|
{
|
||||||
errmsg = recordBaseDir.absolutePath() + " does not exist but could not be created";
|
errmsg = recordBaseDir.absolutePath() + " does not exist but could not be created";
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
|
||||||
qCritical() << errmsg;
|
qCritical() << errmsg;
|
||||||
|
#endif
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
if (!fi.isDir())
|
if (!fi.isDir())
|
||||||
{
|
{
|
||||||
errmsg = recordBaseDir.absolutePath() + " exists but is not a directory";
|
errmsg = recordBaseDir.absolutePath() + " exists but is not a directory";
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
|
||||||
qCritical() << errmsg;
|
qCritical() << errmsg;
|
||||||
|
#endif
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
if (!fi.isWritable())
|
if (!fi.isWritable())
|
||||||
{
|
{
|
||||||
errmsg = recordBaseDir.absolutePath() + " is a directory but cannot be written to";
|
errmsg = recordBaseDir.absolutePath() + " is a directory but cannot be written to";
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
||||||
|
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
|
||||||
qCritical() << errmsg;
|
qCritical() << errmsg;
|
||||||
|
#endif
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ),
|
|
||||||
this, SLOT( OnTriggerSession() ),
|
|
||||||
Qt::ConnectionType::QueuedConnection );
|
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( StopRecorder() ),
|
|
||||||
this, SLOT( OnEnd() ),
|
|
||||||
Qt::ConnectionType::QueuedConnection );
|
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( EndRecorderThread() ),
|
|
||||||
this, SLOT( OnAboutToQuit() ) );
|
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( Stopped() ),
|
|
||||||
this, SLOT( OnEnd() ),
|
|
||||||
Qt::ConnectionType::QueuedConnection );
|
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( ClientDisconnected ( int ) ),
|
|
||||||
this, SLOT( OnDisconnected ( int ) ),
|
|
||||||
Qt::ConnectionType::QueuedConnection );
|
|
||||||
|
|
||||||
qRegisterMetaType<CVector<int16_t>> ( "CVector<int16_t>" );
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( AudioFrame( const int, const QString, const CHostAddress, const int, const CVector<int16_t> ) ),
|
|
||||||
this, SLOT( OnFrame (const int, const QString, const CHostAddress, const int, const CVector<int16_t> ) ),
|
|
||||||
Qt::ConnectionType::QueuedConnection );
|
|
||||||
|
|
||||||
QObject::connect( QCoreApplication::instance(), SIGNAL ( aboutToQuit() ),
|
|
||||||
this, SLOT( OnAboutToQuit() ) );
|
|
||||||
|
|
||||||
iServerFrameSizeSamples = _iServerFrameSizeSamples;
|
|
||||||
|
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/recorder/jamrecorder.h
Executable file → Normal file
16
src/recorder/jamrecorder.h
Executable file → Normal file
|
@ -139,8 +139,10 @@ class CJamRecorder : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CJamRecorder ( const QString recordingDirName ) :
|
CJamRecorder ( const QString strRecordingBaseDir,
|
||||||
recordBaseDir ( recordingDirName ),
|
const int iServerFrameSizeSamples ) :
|
||||||
|
recordBaseDir ( strRecordingBaseDir ),
|
||||||
|
iServerFrameSizeSamples ( iServerFrameSizeSamples ),
|
||||||
isRecording ( false )
|
isRecording ( false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -149,7 +151,7 @@ public:
|
||||||
* @brief Create recording directory, if necessary, and connect signal handlers
|
* @brief Create recording directory, if necessary, and connect signal handlers
|
||||||
* @param server Server object emiting signals
|
* @param server Server object emiting signals
|
||||||
*/
|
*/
|
||||||
QString Init( const CServer* server, const int _iServerFrameSizeSamples );
|
QString Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SessionDirToReaper Method that allows an RPP file to be recreated
|
* @brief SessionDirToReaper Method that allows an RPP file to be recreated
|
||||||
|
@ -164,15 +166,14 @@ private:
|
||||||
void AudacityLofFromCurrentSession();
|
void AudacityLofFromCurrentSession();
|
||||||
|
|
||||||
QDir recordBaseDir;
|
QDir recordBaseDir;
|
||||||
|
int iServerFrameSizeSamples;
|
||||||
bool isRecording;
|
bool isRecording;
|
||||||
CJamSession* currentSession;
|
CJamSession* currentSession;
|
||||||
int iServerFrameSizeSamples;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void RecordingSessionStarted ( QString sessionDir );
|
void RecordingSessionStarted ( QString sessionDir );
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
/**
|
/**
|
||||||
* @brief Handle last client leaving the server, ends the recording.
|
* @brief Handle last client leaving the server, ends the recording.
|
||||||
*/
|
*/
|
||||||
|
@ -201,6 +202,3 @@ private slots:
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(int16_t)
|
|
||||||
Q_DECLARE_METATYPE(CVector<int16_t>)
|
|
||||||
|
|
168
src/server.cpp
168
src/server.cpp
|
@ -241,7 +241,6 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
Logging ( iMaxDaysHistory ),
|
Logging ( iMaxDaysHistory ),
|
||||||
iFrameCount ( 0 ),
|
iFrameCount ( 0 ),
|
||||||
bWriteStatusHTMLFile ( false ),
|
bWriteStatusHTMLFile ( false ),
|
||||||
bRecorderInitialised ( false ),
|
|
||||||
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
|
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
|
||||||
ServerListManager ( iPortNumber,
|
ServerListManager ( iPortNumber,
|
||||||
strCentralServer,
|
strCentralServer,
|
||||||
|
@ -404,6 +403,9 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
QString().number( static_cast<int> ( iPortNumber ) ) );
|
QString().number( static_cast<int> ( iPortNumber ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jam recorder needs the frame size
|
||||||
|
JamController.SetRecordingDir ( strRecordingDirName, iServerFrameSizeSamples );
|
||||||
|
|
||||||
// manage welcome message: if the welcome message is a valid link to a local
|
// manage welcome message: if the welcome message is a valid link to a local
|
||||||
// file, the content of that file is used as the welcome message (#361)
|
// file, the content of that file is used as the welcome message (#361)
|
||||||
strWelcomeMessage = strNewWelcomeMessage; // first copy text, may be overwritten
|
strWelcomeMessage = strNewWelcomeMessage; // first copy text, may be overwritten
|
||||||
|
@ -473,6 +475,28 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged,
|
QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged,
|
||||||
this, &CServer::SvrRegStatusChanged );
|
this, &CServer::SvrRegStatusChanged );
|
||||||
|
|
||||||
|
QObject::connect ( &JamController, &recorder::CJamController::RestartRecorder,
|
||||||
|
this, &CServer::RestartRecorder );
|
||||||
|
|
||||||
|
QObject::connect ( &JamController, &recorder::CJamController::StopRecorder,
|
||||||
|
this, &CServer::StopRecorder );
|
||||||
|
|
||||||
|
QObject::connect ( &JamController, &recorder::CJamController::RecordingSessionStarted,
|
||||||
|
this, &CServer::RecordingSessionStarted );
|
||||||
|
|
||||||
|
QObject::connect ( &JamController, &recorder::CJamController::EndRecorderThread,
|
||||||
|
this, &CServer::EndRecorderThread );
|
||||||
|
|
||||||
|
QObject::connect( this, &CServer::Stopped,
|
||||||
|
&JamController, &recorder::CJamController::Stopped );
|
||||||
|
|
||||||
|
QObject::connect( this, &CServer::ClientDisconnected,
|
||||||
|
&JamController, &recorder::CJamController::ClientDisconnected );
|
||||||
|
|
||||||
|
qRegisterMetaType<CVector<int16_t>> ( "CVector<int16_t>" );
|
||||||
|
QObject::connect( this, &CServer::AudioFrame,
|
||||||
|
&JamController, &recorder::CJamController::AudioFrame );
|
||||||
|
|
||||||
QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
this, &CServer::OnAboutToQuit );
|
this, &CServer::OnAboutToQuit );
|
||||||
|
|
||||||
|
@ -626,7 +650,7 @@ void CServer::OnNewConnection ( int iChID,
|
||||||
vecChannels[iChID].CreateVersionAndOSMes();
|
vecChannels[iChID].CreateVersionAndOSMes();
|
||||||
|
|
||||||
// send recording state message on connection
|
// send recording state message on connection
|
||||||
vecChannels[iChID].CreateRecorderStateMes ( GetRecorderState() );
|
vecChannels[iChID].CreateRecorderStateMes ( JamController.GetRecorderState() );
|
||||||
|
|
||||||
// reset the conversion buffers
|
// reset the conversion buffers
|
||||||
DoubleFrameSizeConvBufIn[iChID].Reset();
|
DoubleFrameSizeConvBufIn[iChID].Reset();
|
||||||
|
@ -718,7 +742,7 @@ void CServer::OnHandledSignal ( int sigNum )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
SetEnableRecording ( !bEnableRecording );
|
SetEnableRecording ( !JamController.GetRecordingEnabled() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
|
@ -904,7 +928,7 @@ static CTimingMeas JitterMeas ( 1000, "test2.dat" ); JitterMeas.Measure(); // TE
|
||||||
// and emit the client disconnected signal
|
// and emit the client disconnected signal
|
||||||
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
|
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
|
||||||
{
|
{
|
||||||
if ( bEnableRecording )
|
if ( JamController.GetRecordingEnabled() )
|
||||||
{
|
{
|
||||||
emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
|
emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
|
||||||
}
|
}
|
||||||
|
@ -989,7 +1013,7 @@ static CTimingMeas JitterMeas ( 1000, "test2.dat" ); JitterMeas.Measure(); // TE
|
||||||
const int iCurNumAudChan = vecNumAudioChannels[i];
|
const int iCurNumAudChan = vecNumAudioChannels[i];
|
||||||
|
|
||||||
// export the audio data for recording purpose
|
// export the audio data for recording purpose
|
||||||
if ( bEnableRecording )
|
if ( JamController.GetRecordingEnabled() )
|
||||||
{
|
{
|
||||||
emit AudioFrame ( iCurChanID,
|
emit AudioFrame ( iCurChanID,
|
||||||
vecChannels[iCurChanID].GetName(),
|
vecChannels[iCurChanID].GetName(),
|
||||||
|
@ -1324,42 +1348,6 @@ void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::CreateAndSendRecorderStateForAllConChannels()
|
|
||||||
{
|
|
||||||
// get recorder state
|
|
||||||
ERecorderState eRecorderState = GetRecorderState();
|
|
||||||
|
|
||||||
// now send recorder state to all connected clients
|
|
||||||
for ( int i = 0; i < iMaxNumChannels; i++ )
|
|
||||||
{
|
|
||||||
if ( vecChannels[i].IsConnected() )
|
|
||||||
{
|
|
||||||
// send message
|
|
||||||
vecChannels[i].CreateRecorderStateMes ( eRecorderState );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERecorderState CServer::GetRecorderState()
|
|
||||||
{
|
|
||||||
// return recorder state
|
|
||||||
if ( bRecorderInitialised )
|
|
||||||
{
|
|
||||||
if ( bEnableRecording )
|
|
||||||
{
|
|
||||||
return RS_RECORDING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return RS_NOT_ENABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return RS_NOT_INITIALISED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CServer::CreateOtherMuteStateChanged ( const int iCurChanID,
|
void CServer::CreateOtherMuteStateChanged ( const int iCurChanID,
|
||||||
const int iOtherChanID,
|
const int iOtherChanID,
|
||||||
const bool bIsMuted )
|
const bool bIsMuted )
|
||||||
|
@ -1541,6 +1529,14 @@ void CServer::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServer::SetEnableRecording ( bool bNewEnableRecording )
|
||||||
|
{
|
||||||
|
JamController.SetEnableRecording ( bNewEnableRecording, IsRunning() );
|
||||||
|
|
||||||
|
// send recording state message - doesn't hurt
|
||||||
|
CreateAndSendRecorderStateForAllConChannels();
|
||||||
|
}
|
||||||
|
|
||||||
void CServer::StartStatusHTMLFileWriting ( const QString& strNewFileName,
|
void CServer::StartStatusHTMLFileWriting ( const QString& strNewFileName,
|
||||||
const QString& strNewServerNameWithPort )
|
const QString& strNewServerNameWithPort )
|
||||||
{
|
{
|
||||||
|
@ -1590,89 +1586,19 @@ void CServer::WriteHTMLChannelList()
|
||||||
streamFileOut << "</ul>" << endl;
|
streamFileOut << "</ul>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::RequestNewRecording()
|
void CServer::CreateAndSendRecorderStateForAllConChannels()
|
||||||
{
|
{
|
||||||
if ( bRecorderInitialised && bEnableRecording )
|
// get recorder state
|
||||||
{
|
ERecorderState eRecorderState = JamController.GetRecorderState();
|
||||||
emit RestartRecorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send recording state message - doesn't hurt
|
// now send recorder state to all connected clients
|
||||||
CreateAndSendRecorderStateForAllConChannels();
|
for ( int i = 0; i < iMaxNumChannels; i++ )
|
||||||
|
{
|
||||||
|
if ( vecChannels[i].IsConnected() )
|
||||||
|
{
|
||||||
|
// send message
|
||||||
|
vecChannels[i].CreateRecorderStateMes ( eRecorderState );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::SetEnableRecording ( bool bNewEnableRecording )
|
|
||||||
{
|
|
||||||
if ( bRecorderInitialised )
|
|
||||||
{
|
|
||||||
// note that this block executes regardless of whether
|
|
||||||
// what appears to be a change is being applied, to ensure
|
|
||||||
// the requested state is the result
|
|
||||||
bEnableRecording = bNewEnableRecording;
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
|
|
||||||
// TODO we should use the ConsoleWriterFactory() instead of qInfo()
|
|
||||||
qInfo() << "Recording state" << ( bEnableRecording ? "enabled" : "disabled" );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !bEnableRecording )
|
|
||||||
{
|
|
||||||
emit StopRecorder();
|
|
||||||
}
|
|
||||||
else if ( !IsRunning() )
|
|
||||||
{
|
|
||||||
// This dirty hack is for the GUI. It doesn't care.
|
|
||||||
emit StopRecorder();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send recording state message
|
|
||||||
CreateAndSendRecorderStateForAllConChannels();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CServer::SetRecordingDir ( QString newRecordingDir )
|
|
||||||
{
|
|
||||||
if ( bRecorderInitialised )
|
|
||||||
{
|
|
||||||
// We have a thread and we want to start a new one.
|
|
||||||
// We only want one running.
|
|
||||||
// This could take time, unfortunately.
|
|
||||||
// Hopefully changing recording directory will NOT happen during a long jam...
|
|
||||||
emit EndRecorderThread();
|
|
||||||
thJamRecorder.wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !newRecordingDir.isEmpty() )
|
|
||||||
{
|
|
||||||
pJamRecorder = new recorder::CJamRecorder ( newRecordingDir );
|
|
||||||
strRecorderErrMsg = pJamRecorder->Init ( this, iServerFrameSizeSamples );
|
|
||||||
bRecorderInitialised = ( strRecorderErrMsg == QString::null );
|
|
||||||
bEnableRecording = bRecorderInitialised;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This is the only time this is ever true - UI needs to handle it
|
|
||||||
strRecorderErrMsg = QString::null;
|
|
||||||
bRecorderInitialised = false;
|
|
||||||
bEnableRecording = false;
|
|
||||||
}
|
|
||||||
if ( bRecorderInitialised )
|
|
||||||
{
|
|
||||||
strRecordingDir = newRecordingDir;
|
|
||||||
pJamRecorder->moveToThread ( &thJamRecorder );
|
|
||||||
thJamRecorder.setObjectName ( "Jamulus::JamRecorder" );
|
|
||||||
|
|
||||||
QObject::connect ( &thJamRecorder, &QThread::finished,
|
|
||||||
pJamRecorder, &QObject::deleteLater );
|
|
||||||
|
|
||||||
QObject::connect ( pJamRecorder, &recorder::CJamRecorder::RecordingSessionStarted,
|
|
||||||
this, &CServer::RecordingSessionStarted );
|
|
||||||
|
|
||||||
thJamRecorder.start();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strRecordingDir = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
src/server.h
41
src/server.h
|
@ -43,8 +43,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "serverlogging.h"
|
#include "serverlogging.h"
|
||||||
#include "serverlist.h"
|
#include "serverlist.h"
|
||||||
#include "recorder/jamrecorder.h"
|
#include "recorder/jamcontroller.h"
|
||||||
|
|
||||||
|
|
||||||
/* Definitions ****************************************************************/
|
/* Definitions ****************************************************************/
|
||||||
// no valid channel number
|
// no valid channel number
|
||||||
|
@ -199,13 +198,20 @@ public:
|
||||||
CVector<int>& veciJitBufNumFrames,
|
CVector<int>& veciJitBufNumFrames,
|
||||||
CVector<int>& veciNetwFrameSizeFact );
|
CVector<int>& veciNetwFrameSizeFact );
|
||||||
|
|
||||||
bool GetRecorderInitialised() { return bRecorderInitialised; }
|
// Jam recorder ------------------------------------------------------------
|
||||||
QString GetRecorderErrMsg() { return strRecorderErrMsg; }
|
bool GetRecorderInitialised() { return JamController.GetRecorderInitialised(); }
|
||||||
bool GetRecordingEnabled() { return bEnableRecording; }
|
QString GetRecorderErrMsg() { return JamController.GetRecorderErrMsg(); }
|
||||||
void RequestNewRecording();
|
bool GetRecordingEnabled() { return JamController.GetRecordingEnabled(); }
|
||||||
|
void RequestNewRecording() { JamController.RequestNewRecording(); }
|
||||||
|
|
||||||
void SetEnableRecording ( bool bNewEnableRecording );
|
void SetEnableRecording ( bool bNewEnableRecording );
|
||||||
QString GetRecordingDir() { return strRecordingDir; }
|
|
||||||
void SetRecordingDir( QString newRecordingDir );
|
QString GetRecordingDir() { return JamController.GetRecordingDir(); }
|
||||||
|
|
||||||
|
void SetRecordingDir( QString newRecordingDir )
|
||||||
|
{ JamController.SetRecordingDir ( newRecordingDir, iServerFrameSizeSamples ); }
|
||||||
|
|
||||||
|
virtual void CreateAndSendRecorderStateForAllConChannels();
|
||||||
|
|
||||||
// Server list management --------------------------------------------------
|
// Server list management --------------------------------------------------
|
||||||
void UpdateServerList() { ServerListManager.Update(); }
|
void UpdateServerList() { ServerListManager.Update(); }
|
||||||
|
@ -277,10 +283,6 @@ protected:
|
||||||
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
|
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
|
||||||
const QString& strChatText );
|
const QString& strChatText );
|
||||||
|
|
||||||
virtual void CreateAndSendRecorderStateForAllConChannels();
|
|
||||||
|
|
||||||
ERecorderState GetRecorderState();
|
|
||||||
|
|
||||||
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
|
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
|
||||||
const int iOtherChanID,
|
const int iOtherChanID,
|
||||||
const bool bIsMuted );
|
const bool bIsMuted );
|
||||||
|
@ -366,19 +368,14 @@ protected:
|
||||||
QString strServerHTMLFileListName;
|
QString strServerHTMLFileListName;
|
||||||
QString strServerNameWithPort;
|
QString strServerNameWithPort;
|
||||||
|
|
||||||
// recording thread
|
|
||||||
bool bRecorderInitialised;
|
|
||||||
bool bEnableRecording;
|
|
||||||
QThread thJamRecorder;
|
|
||||||
recorder::CJamRecorder* pJamRecorder;
|
|
||||||
QString strRecorderErrMsg;
|
|
||||||
QString strRecordingDir;
|
|
||||||
|
|
||||||
CHighPrecisionTimer HighPrecisionTimer;
|
CHighPrecisionTimer HighPrecisionTimer;
|
||||||
|
|
||||||
// server list
|
// server list
|
||||||
CServerListManager ServerListManager;
|
CServerListManager ServerListManager;
|
||||||
|
|
||||||
|
// jam recorder
|
||||||
|
recorder::CJamController JamController;
|
||||||
|
|
||||||
// GUI settings
|
// GUI settings
|
||||||
bool bAutoRunMinimized;
|
bool bAutoRunMinimized;
|
||||||
|
|
||||||
|
@ -399,6 +396,8 @@ signals:
|
||||||
const CHostAddress RecHostAddr,
|
const CHostAddress RecHostAddr,
|
||||||
const int iNumAudChan,
|
const int iNumAudChan,
|
||||||
const CVector<int16_t> vecsData );
|
const CVector<int16_t> vecsData );
|
||||||
|
|
||||||
|
// pass through from jam controller
|
||||||
void RestartRecorder();
|
void RestartRecorder();
|
||||||
void StopRecorder();
|
void StopRecorder();
|
||||||
void RecordingSessionStarted ( QString sessionDir );
|
void RecordingSessionStarted ( QString sessionDir );
|
||||||
|
@ -480,3 +479,5 @@ public slots:
|
||||||
|
|
||||||
void OnHandledSignal ( int sigNum );
|
void OnHandledSignal ( int sigNum );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(CVector<int16_t>)
|
||||||
|
|
Loading…
Reference in a new issue