Merge pull request #391 from pljones/feature/228-refactor-jam-recorder

Feature/228 refactor jam recorder
This commit is contained in:
Volker Fischer 2020-06-28 14:47:52 +02:00 committed by GitHub
commit c94d450868
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 364 additions and 164 deletions

View file

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

0
src/recorder/creaperproject.h Executable file → Normal file
View file

0
src/recorder/cwavestream.cpp Executable file → Normal file
View file

0
src/recorder/cwavestream.h Executable file → Normal file
View file

171
src/recorder/jamcontroller.cpp Executable file
View 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
View 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)

69
src/recorder/jamrecorder.cpp Executable file → Normal file
View file

@ -302,60 +302,43 @@ 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 int _iServerFrameSizeSamples )
{ {
QFileInfo fi(recordBaseDir.absolutePath()); QString errmsg = QString::null;
fi.setCaching(false); QFileInfo fi ( recordBaseDir.absolutePath() );
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; #if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
qCritical() << errmsg;
#endif
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; #if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
qCritical() << errmsg;
#endif
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; #if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
// TODO we should use the ConsoleWriterFactory() instead of qCritical()
qCritical() << errmsg;
#endif
return errmsg;
} }
QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ), return errmsg;
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 ( 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;
thisThread = new QThread();
moveToThread ( thisThread );
thisThread->start();
return true;
} }
/** /**
@ -410,7 +393,7 @@ void CJamRecorder::OnAboutToQuit()
{ {
OnEnd(); OnEnd();
thisThread->exit(); QThread::currentThread()->exit();
} }
void CJamRecorder::ReaperProjectFromCurrentSession() void CJamRecorder::ReaperProjectFromCurrentSession()

32
src/recorder/jamrecorder.h Executable file → Normal file
View file

@ -139,9 +139,11 @@ class CJamRecorder : public QObject
Q_OBJECT Q_OBJECT
public: public:
CJamRecorder ( const QString recordingDirName ) : CJamRecorder ( const QString strRecordingBaseDir,
recordBaseDir ( recordingDirName ), const int iServerFrameSizeSamples ) :
isRecording ( false ) recordBaseDir ( strRecordingBaseDir ),
iServerFrameSizeSamples ( iServerFrameSizeSamples ),
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
*/ */
bool 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
@ -163,46 +165,40 @@ private:
void ReaperProjectFromCurrentSession(); void ReaperProjectFromCurrentSession();
void AudacityLofFromCurrentSession(); void AudacityLofFromCurrentSession();
QDir recordBaseDir; QDir recordBaseDir;
int iServerFrameSizeSamples;
bool isRecording; bool isRecording;
CJamSession* currentSession; CJamSession* currentSession;
int iServerFrameSizeSamples;
QThread* thisThread;
signals: signals:
void RecordingSessionStarted ( QString sessionDir ); void RecordingSessionStarted ( QString sessionDir );
private slots: public 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 );
}; };
} }
Q_DECLARE_METATYPE(int16_t)
Q_DECLARE_METATYPE(CVector<int16_t>)

View file

@ -240,9 +240,6 @@ 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 ),
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ), HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
ServerListManager ( iPortNumber, ServerListManager ( iPortNumber,
@ -406,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
@ -424,11 +424,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 +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( &JamRecorder, &recorder::CJamRecorder::RecordingSessionStarted, 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 ); 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 );
@ -635,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();
@ -727,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:
@ -742,46 +757,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
@ -953,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?
} }
@ -1038,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(),
@ -1373,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 )
@ -1590,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 )
{ {
@ -1639,6 +1586,22 @@ void CServer::WriteHTMLChannelList()
streamFileOut << "</ul>" << endl; streamFileOut << "</ul>" << endl;
} }
void CServer::CreateAndSendRecorderStateForAllConChannels()
{
// get recorder state
ERecorderState eRecorderState = JamController.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 );
}
}
}
void CServer::customEvent ( QEvent* pEvent ) void CServer::customEvent ( QEvent* pEvent )
{ {
if ( pEvent->type() == QEvent::User + 11 ) if ( pEvent->type() == QEvent::User + 11 )

View file

@ -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,11 +198,21 @@ public:
CVector<int>& veciJitBufNumFrames, CVector<int>& veciJitBufNumFrames,
CVector<int>& veciNetwFrameSizeFact ); CVector<int>& veciNetwFrameSizeFact );
bool GetRecorderInitialised() { return bRecorderInitialised; } // Jam recorder ------------------------------------------------------------
bool GetRecordingEnabled() { return bEnableRecording; } bool GetRecorderInitialised() { return JamController.GetRecorderInitialised(); }
void RequestNewRecording(); QString GetRecorderErrMsg() { return JamController.GetRecorderErrMsg(); }
bool GetRecordingEnabled() { return JamController.GetRecordingEnabled(); }
void RequestNewRecording() { JamController.RequestNewRecording(); }
void SetEnableRecording ( bool bNewEnableRecording ); void SetEnableRecording ( bool bNewEnableRecording );
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(); }
@ -274,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 );
@ -358,11 +363,6 @@ 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;
@ -373,6 +373,9 @@ protected:
// server list // server list
CServerListManager ServerListManager; CServerListManager ServerListManager;
// jam recorder
recorder::CJamController JamController;
// GUI settings // GUI settings
bool bAutoRunMinimized; bool bAutoRunMinimized;
@ -393,9 +396,12 @@ 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 );
void EndRecorderThread();
public slots: public slots:
void OnTimer(); void OnTimer();
@ -473,3 +479,5 @@ public slots:
void OnHandledSignal ( int sigNum ); void OnHandledSignal ( int sigNum );
}; };
Q_DECLARE_METATYPE(CVector<int16_t>)