Skip to content

Commit f246b96

Browse files
committed
Refactored the way audio input file patterns are handled, fixing some defaulting behaviour, and adding support for custom default patterns and locations to EngineBehaviour
1 parent a7de37c commit f246b96

File tree

3 files changed

+76
-48
lines changed

3 files changed

+76
-48
lines changed

modules/tracktion_engine/playback/devices/tracktion_WaveInputDevice.cpp

Lines changed: 67 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -64,56 +64,70 @@ static const char* datePattern = "%date%";
6464
static const char* timePattern = "%time%";
6565
static const char* takePattern = "%take%";
6666

67-
static juce::String expandPatterns (Edit& ed, const juce::String& s, Track* track, int take)
67+
static juce::String expandPatterns (Edit& ed, juce::String s, Track* track, int take)
6868
{
69-
juce::String editName (TRANS("Unknown"));
70-
juce::String trackName (TRANS("Unknown"));
71-
auto projDir = juce::File::getCurrentWorkingDirectory().getFullPathName();
69+
{
70+
auto editName = ed.getName();
7271

73-
editName = juce::File::createLegalFileName (ed.getName());
72+
if (editName.isEmpty())
73+
s = s.replace (juce::String (editPattern) + "_", {}, true);
7474

75-
if (track != nullptr)
76-
trackName = juce::File::createLegalFileName (track->getName());
75+
s = s.replace (editPattern, editName, true);
76+
}
7777

78-
if (auto proj = getProjectForEdit (ed))
7978
{
80-
projDir = proj->getDirectoryForMedia (ProjectItem::Category::recorded).getFullPathName();
79+
juce::String trackName;
80+
81+
if (track != nullptr)
82+
trackName = track->getName();
83+
84+
if (trackName.isEmpty())
85+
s = s.replace (juce::String (trackPattern) + "_", {}, true);
86+
87+
s = s.replace (trackPattern, trackName, true);
8188
}
82-
else if (ed.editFileRetriever)
89+
8390
{
84-
auto editFile = ed.editFileRetriever();
91+
auto projDir = ed.engine.getEngineBehaviour().getDefaultFolderForAudioRecordings (ed).getFullPathName();
8592

86-
if (editFile != juce::File() && editFile.getParentDirectory().isDirectory())
87-
projDir = editFile.getParentDirectory().getFullPathName();
93+
if (auto proj = getProjectForEdit (ed))
94+
{
95+
projDir = proj->getDirectoryForMedia (ProjectItem::Category::recorded).getFullPathName();
96+
}
97+
else if (ed.editFileRetriever)
98+
{
99+
auto editFile = ed.editFileRetriever();
100+
101+
if (editFile != juce::File() && editFile.getParentDirectory().isDirectory())
102+
projDir = editFile.getParentDirectory().getFullPathName();
103+
}
104+
105+
s = s.replace (projDirPattern, projDir, true);
88106
}
89107

90108
auto now = juce::Time::getCurrentTime();
91109

92-
juce::String date;
110+
{
111+
juce::String date;
93112

94-
date << now.getDayOfMonth()
95-
<< juce::Time::getMonthName (now.getMonth(), true)
96-
<< now.getYear();
113+
date << now.getDayOfMonth()
114+
<< juce::Time::getMonthName (now.getMonth(), true)
115+
<< now.getYear();
97116

98-
auto time = juce::String::formatted ("%d%02d%02d",
99-
now.getHours(),
100-
now.getMinutes(),
101-
now.getSeconds());
117+
s = s.replace (datePattern, date, true);
118+
}
102119

103-
juce::String s2;
120+
s = s.replace (timePattern, juce::String::formatted ("%d%02d%02d",
121+
now.getHours(),
122+
now.getMinutes(),
123+
now.getSeconds()), true);
104124

105125
if (! s.contains (takePattern))
106-
s2 = s + "_" + juce::String (takePattern);
107-
else
108-
s2 = s;
109-
110-
return juce::File::createLegalPathName (s2.replace (projDirPattern, projDir, true)
111-
.replace (editPattern, editName, true)
112-
.replace (trackPattern, trackName, true)
113-
.replace (datePattern, date, true)
114-
.replace (timePattern, time, true)
115-
.replace (takePattern, juce::String (take), true)
116-
.trim());
126+
s += "_" + juce::String (takePattern);
127+
128+
s = s.replace (takePattern, juce::String (take), true);
129+
130+
return juce::File::createLegalPathName (s.trim());
117131
}
118132

119133

@@ -345,7 +359,7 @@ class WaveInputDeviceInstance : public InputDeviceInstance
345359
return tl::unexpected (TRANS("The current project is read-only, so new clips can't be recorded into it!"));
346360

347361
auto format = getFormatToUse();
348-
const auto res = getDestinationRecordingFile (edit, targetID, *format, getWaveInput().filenameMask);
362+
const auto res = getDestinationRecordingFile (edit, targetID, *format, getWaveInput().getFilenameMask());
349363

350364
if (! res)
351365
return tl::unexpected (res.error());
@@ -1002,7 +1016,7 @@ class WaveInputDeviceInstance : public InputDeviceInstance
10021016
return nullptr;
10031017

