Merge pull request #229 from pljones/feature/170-allow-triggered-recording-cuts

Feature/170 allow triggered recording cuts
This commit is contained in:
Volker Fischer 2020-05-16 09:20:47 +02:00 committed by GitHub
commit e529baeb94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 120 additions and 35 deletions

View file

@ -314,6 +314,10 @@ void CJamRecorder::Init( const CServer* server,
throw std::runtime_error( (recordBaseDir.absolutePath() + " is a directory but cannot be written to").toStdString() );
}
QObject::connect( (const QObject *)server, SIGNAL ( RestartRecorder() ),
this, SLOT( OnTriggerSession() ),
Qt::ConnectionType::QueuedConnection );
QObject::connect( (const QObject *)server, SIGNAL ( Stopped() ),
this, SLOT( OnEnd() ),
Qt::ConnectionType::QueuedConnection );
@ -322,13 +326,12 @@ void CJamRecorder::Init( const CServer* server,
this, SLOT( OnDisconnected ( int ) ),
Qt::ConnectionType::QueuedConnection );
qRegisterMetaType<CVector<int16_t>>();
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() ),
QObject::connect( QCoreApplication::instance(), SIGNAL ( aboutToQuit() ),
this, SLOT( OnAboutToQuit() ) );
iServerFrameSizeSamples = _iServerFrameSizeSamples;
@ -338,11 +341,10 @@ void CJamRecorder::Init( const CServer* server,
thisThread->start();
}
/**
* @brief CJamRecorder::OnStart Start up tasks when the first client connects
* @brief CJamRecorder::Start Start up tasks for a new session
*/
void CJamRecorder::OnStart() {
void CJamRecorder::Start() {
// Ensure any previous cleaning up has been done.
OnEnd();
@ -350,11 +352,17 @@ void CJamRecorder::OnStart() {
isRecording = true;
}
/**
* @brief CJamRecorder::OnEnd Finalise the recording and emit the Reaper RPP file
*
* Emits RecordingSessionEnded with the Reaper project file name,
* or null if was not recording or a problem occurs
*/
void CJamRecorder::OnEnd()
{
QString reaperProjectFileName = QString::Null();
if ( isRecording )
{
isRecording = false;
@ -366,21 +374,46 @@ void CJamRecorder::OnEnd()
if (fi.exists())
{
qWarning() << "CJamRecorder::OnEnd():" << fi.absolutePath() << "exists and will not be overwritten.";
reaperProjectFileName = QString::Null();
}
else
{
QFile outf (reaperProjectFileName);
outf.open(QFile::WriteOnly);
QTextStream out(&outf);
out << CReaperProject( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << endl;
qDebug() << "Session RPP:" << reaperProjectFileName;
if ( outf.open(QFile::WriteOnly) )
{
QTextStream out(&outf);
out << CReaperProject( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << endl;
qDebug() << "Session RPP:" << reaperProjectFileName;
}
else
{
qWarning() << "CJamRecorder::OnEnd():" << fi.absolutePath() << "could not be created, no RPP written.";
reaperProjectFileName = QString::Null();
}
}
delete currentSession;
currentSession = nullptr;
}
emit RecordingSessionEnded ( reaperProjectFileName );
}
/**
* @brief CJamRecorder::OnTriggerSession End one session and start a new one
*/
void CJamRecorder::OnTriggerSession()
{
// This should magically get everything right...
if ( isRecording )
{
Start();
}
}
/**
* @brief CJamRecorder::OnAboutToQuit End any recording and exit thread
*/
void CJamRecorder::OnAboutToQuit()
{
OnEnd();
@ -452,7 +485,7 @@ void CJamRecorder::OnFrame(const int iChID, const QString name, const CHostAddre
// Make sure we are ready
if ( !isRecording )
{
OnStart();
Start();
}
currentSession->Frame( iChID, name, address, numAudioChannels, data, iServerFrameSizeSamples );

View file

@ -143,21 +143,44 @@ public:
{
}
/**
* @brief Create recording directory, if necessary, and connect signal handlers
* @param server Server object emiting signals
*/
void Init( const CServer* server, const int _iServerFrameSizeSamples );
/**
* @brief SessionDirToReaper Method that allows an RPP file to be recreated
* @param strSessionDirName Where the session wave files are
* @param serverFrameSizeSamples What the server frame size was for the session
*/
static void SessionDirToReaper( QString& strSessionDirName, int serverFrameSizeSamples );
public slots:
/**
* @brief Raised when first client joins the server, triggering a new recording.
*/
void OnStart();
private:
void Start();
QDir recordBaseDir;
bool isRecording;
CJamSession* currentSession;
int iServerFrameSizeSamples;
QThread* thisThread;
signals:
void RecordingSessionEnded ( QString sessionDir );
private slots:
/**
* @brief Raised when last client leaves the server, ending the recording.
*/
void OnEnd();
/**
* @brief Raised to end one session and start a new one.
*/
void OnTriggerSession();
/**
* @brief Raised when application is stopping
*/
@ -173,15 +196,6 @@ public slots:
* @brief Raised when a frame of data is available to process
*/
void OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data );
private:
QDir recordBaseDir;
bool isRecording;
CJamSession* currentSession;
int iServerFrameSizeSamples;
QThread* thisThread;
};
}

View file

@ -471,8 +471,8 @@ CServer::CServer ( const int iNewMaxNumChan,
this, SLOT ( OnAboutToQuit() ) );
QObject::connect ( pSignalHandler,
SIGNAL ( ShutdownSignal ( int ) ),
this, SLOT ( OnShutdown ( int ) ) );
SIGNAL ( HandledSignal ( int ) ),
this, SLOT ( OnHandledSignal ( int ) ) );
connectChannelSignalsToServerSlots<MAX_NUM_CHANNELS>();
@ -665,10 +665,35 @@ void CServer::OnAboutToQuit()
}
}
void CServer::OnShutdown ( int )
void CServer::OnHandledSignal ( int sigNum )
{
// This should trigger OnAboutToQuit
#ifdef _WIN32
// Windows does not actually get OnHandledSignal triggered
QCoreApplication::instance()->exit();
Q_UNUSED ( sigNum )
#else
switch ( sigNum )
{
case SIGUSR1:
RequestNewRecording();
break;
case SIGINT:
case SIGTERM:
// This should trigger OnAboutToQuit
QCoreApplication::instance()->exit();
break;
default:
break;
}
#endif
}
void CServer::Start()
@ -1565,3 +1590,11 @@ void CServer::CreateLevelsForAllConChannels ( const int i
vecLevelsOut[j] = static_cast<uint16_t> ( ceil ( dCurSigLevel ) );
}
}
void CServer::RequestNewRecording()
{
if ( bEnableRecording )
{
emit RestartRecorder();
}
}

