Save the source
This commit is contained in:
parent
b08865c50c
commit
40b699e0a5
4 changed files with 124 additions and 78 deletions
|
@ -302,27 +302,32 @@ QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString
|
||||||
/**
|
/**
|
||||||
* @brief CJamRecorder::Init Create recording directory, if necessary, and connect signal handlers
|
* @brief CJamRecorder::Init Create recording directory, if necessary, and connect signal handlers
|
||||||
* @param server Server object emiting signals
|
* @param server Server object emiting signals
|
||||||
|
* @return QString::null on success else the failure reason
|
||||||
*/
|
*/
|
||||||
bool CJamRecorder::Init( const CServer* server,
|
QString CJamRecorder::Init( const CServer* server,
|
||||||
const int _iServerFrameSizeSamples )
|
const int _iServerFrameSizeSamples )
|
||||||
{
|
{
|
||||||
|
QString errmsg = QString::null;
|
||||||
QFileInfo fi(recordBaseDir.absolutePath());
|
QFileInfo fi(recordBaseDir.absolutePath());
|
||||||
fi.setCaching(false);
|
fi.setCaching(false);
|
||||||
|
|
||||||
if (!fi.exists() && !QDir().mkpath(recordBaseDir.absolutePath()))
|
if (!fi.exists() && !QDir().mkpath(recordBaseDir.absolutePath()))
|
||||||
{
|
{
|
||||||
qCritical() << recordBaseDir.absolutePath() << "does not exist but could not be created";
|
errmsg = recordBaseDir.absolutePath() + " does not exist but could not be created";
|
||||||
return false;
|
qCritical() << errmsg;
|
||||||
|
return errmsg;
|
||||||
}
|
}
|
||||||
if (!fi.isDir())
|
if (!fi.isDir())
|
||||||
{
|
{
|
||||||
qCritical() << recordBaseDir.absolutePath() << "exists but is not a directory";
|
errmsg = recordBaseDir.absolutePath() + " exists but is not a directory";
|
||||||
return false;
|
qCritical() << errmsg;
|
||||||
|
return errmsg;
|
||||||
}
|
}
|
||||||
if (!fi.isWritable())
|
if (!fi.isWritable())
|
||||||
{
|
{
|
||||||
qCritical() << recordBaseDir.absolutePath() << "is a directory but cannot be written to";
|
errmsg = recordBaseDir.absolutePath() + " is a directory but cannot be written to";
|
||||||
return false;
|
qCritical() << errmsg;
|
||||||
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ),
|
QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ),
|
||||||
|
@ -333,6 +338,9 @@ bool CJamRecorder::Init( const CServer* server,
|
||||||
this, SLOT( OnEnd() ),
|
this, SLOT( OnEnd() ),
|
||||||
Qt::ConnectionType::QueuedConnection );
|
Qt::ConnectionType::QueuedConnection );
|
||||||
|
|
||||||
|
QObject::connect( (const QObject *)server, SIGNAL ( EndRecorderThread() ),
|
||||||
|
this, SLOT( OnAboutToQuit() ) );
|
||||||
|
|
||||||
QObject::connect( (const QObject *)server, SIGNAL ( Stopped() ),
|
QObject::connect( (const QObject *)server, SIGNAL ( Stopped() ),
|
||||||
this, SLOT( OnEnd() ),
|
this, SLOT( OnEnd() ),
|
||||||
Qt::ConnectionType::QueuedConnection );
|
Qt::ConnectionType::QueuedConnection );
|
||||||
|
@ -351,11 +359,7 @@ bool CJamRecorder::Init( const CServer* server,
|
||||||
|
|
||||||
iServerFrameSizeSamples = _iServerFrameSizeSamples;
|
iServerFrameSizeSamples = _iServerFrameSizeSamples;
|
||||||
|
|
||||||
thisThread = new QThread();
|
return errmsg;
|
||||||
moveToThread ( thisThread );
|
|
||||||
thisThread->start();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -410,7 +414,7 @@ void CJamRecorder::OnAboutToQuit()
|
||||||
{
|
{
|
||||||
OnEnd();
|
OnEnd();
|
||||||
|
|
||||||
thisThread->exit();
|
QThread::currentThread()->exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJamRecorder::ReaperProjectFromCurrentSession()
|
void CJamRecorder::ReaperProjectFromCurrentSession()
|
||||||
|
|
|
@ -149,7 +149,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
|
||||||
*/
|
*/
|
||||||
bool Init( const CServer* server, const int _iServerFrameSizeSamples );
|
QString Init( const CServer* server, const int _iServerFrameSizeSamples );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SessionDirToReaper Method that allows an RPP file to be recreated
|
* @brief SessionDirToReaper Method that allows an RPP file to be recreated
|
||||||
|
@ -169,35 +169,33 @@ private:
|
||||||
CJamSession* currentSession;
|
CJamSession* currentSession;
|
||||||
int iServerFrameSizeSamples;
|
int iServerFrameSizeSamples;
|
||||||
|
|
||||||
QThread* thisThread;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void RecordingSessionStarted ( QString sessionDir );
|
void RecordingSessionStarted ( QString sessionDir );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/**
|
/**
|
||||||
* @brief Raised when last client leaves the server, ending the recording.
|
* @brief Handle last client leaving the server, ends the recording.
|
||||||
*/
|
*/
|
||||||
void OnEnd();
|
void OnEnd();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raised to end one session and start a new one.
|
* @brief Handle request to end one session and start a new one.
|
||||||
*/
|
*/
|
||||||
void OnTriggerSession();
|
void OnTriggerSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raised when application is stopping
|
* @brief Handle application stopping
|
||||||
*/
|
*/
|
||||||
void OnAboutToQuit();
|
void OnAboutToQuit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raised when an existing client leaves the server.
|
* @brief Handle an existing client leaving the server.
|
||||||
* @param iChID channel number of client
|
* @param iChID channel number of client
|
||||||
*/
|
*/
|
||||||
void OnDisconnected ( int iChID );
|
void OnDisconnected ( int iChID );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Raised when a frame of data is available to process
|
* @brief Handle a frame of data to process
|
||||||
*/
|
*/
|
||||||
void OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data );
|
void OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data );
|
||||||
};
|
};
|
||||||
|
|
139
src/server.cpp
139
src/server.cpp
|
@ -240,10 +240,8 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
Socket ( this, iPortNumber ),
|
Socket ( this, iPortNumber ),
|
||||||
Logging ( iMaxDaysHistory ),
|
Logging ( iMaxDaysHistory ),
|
||||||
iFrameCount ( 0 ),
|
iFrameCount ( 0 ),
|
||||||
JamRecorder ( strRecordingDirName ),
|
|
||||||
bRecorderInitialised ( false ),
|
|
||||||
bEnableRecording ( false ),
|
|
||||||
bWriteStatusHTMLFile ( false ),
|
bWriteStatusHTMLFile ( false ),
|
||||||
|
bRecorderInitialised ( false ),
|
||||||
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
|
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
|
||||||
ServerListManager ( iPortNumber,
|
ServerListManager ( iPortNumber,
|
||||||
strCentralServer,
|
strCentralServer,
|
||||||
|
@ -424,11 +422,7 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
strWelcomeMessage = strWelcomeMessage.left ( MAX_LEN_CHAT_TEXT );
|
strWelcomeMessage = strWelcomeMessage.left ( MAX_LEN_CHAT_TEXT );
|
||||||
|
|
||||||
// enable jam recording (if requested) - kicks off the thread
|
// enable jam recording (if requested) - kicks off the thread
|
||||||
if ( !strRecordingDirName.isEmpty() )
|
SetRecordingDir ( strRecordingDirName );
|
||||||
{
|
|
||||||
bRecorderInitialised = JamRecorder.Init ( this, iServerFrameSizeSamples );
|
|
||||||
SetEnableRecording ( bRecorderInitialised );
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable all channels (for the server all channel must be enabled the
|
// enable all channels (for the server all channel must be enabled the
|
||||||
// entire life time of the software)
|
// entire life time of the software)
|
||||||
|
@ -479,9 +473,6 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged,
|
QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged,
|
||||||
this, &CServer::SvrRegStatusChanged );
|
this, &CServer::SvrRegStatusChanged );
|
||||||
|
|
||||||
QObject::connect( &JamRecorder, &recorder::CJamRecorder::RecordingSessionStarted,
|
|
||||||
this, &CServer::RecordingSessionStarted );
|
|
||||||
|
|
||||||
QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
QObject::connect ( QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
this, &CServer::OnAboutToQuit );
|
this, &CServer::OnAboutToQuit );
|
||||||
|
|
||||||
|
@ -742,46 +733,6 @@ void CServer::OnHandledSignal ( int sigNum )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServer::RequestNewRecording()
|
|
||||||
{
|
|
||||||
if ( bRecorderInitialised && bEnableRecording )
|
|
||||||
{
|
|
||||||
emit RestartRecorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send recording state message - doesn't hurt
|
|
||||||
CreateAndSendRecorderStateForAllConChannels();
|
|
||||||
}
|
|
||||||
|
|
||||||
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::Start()
|
void CServer::Start()
|
||||||
{
|
{
|
||||||
// only start if not already running
|
// only start if not already running
|
||||||
|
@ -1639,6 +1590,92 @@ void CServer::WriteHTMLChannelList()
|
||||||
streamFileOut << "</ul>" << endl;
|
streamFileOut << "</ul>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServer::RequestNewRecording()
|
||||||
|
{
|
||||||
|
if ( bRecorderInitialised && bEnableRecording )
|
||||||
|
{
|
||||||
|
emit RestartRecorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send recording state message - doesn't hurt
|
||||||
|
CreateAndSendRecorderStateForAllConChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CServer::customEvent ( QEvent* pEvent )
|
void CServer::customEvent ( QEvent* pEvent )
|
||||||
{
|
{
|
||||||
if ( pEvent->type() == QEvent::User + 11 )
|
if ( pEvent->type() == QEvent::User + 11 )
|
||||||
|
|
17
src/server.h
17
src/server.h
|
@ -200,9 +200,12 @@ public:
|
||||||
CVector<int>& veciNetwFrameSizeFact );
|
CVector<int>& veciNetwFrameSizeFact );
|
||||||
|
|
||||||
bool GetRecorderInitialised() { return bRecorderInitialised; }
|
bool GetRecorderInitialised() { return bRecorderInitialised; }
|
||||||
|
QString GetRecorderErrMsg() { return strRecorderErrMsg; }
|
||||||
bool GetRecordingEnabled() { return bEnableRecording; }
|
bool GetRecordingEnabled() { return bEnableRecording; }
|
||||||
void RequestNewRecording();
|
void RequestNewRecording();
|
||||||
void SetEnableRecording ( bool bNewEnableRecording );
|
void SetEnableRecording ( bool bNewEnableRecording );
|
||||||
|
QString GetRecordingDir() { return strRecordingDir; }
|
||||||
|
void SetRecordingDir( QString newRecordingDir );
|
||||||
|
|
||||||
// Server list management --------------------------------------------------
|
// Server list management --------------------------------------------------
|
||||||
void UpdateServerList() { ServerListManager.Update(); }
|
void UpdateServerList() { ServerListManager.Update(); }
|
||||||
|
@ -358,16 +361,19 @@ protected:
|
||||||
// channel level update frame interval counter
|
// channel level update frame interval counter
|
||||||
int iFrameCount;
|
int iFrameCount;
|
||||||
|
|
||||||
// recording thread
|
|
||||||
recorder::CJamRecorder JamRecorder;
|
|
||||||
bool bRecorderInitialised;
|
|
||||||
bool bEnableRecording;
|
|
||||||
|
|
||||||
// HTML file server status
|
// HTML file server status
|
||||||
bool bWriteStatusHTMLFile;
|
bool bWriteStatusHTMLFile;
|
||||||
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
|
||||||
|
@ -396,6 +402,7 @@ signals:
|
||||||
void RestartRecorder();
|
void RestartRecorder();
|
||||||
void StopRecorder();
|
void StopRecorder();
|
||||||
void RecordingSessionStarted ( QString sessionDir );
|
void RecordingSessionStarted ( QString sessionDir );
|
||||||
|
void EndRecorderThread();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnTimer();
|
void OnTimer();
|
||||||
|
|
Loading…
Reference in a new issue