Save the source

This commit is contained in:
Peter L Jones 2020-06-20 17:04:06 +01:00
parent b08865c50c
commit 40b699e0a5
4 changed files with 124 additions and 78 deletions

View file

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

View file

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

View file

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

View file

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