View file

@ -285,6 +285,8 @@ protected:
const CVector<CVector<int16_t> > vecvecsData,
CVector<uint16_t>& vecLevelsOut );
void RequestNewRecording();
// do not use the vector class since CChannel does not have appropriate
// copy constructor/operator
CChannel vecChannels[MAX_NUM_CHANNELS];
@ -364,6 +366,7 @@ signals:
const CHostAddress RecHostAddr,
const int iNumAudChan,
const CVector<int16_t> vecsData );
void RestartRecorder();
public slots:
void OnTimer();
@ -441,5 +444,5 @@ public slots:
void OnAboutToQuit();
void OnShutdown ( int );
void OnHandledSignal ( int sigNum );
};

View file

@ -75,7 +75,7 @@ CSignalHandler* CSignalHandler::getSingletonP() { return singleton; }
bool CSignalHandler::emitSignal ( int sigNum )
{
return QMetaObject::invokeMethod( singleton, "ShutdownSignal", Qt::QueuedConnection, Q_ARG( int, sigNum ) );
return QMetaObject::invokeMethod( singleton, "HandledSignal", Qt::QueuedConnection, Q_ARG( int, sigNum ) );
}
#ifndef _WIN32
@ -124,11 +124,11 @@ QReadWriteLock* CSignalWin::getLock() const
return &lock;
}
BOOL WINAPI CSignalWin::signalHandler ( _In_ DWORD sigNum )
BOOL WINAPI CSignalWin::signalHandler ( _In_ DWORD )
{
auto self = getSelf<CSignalWin>();
QReadLocker lock ( self->getLock() );
return self->pSignalHandler->emitSignal ( static_cast<int>( sigNum ) );
return self->pSignalHandler->emitSignal ( -1 );
}
#else
@ -145,12 +145,14 @@ CSignalUnix::CSignalUnix ( CSignalHandler* nPSignalHandler ) :
socketNotifier->setEnabled ( true );
setSignalHandled ( SIGUSR1, true );
setSignalHandled ( SIGINT, true );
setSignalHandled ( SIGTERM, true );
}
}
CSignalUnix::~CSignalUnix() {
setSignalHandled ( SIGUSR1, false );
setSignalHandled ( SIGINT, false );
setSignalHandled ( SIGTERM, false );
}

View file

@ -104,7 +104,7 @@ public slots:
#endif
signals:
void ShutdownSignal ( int sigNum );
void HandledSignal ( int sigNum );
private:
QScopedPointer<CSignalBase> pSignalBase;
@ -153,7 +153,7 @@ public:
private:
mutable QReadWriteLock lock;
static BOOL WINAPI signalHandler ( _In_ DWORD sigNum );
static BOOL WINAPI signalHandler ( _In_ DWORD );
};
#else