10041018
auto format = getFormatToUse();
1005-
const auto res = getDestinationRecordingFile (edit, dstTrack->itemID, *format, getWaveInput().filenameMask);
1019+
const auto res = getDestinationRecordingFile (edit, dstTrack->itemID, *format, getWaveInput().getFilenameMask());
10061020

10071021
if (! res)
10081022
return {};
@@ -1419,7 +1433,7 @@ void WaveInputDevice::closeDevice()
14191433

14201434
void WaveInputDevice::loadProps()
14211435
{
1422-
filenameMask = getDefaultMask();
1436+
filenameMask = {};
14231437
inputGainDb = 0.0f;
14241438
monitorMode = MonitorMode::automatic;
14251439
outputFormat = engine.getAudioFileFormatManager().getDefaultFormat()->getFormatName();
@@ -1434,6 +1448,10 @@ void WaveInputDevice::loadProps()
14341448
if (auto n = engine.getPropertyStorage().getXmlPropertyItem (SettingID::wavein, propName))
14351449
{
14361450
filenameMask = n->getStringAttribute ("filename", filenameMask);
1451+
1452+
if (filenameMask == engine.getEngineBehaviour().getDefaultAudioRecordingFilePattern())
1453+
filenameMask = {};
1454+
14371455
inputGainDb = (float) n->getDoubleAttribute ("gainDb", inputGainDb);
14381456
monitorMode = magic_enum::enum_cast<MonitorMode> (n->getStringAttribute ("monitorMode").toStdString()).value_or (MonitorMode::automatic);
14391457

@@ -1458,7 +1476,9 @@ void WaveInputDevice::saveProps()
14581476
{
14591477
juce::XmlElement n ("SETTINGS");
14601478

1461-
n.setAttribute ("filename", filenameMask);
1479+
if (filenameMask.isNotEmpty())
1480+
n.setAttribute ("filename", filenameMask);
1481+
14621482
n.setAttribute ("gainDb", inputGainDb);
14631483
n.setAttribute ("monitorMode", std::string (magic_enum::enum_name (monitorMode)));
14641484
n.setAttribute ("format", outputFormat);
@@ -1534,30 +1554,31 @@ void WaveInputDevice::setRecordTriggerDb (float newDB)
15341554
}
15351555
}
15361556

1537-
juce::String WaveInputDevice::getDefaultMask()
1557+
juce::String WaveInputDevice::getFilenameMask() const
15381558
{
1539-
juce::String defaultFile;
1540-
defaultFile << projDirPattern << juce::File::getSeparatorChar() << editPattern << '_'
1541-
<< trackPattern<< '_' << TRANS("Take") << '_' << takePattern;
1559+
if (filenameMask.isNotEmpty())
1560+
return filenameMask;
15421561

1543-
return defaultFile;
1562+
return engine.getEngineBehaviour().getDefaultAudioRecordingFilePattern();
15441563
}
15451564

15461565
void WaveInputDevice::setFilenameMask (const juce::String& newMask)
15471566
{
15481567
if (filenameMask != newMask)
15491568
{
1550-
filenameMask = newMask.isNotEmpty() ? newMask
1551-
: getDefaultMask();
1569+
filenameMask = newMask;
1570+
1571+
if (filenameMask == engine.getEngineBehaviour().getDefaultAudioRecordingFilePattern())
1572+
filenameMask = {};
1573+
15521574
changed();
15531575
saveProps();
15541576
}
15551577
}
15561578

15571579
void WaveInputDevice::setFilenameMaskToDefault()
15581580
{
1559-
if (getDefaultMask() != filenameMask)
1560-
setFilenameMask ({});
1581+
setFilenameMask ({});
15611582
}
15621583

15631584
void WaveInputDevice::setBitDepth (int newDepth)

modules/tracktion_engine/playback/devices/tracktion_WaveInputDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ class WaveInputDevice : public InputDevice
4747
float getInputGainDb() const { return inputGainDb; }
4848
void setRecordTriggerDb (float);
4949
float getRecordTriggerDb() const { return recordTriggerDb; }
50+
51+
juce::String getFilenameMask() const;
5052
void setFilenameMask (const juce::String&);
51-
juce::String getFilenameMask() const { return filenameMask; }
5253
void setFilenameMaskToDefault();
53-
static juce::String getDefaultMask();
5454

5555
void setOutputFormat (const juce::String&);
5656
juce::String getOutputFormat() const { return outputFormat; }

modules/tracktion_engine/utilities/tracktion_EngineBehaviour.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ class EngineBehaviour
136136
/// 0 = normal, 1 = high, 2 = realtime
137137
virtual void setProcessPriority (int /*level*/) {}
138138

139+
/// If this is implemented, this folder will be used for the %project% pattern when
140+
/// parsing an audio input device's target filename.
141+
virtual juce::File getDefaultFolderForAudioRecordings (Edit&) { return {}; }
142+
143+
/// The default filename that will be used for audio input devices if not overridden
144+
virtual juce::String getDefaultAudioRecordingFilePattern() { return "%projectdir%/%edit%_%track%_Take_%take%"; }
145+
139146
//==============================================================================
140147
// Model-related options
141148

0 commit comments

Comments
 (0)