diff --git a/ChangeLog b/ChangeLog index 7ee4c8d7..77efbdde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,7 +21,7 @@ - bug fix: on MacOS declare an activity to ensure the process doesn't get throttled by OS level Nap, Sleep, and Thread Priority systems, coded by AronVietti (#23) - +- add Audacity "list of files" writer to jam recorder, by pljones (#315) diff --git a/src/recorder/creaperproject.h b/src/recorder/creaperproject.h index be6f190a..1fbb57ea 100755 --- a/src/recorder/creaperproject.h +++ b/src/recorder/creaperproject.h @@ -32,21 +32,6 @@ namespace recorder { -struct STrackItem -{ - STrackItem(int numAudioChannels, qint64 startFrame, qint64 frameCount, QString fileName) : - numAudioChannels(numAudioChannels), - startFrame(startFrame), - frameCount(frameCount), - fileName(fileName) - { - } - int numAudioChannels; - qint64 startFrame; - qint64 frameCount; - QString fileName; -}; - class CReaperItem : public QObject { Q_OBJECT @@ -59,12 +44,6 @@ private: const QUuid iguid = QUuid::createUuid(); const QUuid guid = QUuid::createUuid(); QString out; - - inline QString secondsAt48K( const qint64 frames, - const int frameSize ) - { - return QString::number( static_cast( frames * frameSize ) / 48000, 'f', 14 ); - } }; class CReaperTrack : public QObject diff --git a/src/recorder/cwavestream.h b/src/recorder/cwavestream.h index f3ceab66..6d8f1ec8 100755 --- a/src/recorder/cwavestream.h +++ b/src/recorder/cwavestream.h @@ -27,6 +27,31 @@ namespace recorder { +inline QString secondsAt48K( const qint64 frames, + const int frameSize ) +{ + return QString::number( static_cast( frames * frameSize ) / 48000, 'f', 14 ); +} + +struct STrackItem +{ + STrackItem ( int numAudioChannels, + qint64 startFrame, + qint64 frameCount, + QString fileName ) : + numAudioChannels ( numAudioChannels ), + startFrame ( startFrame ), + frameCount ( frameCount ), + fileName ( fileName ) + { + } + + int numAudioChannels; + qint64 startFrame; + qint64 frameCount; + QString fileName; +}; + class HdrRiff { public: diff --git a/src/recorder/jamrecorder.cpp b/src/recorder/jamrecorder.cpp index d8dc9833..40e10321 100755 --- a/src/recorder/jamrecorder.cpp +++ b/src/recorder/jamrecorder.cpp @@ -381,35 +381,15 @@ void CJamRecorder::OnEnd() isRecording = false; currentSession->End(); - QString reaperProjectFileName = currentSession->SessionDir().filePath(currentSession->Name().append(".rpp")); - const QFileInfo fi(reaperProjectFileName); - - if (fi.exists()) - { - qWarning() << "CJamRecorder::OnEnd():" << fi.absolutePath() << "exists and will not be overwritten."; - reaperProjectFileName = QString::Null(); - } - else - { - QFile outf (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(); - } - } + ReaperProjectFromCurrentSession(); + AudacityLofFromCurrentSession(); delete currentSession; currentSession = nullptr; } } + /** * @brief CJamRecorder::OnTriggerSession End one session and start a new one */ @@ -432,6 +412,66 @@ void CJamRecorder::OnAboutToQuit() thisThread->exit(); } +void CJamRecorder::ReaperProjectFromCurrentSession() +{ + QString reaperProjectFileName = currentSession->SessionDir().filePath(currentSession->Name().append(".rpp")); + const QFileInfo fi(reaperProjectFileName); + + if (fi.exists()) + { + qWarning() << "CJamRecorder::ReaperProjectFromCurrentSession():" << fi.absolutePath() << "exists and will not be overwritten."; + } + else + { + QFile outf (reaperProjectFileName); + if ( outf.open(QFile::WriteOnly) ) + { + QTextStream out(&outf); + out << CReaperProject( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << endl; + qDebug() << "Session RPP:" << reaperProjectFileName; + } + else + { + qWarning() << "CJamRecorder::ReaperProjectFromCurrentSession():" << fi.absolutePath() << "could not be created, no RPP written."; + } + } +} + +void CJamRecorder::AudacityLofFromCurrentSession() +{ + QString audacityLofFileName = currentSession->SessionDir().filePath(currentSession->Name().append(".lof")); + const QFileInfo fi(audacityLofFileName); + + if (fi.exists()) + { + qWarning() << "CJamRecorder::AudacityLofFromCurrentSession():" << fi.absolutePath() << "exists and will not be overwritten."; + } + else + { + QFile outf (audacityLofFileName); + if ( outf.open(QFile::WriteOnly) ) + { + QTextStream sOut(&outf); + + foreach ( auto trackName, currentSession->Tracks().keys() ) + { + foreach ( auto item, currentSession->Tracks()[trackName] ) { + QFileInfo fi ( item.fileName ); + sOut << "file " << '"' << fi.fileName() << '"'; + sOut << " offset " << secondsAt48K( item.startFrame, iServerFrameSizeSamples ) << endl; + } + } + + sOut.flush(); + qDebug() << "Session LOF:" << audacityLofFileName; + } + else + { + qWarning() << "CJamRecorder::AudacityLofFromCurrentSession():" << fi.absolutePath() << "could not be created, no LOF written."; + } + } +} + /** * @brief CJamRecorder::SessionDirToReaper Replica of CJamRecorder::OnEnd() but using the directory contents to construct the CReaperProject object * @param strSessionDirName diff --git a/src/recorder/jamrecorder.h b/src/recorder/jamrecorder.h index 0dec305f..b0e2651c 100755 --- a/src/recorder/jamrecorder.h +++ b/src/recorder/jamrecorder.h @@ -159,6 +159,8 @@ public: private: void Start(); + void ReaperProjectFromCurrentSession(); + void AudacityLofFromCurrentSession(); QDir recordBaseDir;