2019-04-10 20:00:54 +02:00
|
|
|
/******************************************************************************\
|
2020-06-08 23:20:25 +02:00
|
|
|
* Copyright (c) 2020
|
2019-04-10 20:00:54 +02:00
|
|
|
*
|
|
|
|
* 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.,
|
2020-06-08 22:58:11 +02:00
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
2019-04-10 20:00:54 +02:00
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
2019-07-09 08:52:38 +02:00
|
|
|
#pragma once
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QDateTime>
|
|
|
|
|
|
|
|
#include "../util.h"
|
|
|
|
#include "../channel.h"
|
|
|
|
|
|
|
|
#include "creaperproject.h"
|
|
|
|
#include "cwavestream.h"
|
|
|
|
|
|
|
|
namespace recorder {
|
|
|
|
|
|
|
|
class CJamClientConnection : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
CJamClientConnection(const int _numAudioChannels, const qint64 _startFrame, const qint64 _length, const QString _name, const QString _fileName) :
|
|
|
|
numAudioChannels (_numAudioChannels),
|
|
|
|
startFrame (_startFrame),
|
|
|
|
length (_length),
|
|
|
|
name (_name),
|
|
|
|
fileName (_fileName)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int Format() { return numAudioChannels; }
|
|
|
|
qint64 StartFrame() { return startFrame; }
|
|
|
|
qint64 Length() { return length; }
|
|
|
|
QString Name() { return name; }
|
|
|
|
QString FileName() { return fileName; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
const int numAudioChannels;
|
|
|
|
const qint64 startFrame;
|
|
|
|
const qint64 length;
|
|
|
|
const QString name;
|
|
|
|
const QString fileName;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CJamClient : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
CJamClient(const qint64 frame, const int numChannels, const QString name, const CHostAddress address, const QDir recordBaseDir);
|
|
|
|
|
2020-04-10 19:32:01 +02:00
|
|
|
void Frame(const QString name, const CVector<int16_t>& pcm, int iServerFrameSizeSamples);
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
void Disconnect();
|
|
|
|
|
|
|
|
qint64 StartFrame() { return startFrame; }
|
|
|
|
qint64 FrameCount() { return frameCount; }
|
|
|
|
uint16_t NumAudioChannels() { return numChannels; }
|
|
|
|
QString ClientName() { return name.leftJustified(4, '_', false).replace(QRegExp("[-.:/\\ ]"), "_")
|
|
|
|
.append("-")
|
|
|
|
.append(address.toString(CHostAddress::EStringMode::SM_IP_NO_LAST_BYTE_PORT).replace(QRegExp("[-.:/\\ ]"), "_"))
|
|
|
|
;
|
|
|
|
}
|
|
|
|
CHostAddress ClientAddress() { return address; }
|
|
|
|
|
|
|
|
QString FileName() { return filename; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
const qint64 startFrame;
|
|
|
|
const uint16_t numChannels;
|
|
|
|
QString name;
|
|
|
|
const CHostAddress address;
|
|
|
|
|
|
|
|
QString filename;
|
|
|
|
QFile* wavFile;
|
|
|
|
QDataStream* out;
|
|
|
|
qint64 frameCount = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CJamSession : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
CJamSession(QDir recordBaseDir);
|
|
|
|
|
2020-04-10 19:32:01 +02:00
|
|
|
void Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples);
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
void End();
|
|
|
|
|
|
|
|
QVector<CJamClient*> Clients() { return vecptrJamClients; }
|
|
|
|
|
|
|
|
QMap<QString, QList<STrackItem>> Tracks();
|
|
|
|
|
|
|
|
QString Name() { return sessionDir.dirName(); }
|
|
|
|
|
|
|
|
const QDir SessionDir() { return sessionDir; }
|
|
|
|
|
|
|
|
void DisconnectClient(int iChID);
|
|
|
|
|
2020-04-10 19:32:01 +02:00
|
|
|
static QMap<QString, QList<STrackItem>> TracksFromSessionDir(const QString& name, int iServerFrameSizeSamples);
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
CJamSession();
|
|
|
|
|
|
|
|
const QDir sessionDir;
|
|
|
|
|
|
|
|
qint64 currentFrame;
|
2020-05-22 19:02:50 +02:00
|
|
|
int chIdDisconnected;
|
2019-04-03 19:12:45 +02:00
|
|
|
QVector<CJamClient*> vecptrJamClients;
|
|
|
|
QList<CJamClientConnection*> jamClientConnections;
|
|
|
|
};
|
|
|
|
|
2020-05-08 18:16:27 +02:00
|
|
|
class CJamRecorder : public QObject
|
2019-04-03 19:12:45 +02:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2020-05-08 18:16:27 +02:00
|
|
|
CJamRecorder ( const QString recordingDirName ) :
|
|
|
|
recordBaseDir ( recordingDirName ),
|
|
|
|
isRecording ( false )
|
|
|
|
{
|
|
|
|
}
|
2020-04-10 18:51:37 +02:00
|
|
|
|
2020-05-15 20:50:41 +02:00
|
|
|
/**
|
|
|
|
* @brief Create recording directory, if necessary, and connect signal handlers
|
|
|
|
* @param server Server object emiting signals
|
|
|
|
*/
|
2020-05-30 17:24:52 +02:00
|
|
|
bool Init( const CServer* server, const int _iServerFrameSizeSamples );
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
/**
|
2020-05-15 20:50:41 +02:00
|
|
|
* @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
|
2019-04-03 19:12:45 +02:00
|
|
|
*/
|
2020-05-15 20:50:41 +02:00
|
|
|
static void SessionDirToReaper( QString& strSessionDirName, int serverFrameSizeSamples );
|
|
|
|
|
|
|
|
private:
|
|
|
|
void Start();
|
2020-06-03 23:31:52 +02:00
|
|
|
void ReaperProjectFromCurrentSession();
|
|
|
|
void AudacityLofFromCurrentSession();
|
2020-05-15 20:50:41 +02:00
|
|
|
|
|
|
|
QDir recordBaseDir;
|
|
|
|
|
|
|
|
bool isRecording;
|
|
|
|
CJamSession* currentSession;
|
|
|
|
int iServerFrameSizeSamples;
|
|
|
|
|
|
|
|
QThread* thisThread;
|
|
|
|
|
|
|
|
signals:
|
2020-05-15 23:04:55 +02:00
|
|
|
void RecordingSessionStarted ( QString sessionDir );
|
2019-04-03 19:12:45 +02:00
|
|
|
|
2020-05-15 20:50:41 +02:00
|
|
|
private slots:
|
2019-04-03 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* @brief Raised when last client leaves the server, ending the recording.
|
|
|
|
*/
|
|
|
|
void OnEnd();
|
|
|
|
|
2020-05-15 20:50:41 +02:00
|
|
|
/**
|
|
|
|
* @brief Raised to end one session and start a new one.
|
|
|
|
*/
|
|
|
|
void OnTriggerSession();
|
|
|
|
|
2020-05-08 18:16:27 +02:00
|
|
|
/**
|
|
|
|
* @brief Raised when application is stopping
|
|
|
|
*/
|
|
|
|
void OnAboutToQuit();
|
|
|
|
|
2019-04-03 19:12:45 +02:00
|
|
|
/**
|
|
|
|
* @brief Raised when an existing client leaves the server.
|
|
|
|
* @param iChID channel number of client
|
|
|
|
*/
|
2020-05-08 18:16:27 +02:00
|
|
|
void OnDisconnected ( int iChID );
|
2019-04-03 19:12:45 +02:00
|
|
|
|
|
|
|
/**
|
2020-05-08 18:16:27 +02:00
|
|
|
* @brief Raised when a frame of data is available to process
|
2019-04-03 19:12:45 +02:00
|
|
|
*/
|
2020-05-08 18:16:27 +02:00
|
|
|
void OnFrame ( const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data );
|
2019-04-03 19:12:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(int16_t)
|
|
|
|
Q_DECLARE_METATYPE(CVector<int16_t>)
|