Merge pull request #229 from pljones/feature/170-allow-triggered-recording-cuts
Feature/170 allow triggered recording cuts
This commit is contained in:
commit
e529baeb94
6 changed files with 120 additions and 35 deletions
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue