Merge pull request #51 from pljones/multiple-frame-sizes-in-recorder

Multiple frame sizes in recorder
This commit is contained in:
corrados 2020-04-10 19:43:04 +02:00 committed by GitHub
commit 82935c8cd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 34 deletions

View File

@ -55,7 +55,7 @@ using namespace recorder;
* @param trackItem the details of where the item is in the track, along with the RIFF WAVE filename
* @param iid the sequential item id
*/
CReaperItem::CReaperItem(const QString& name, const STrackItem& trackItem, const qint32& iid)
CReaperItem::CReaperItem(const QString& name, const STrackItem& trackItem, const qint32& iid, int frameSize)
{
QString wavName = trackItem.fileName; // assume RPP in same location...
@ -64,8 +64,8 @@ CReaperItem::CReaperItem(const QString& name, const STrackItem& trackItem, const
sOut << " <ITEM " << endl;
sOut << " FADEIN 0 0 0 0 0 0" << endl;
sOut << " FADEOUT 0 0 0 0 0 0" << endl;
sOut << " POSITION " << secondsAt48K(trackItem.startFrame) << endl;
sOut << " LENGTH " << secondsAt48K(trackItem.frameCount) << endl;
sOut << " POSITION " << secondsAt48K( trackItem.startFrame, frameSize ) << endl;
sOut << " LENGTH " << secondsAt48K( trackItem.frameCount, frameSize ) << endl;
sOut << " IGUID " << iguid.toString() << endl;
sOut << " IID " << iid << endl;
sOut << " NAME " << name << endl;
@ -86,7 +86,7 @@ CReaperItem::CReaperItem(const QString& name, const STrackItem& trackItem, const
* @param iid the sequential track id
* @param items the list of items in the track
*/
CReaperTrack::CReaperTrack(QString name, qint32& iid, QList<STrackItem> items)
CReaperTrack::CReaperTrack(QString name, qint32& iid, QList<STrackItem> items, int frameSize)
{
QTextStream sOut(&out);
@ -96,7 +96,7 @@ CReaperTrack::CReaperTrack(QString name, qint32& iid, QList<STrackItem> items)
int ino = 1;
foreach (auto item, items) {
sOut << CReaperItem(name + " (" + QString::number(ino) + ")", item, iid).toString() << endl;
sOut << CReaperItem(name + " (" + QString::number(ino) + ")", item, iid, frameSize).toString() << endl;
ino++;
iid++;
}
@ -109,7 +109,7 @@ CReaperTrack::CReaperTrack(QString name, qint32& iid, QList<STrackItem> items)
* @brief CReaperProject::CReaperProject Construct a Reaper RPP "<REAPER_PROJECT>" for a given list of tracks
* @param tracks the list of tracks
*/
CReaperProject::CReaperProject(QMap<QString, QList<STrackItem>> tracks)
CReaperProject::CReaperProject(QMap<QString, QList<STrackItem>> tracks, int frameSize)
{
QTextStream sOut(&out);
@ -121,7 +121,7 @@ CReaperProject::CReaperProject(QMap<QString, QList<STrackItem>> tracks)
qint32 iid = 0;
foreach(auto trackName, tracks.keys())
{
sOut << CReaperTrack(trackName, iid, tracks[trackName]).toString() << endl;
sOut << CReaperTrack(trackName, iid, tracks[trackName], frameSize).toString() << endl;
}
sOut << ">";

View File

@ -52,7 +52,7 @@ class CReaperItem : public QObject
Q_OBJECT
public:
CReaperItem(const QString& name, const STrackItem& trackItem, const qint32& iid);
CReaperItem( const QString& name, const STrackItem& trackItem, const qint32& iid, int frameSize );
QString toString() { return out; }
private:
@ -60,7 +60,11 @@ private:
const QUuid guid = QUuid::createUuid();
QString out;
inline QString secondsAt48K(const qint64 frames) { return QString::number(static_cast<double>(frames * SYSTEM_FRAME_SIZE_SAMPLES) / 48000, 'f', 14); }
inline QString secondsAt48K( const qint64 frames,
const int frameSize )
{
return QString::number( static_cast<double>( frames * frameSize ) / 48000, 'f', 14 );
}
};
class CReaperTrack : public QObject
@ -68,7 +72,7 @@ class CReaperTrack : public QObject
Q_OBJECT
public:
CReaperTrack(QString name, qint32 &iid, QList<STrackItem> items);
CReaperTrack( QString name, qint32 &iid, QList<STrackItem> items, int frameSize );
QString toString() { return out; }
private:
@ -81,7 +85,7 @@ class CReaperProject : public QObject
Q_OBJECT
public:
CReaperProject(QMap<QString, QList<STrackItem> > tracks);
CReaperProject( QMap<QString, QList<STrackItem> > tracks, int frameSize );
QString toString() { return out; }
private:

View File

@ -70,11 +70,11 @@ CJamClient::CJamClient(const qint64 frame, const int _numChannels, const QString
* @param _name The client's current name
* @param pcm The PCM data
*/
void CJamClient::Frame(const QString _name, const CVector<int16_t>& pcm)
void CJamClient::Frame(const QString _name, const CVector<int16_t>& pcm, int iServerFrameSizeSamples)
{
name = _name;
for(int i = 0; i < numChannels * SYSTEM_FRAME_SIZE_SAMPLES; i++)
for(int i = 0; i < numChannels * iServerFrameSizeSamples; i++)
{
*out << pcm[i];
}
@ -165,7 +165,7 @@ void CJamSession::DisconnectClient(int iChID)
*
* Also manages the overall current frame counter for the session.
*/
void CJamSession::Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data)
void CJamSession::Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples)
{
if (vecptrJamClients[iChID] == nullptr)
{
@ -193,7 +193,7 @@ void CJamSession::Frame(const int iChID, const QString name, const CHostAddress
return;
}
vecptrJamClients[iChID]->Frame(name, data);
vecptrJamClients[iChID]->Frame(name, data, iServerFrameSizeSamples);
// If _any_ connected client frame steps past currentFrame, increase currentFrame
if (vecptrJamClients[iChID]->StartFrame() + vecptrJamClients[iChID]->FrameCount() > currentFrame)
@ -250,7 +250,7 @@ QMap<QString, QList<STrackItem>> CJamSession::Tracks()
* @param sessionDirName the directory name to scan
* @return a map of (latest) client name to connection items
*/
QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString& sessionDirName)
QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString& sessionDirName, int iServerFrameSizeSamples)
{
QMap<QString, QList<STrackItem>> tracks;
@ -272,7 +272,7 @@ QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString
}
QFileInfo fiEntry(sessionDir.absoluteFilePath(entry));
qint64 length = fiEntry.size() / numChannels.toInt() / SYSTEM_FRAME_SIZE_SAMPLES;
qint64 length = fiEntry.size() / numChannels.toInt() / iServerFrameSizeSamples;
STrackItem track (
numChannels.toInt(),
@ -295,7 +295,8 @@ QMap<QString, QList<STrackItem>> CJamSession::TracksFromSessionDir(const QString
* @brief CJamRecorder::Init Create recording directory, if necessary, and connect signal handlers
* @param server Server object emiting signals
*/
void CJamRecorder::Init(const CServer* server)
void CJamRecorder::Init( const CServer* server,
const int _iServerFrameSizeSamples )
{
QFileInfo fi(recordBaseDir.absolutePath());
fi.setCaching(false);
@ -325,6 +326,8 @@ void CJamRecorder::Init(const CServer* server)
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);
iServerFrameSizeSamples = _iServerFrameSizeSamples;
}
/**
@ -353,15 +356,15 @@ void CJamRecorder::OnEnd()
if (fi.exists())
{
tsConsole << "CJamRecorder::OnEnd() - " << fi.absolutePath() << " exists and will not be overwritten." << endl;
qWarning() << "CJamRecorder::OnEnd():" << fi.absolutePath() << "exists and will not be overwritten.";
}
else
{
QFile outf (reaperProjectFileName);
outf.open(QFile::WriteOnly);
QTextStream out(&outf);
out << CReaperProject(currentSession->Tracks()).toString() << endl;
tsConsole << "Session RPP: " << reaperProjectFileName << endl;
out << CReaperProject( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << endl;
qDebug() << "Session RPP:" << reaperProjectFileName;
}
delete currentSession;
@ -373,7 +376,7 @@ void CJamRecorder::OnEnd()
* @brief CJamRecorder::SessionDirToReaper Replica of CJamRecorder::OnEnd() but using the directory contents to construct the CReaperProject object
* @param strSessionDirName
*/
void CJamRecorder::SessionDirToReaper(QString& strSessionDirName)
void CJamRecorder::SessionDirToReaper(QString& strSessionDirName, int serverFrameSizeSamples)
{
const QFileInfo fiSessionDir(QDir::cleanPath(strSessionDirName));
if (!fiSessionDir.exists() || !fiSessionDir.isDir())
@ -395,9 +398,9 @@ void CJamRecorder::SessionDirToReaper(QString& strSessionDirName)
}
QTextStream out(&outf);
out << CReaperProject(CJamSession::TracksFromSessionDir(fiSessionDir.absoluteFilePath())).toString() << endl;
out << CReaperProject( CJamSession::TracksFromSessionDir( fiSessionDir.absoluteFilePath(), serverFrameSizeSamples ), serverFrameSizeSamples ).toString() << endl;
(*(new ConsoleWriterFactory())->get()) << "Session RPP: " << reaperProjectFileName << endl;
qDebug() << "Session RPP:" << reaperProjectFileName;
}
/**
@ -408,11 +411,11 @@ void CJamRecorder::OnDisconnected(int iChID)
{
if (!isRecording)
{
tsConsole << "CJamRecorder::OnDisconnected: channel " << iChID << " disconnected but not recording" << endl;
qWarning() << "CJamRecorder::OnDisconnected: channel" << iChID << "disconnected but not recording";
}
if (currentSession == nullptr)
{
tsConsole << "CJamRecorder::OnDisconnected: channel " << iChID << " disconnected but no currentSession" << endl;
qWarning() << "CJamRecorder::OnDisconnected: channel" << iChID << "disconnected but no currentSession";
return;
}
currentSession->DisconnectClient(iChID);
@ -436,5 +439,5 @@ void CJamRecorder::OnFrame(const int iChID, const QString name, const CHostAddre
OnStart();
}
currentSession->Frame(iChID, name, address, numAudioChannels, data);
currentSession->Frame( iChID, name, address, numAudioChannels, data, iServerFrameSizeSamples );
}

View File

@ -70,7 +70,7 @@ class CJamClient : public QObject
public:
CJamClient(const qint64 frame, const int numChannels, const QString name, const CHostAddress address, const QDir recordBaseDir);
void Frame(const QString name, const CVector<int16_t>& pcm);
void Frame(const QString name, const CVector<int16_t>& pcm, int iServerFrameSizeSamples);
void Disconnect();
@ -106,7 +106,7 @@ public:
CJamSession(QDir recordBaseDir);
void Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data);
void Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples);
void End();
@ -120,7 +120,7 @@ public:
void DisconnectClient(int iChID);
static QMap<QString, QList<STrackItem>> TracksFromSessionDir(const QString& name);
static QMap<QString, QList<STrackItem>> TracksFromSessionDir(const QString& name, int iServerFrameSizeSamples);
private:
CJamSession();
@ -139,9 +139,10 @@ class CJamRecorder : public QThread
public:
CJamRecorder(const QString recordingDirName) :
recordBaseDir (recordingDirName), isRecording (false) {}
void Init(const CServer* server);
static void SessionDirToReaper(QString& strSessionDirName);
void Init( const CServer* server, const int _iServerFrameSizeSamples );
static void SessionDirToReaper( QString& strSessionDirName, int serverFrameSizeSamples );
public slots:
/**
@ -170,7 +171,7 @@ private:
bool isRecording;
CJamSession* currentSession;
QTextStream& tsConsole = *((new ConsoleWriterFactory())->get());
int iServerFrameSizeSamples;
};
}

View File

@ -397,7 +397,7 @@ CServer::CServer ( const int iNewMaxNumChan,
// Enable jam recording (if requested)
if ( bEnableRecording )
{
JamRecorder.Init ( this );
JamRecorder.Init ( this, iServerFrameSizeSamples );
JamRecorder.start();
}