54#define DESC XO("AUP project files (*.aup)")
98 std::optional<LibFileFormats::AcidizerTags>& outAcidTags)
override;
104 void SetStreamUsage(wxInt32 WXUNUSED(StreamID),
bool WXUNUSED(Use))
override;
115 using stack = std::vector<struct node>;
142 const FilePath &blockFilename = wxEmptyString,
143 const FilePath &audioFilename = wxEmptyString,
165 #define field(n, t) bool have##n; t n
177 field(selectionformat, wxString);
178 field(audiotimeformat, wxString);
179 field(frequencyformat, wxString);
180 field(bandwidthformat, wxString);
208 std::map<wxString, std::pair<FilePath, std::shared_ptr<SampleBlock>>>;
223 const std::string_view& lhs,
const std::string_view& rhsLower)
225 if (lhs.length() != rhsLower.length())
228 for (
size_t i = 0; i < lhs.length(); ++i)
229 if (std::tolower(lhs[i]) != rhsLower[i])
240 sizeof(
long long) >=
sizeof(uint64_t) &&
241 sizeof(long) >=
sizeof(uint32_t),
242 "Assumptions about sizes in XMLValueChecker calls are invalid!");
251 return wxT(
"legacyaup");
262 auto handle = std::make_unique<AUPImportFileHandle>(fileName,
project);
275 "AUP", std::make_unique<AUPImportPlugin>()
307 Tags* tags, std::optional<LibFileFormats::AcidizerTags>&)
318 auto oldNumTracks =
tracks.Size();
319 auto cleanup =
finally([
this, &
tracks, oldNumTracks]{
322 while (oldNumTracks <
tracks.Size())
327 bool isDirty = history.GetDirty() || !
tracks.empty();
374 if (fi.blockFile.empty())
381 fi.len, fi.format, fi.origin, fi.channel))
392 pClip->UpdateEnvelopeTrackLen();
396 [&](
const auto& errorMessage) {
SetError(errorMessage); },
403"This feature is not supported in Audacity versions past 3.3.3.\n"
404"These stereo tracks have been split into mono tracks.\n"
405"Please verify that everything works as intended before saving.")
450 formats.SetFrequencySelectionFormatName(
mProjectAttrs.frequencyformat);
455 formats.SetBandwidthSelectionFormatName(
mProjectAttrs.bandwidthformat);
519 int numRead = ff.Read(buf,
sizeof(buf));
523 buf[
sizeof(buf) - 1] =
'\0';
525 if (!wxStrncmp(buf,
wxT(
"AudacityProject"), 15))
528 XO(
"This project was saved by Audacity version 1.0 or earlier. The format has\n"
529 "changed and this version of Audacity is unable to import the project.\n\n"
530 "Use a version of Audacity prior to v3.0.0 to upgrade the project and then\n"
531 "you may import it with this version of Audacity."));
535 if (wxStrncmp(buf,
"<?xml", 5) == 0 &&
536 (wxStrstr(buf,
"<audacityproject") ||
537 wxStrstr(buf,
"<project") ))
595 bool success =
false;
669 return SetError(
XO(
"Internal error in importer...tag not recognized"));
682 int requiredTags = 0;
686 auto attr = pair.first;
687 auto value = pair.second;
691#define set(f, v) (mProjectAttrs.have ## f = true, mProjectAttrs.f = v)
697 if (!value.TryGet(lValue) || (lValue < 0))
699 return SetError(
XO(
"Invalid project 'vpos' attribute."));
702 set(vpos, (
int) lValue);
704 else if (attr ==
"h")
706 if (!value.TryGet(dValue))
708 return SetError(
XO(
"Invalid project 'h' attribute."));
713 else if (attr ==
"zoom")
715 if (!value.TryGet(dValue) || (dValue < 0.0))
717 return SetError(
XO(
"Invalid project 'zoom' attribute."));
723 else if (attr ==
"sel0")
725 if (!value.TryGet(dValue))
727 return SetError(
XO(
"Invalid project 'sel0' attribute."));
732 else if (attr ==
"sel1")
734 if (!value.TryGet(dValue))
736 return SetError(
XO(
"Invalid project 'sel1' attribute."));
741 else if (attr ==
"selLow")
743 if (!value.TryGet(dValue) || (dValue < 0.0))
745 return SetError(
XO(
"Invalid project 'selLow' attribute."));
750 else if (attr ==
"selHigh")
752 if (!value.TryGet(dValue) || (dValue < 0.0))
754 return SetError(
XO(
"Invalid project 'selHigh' attribute."));
757 set(selHigh, dValue);
759 else if (attr ==
"version")
764 else if (attr ==
"audacityversion")
768 else if (attr ==
"projname")
773 wxString altname =
mProjDir.GetName() +
wxT(
"_data");
774 mProjDir.SetFullName(wxEmptyString);
776 wxString projName = value.ToWString();
780 if (!projName.empty())
794 if (projName.empty())
805 if (projName.empty())
808 XO(
"Couldn't find the project data folder: \"%s\"").
Format(value.ToWString()));
814 size_t cnt = wxDir::GetAllFiles(
mProjDir.GetFullPath(),
818 for (
const auto &
fn : files)
823 else if (attr ==
"rate")
825 if (!value.TryGet(dValue) || (dValue < 0.0))
827 return SetError(
XO(
"Invalid project 'selLow' attribute."));
833 else if (attr ==
"snapto")
835 set(snapto, (value.ToWString() ==
"on" ?
true :
false));
838 else if (attr ==
"selectionformat")
840 set(selectionformat, value.ToWString());
843 else if (attr ==
"frequencyformat")
845 set(frequencyformat, value.ToWString());
848 else if (attr ==
"bandwidthformat")
850 set(bandwidthformat, value.ToWString());
855 if (requiredTags < 3)
880 XO(
"MIDI tracks found in project file, but this build of Audacity does not include MIDI support, bypassing track."));
894 XO(
"The active project already has a time track and one was encountered in the project being imported, bypassing imported time track."));
926 auto attr = pair.first;
927 auto value = pair.second;
933 else if (attr ==
"track")
935 n =
wxT(
"TRACKNUMBER");
939 n = std::string(attr);
943 v = value.ToWString();
965 auto attr = pair.first;
966 auto value = pair.second;
970 n = value.ToWString();
972 else if (attr ==
"value")
974 v = value.ToWString();
978 if (n ==
wxT(
"id3v2"))
1013 const auto pInterval = wavetrack->
CreateClip();
1101 for (
auto pair :
mAttrs) {
1102 auto attr = pair.first;
1103 auto value = pair.second;
1105 if (attr ==
"maxsamples")
1109 if (!value.TryGet(llvalue) || (llvalue < 0))
1111 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1117 if ((llvalue < 1024) || (llvalue > 64 * 1024 * 1024))
1119 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1122 else if (attr ==
"sampleformat")
1128 return SetError(
XO(
"Invalid sequence 'sampleformat' attribute."));
1133 pSequence->ConvertToSampleFormat(
mFormat);
1135 else if (attr ==
"numsamples")
1139 if (!value.TryGet(llvalue) || (llvalue < 0))
1141 return SetError(
XO(
"Invalid sequence 'numsamples' attribute."));
1155 auto attr = pair.first;
1156 auto value = pair.second;
1158 if (attr ==
"start")
1162 if (!value.TryGet(llvalue) || (llvalue < 0))
1164 return SetError(
XO(
"Unable to parse the waveblock 'start' attribute"));
1181 auto attr = pair.first;
1182 auto value = pair.second;
1187 const wxString strValue = value.ToWString();
1193 filename =
mFileMap[strValue].first;
1197 SetWarning(
XO(
"Missing project file %s\n\nInserting silence instead.")
1202 else if (attr ==
"len")
1205 if (!value.TryGet(lValue) || (lValue <= 0))
1207 return SetError(
XO(
"Missing or invalid simpleblockfile 'len' attribute."));
1228 auto attr = pair.first;
1229 auto value = pair.second;
1234 if (!value.TryGet(lValue) || !(lValue > 0))
1236 return SetError(
XO(
"Missing or invalid silentblockfile 'len' attribute."));
1252 wxString summaryFilename;
1253 wxFileName filename;
1261 auto attr = pair.first;
1262 auto value = pair.second;
1266 const wxString strValue = value.ToWString();
1270 filename.Assign(strValue);
1275 filename.Assign(
mProjDir.GetPath(), strValue);
1281 SetWarning(
XO(
"Missing alias file %s\n\nInserting silence instead.")
1287 summaryFilename = value.ToWString();
1292 if (!value.TryGet(llValue) || (llValue < 0))
1294 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliasstart' attribute."));
1302 if (!value.TryGet(lValue) || (lValue <= 0))
1304 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1312 if (!value.TryGet(lValue) || (lValue < 0))
1314 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1323 if (filename.IsOk())
1325 summaryFilename, filename.GetFullPath(),
1336 if (
mAttrs.empty() ||
mAttrs.front().first !=
"filename")
1339 wxString strAttr =
mAttrs.front().second.ToWString();
1345 fileName0.SetExt({});
1347 fileName0.GetFullPath() +
wxT(
"_data"), strAttr };
1349 strAttr = fileName.GetFullPath();
1352 wxLogWarning(
wxT(
"Could not import file: %s"), strAttr);
1358 auto oldNumTracks =
tracks.Size();
1359 Track *pLast =
nullptr;
1360 if (oldNumTracks > 0)
1361 pLast = *
tracks.rbegin();
1369 if (oldNumTracks ==
tracks.Size())
1374 bool bSuccess =
true;
1376 auto range =
tracks.Any();
1378 range = range.StartingWith(pLast);
1384 for (
auto pTrack: range.Filter<
WaveTrack>()) {
1392 for (
auto pair :
mAttrs) {
1393 auto attr = pair.first;
1394 auto value = pair.second;
1395 if (attr ==
"offset" && value.TryGet(dblValue))
1396 pTrack->MoveTo(dblValue);
1451 auto &pBlock =
mFileMap[wxFileNameFromPath(blockFilename)].second;
1454 if (pClip->NChannels() != 1)
1456 pClip->AppendLegacySharedBlock( pBlock );
1463 "Type sf_count_t is too narrow to hold a sampleCount");
1466 memset(&info, 0,
sizeof(info));
1469 SNDFILE *sf =
nullptr;
1470 bool success =
false;
1472#ifndef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1473 const auto uncaughtExceptionsCount = std::uncaught_exceptions();
1476 auto cleanup =
finally([&]
1481 SFCall<int>(sf_close, sf);
1486 SetWarning(
XO(
"Error while processing %s\n\nInserting silence.").
Format(audioFilename));
1490#ifdef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1491 if (!std::uncaught_exception())
1493 if (uncaughtExceptionsCount == std::uncaught_exceptions())
1500 if (!f.Open(audioFilename))
1510 sf = SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE);
1520 if (SFCall<sf_count_t>(sf_seek, sf, origin.
as_long_long(), SEEK_SET) < 0)
1530 int channels = info.channels;
1532 wxASSERT(channels >= 1);
1533 wxASSERT(channel < channels);
1538 size_t framesRead = 0;
1546 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, (
short *) bufptr, cnt);
1550 framesRead = SFCall<sf_count_t>(sf_readf_int, sf, (
int *) bufptr, cnt);
1551 if (framesRead != cnt)
1554 .
Format(cnt, audioFilename));
1562 int *intPtr = (
int *) bufptr;
1563 for (
size_t i = 0; i < framesRead; i++)
1565 intPtr[i] = intPtr[i] >> 8;
1575 short *tmpptr = (
short *) temp.
ptr();
1577 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, tmpptr, cnt);
1578 if (framesRead != cnt)
1581 .
Format(cnt, audioFilename));
1586 for (
size_t i = 0; i < framesRead; i++)
1588 ((
short *)bufptr)[i] = tmpptr[(channels * i) + channel];
1609 float *tmpptr = (
float *) tmpbuf.
ptr();
1611 framesRead = SFCall<sf_count_t>(sf_readf_float, sf, tmpptr, cnt);
1612 if (framesRead != cnt)
1615 .
Format(cnt, audioFilename));
1647 if (pClip->NChannels() != 1)
1649 pBlock = pClip->AppendLegacyNewBlock(bufptr,
format, cnt);
1660 wxLogError(msg.
Debug());
1673 wxLogWarning(msg.
Debug());
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
static Importer::RegisteredImportPlugin registered
std::unique_ptr< ImportFileHandle > ImportHandle
The interface that all file import "plugins" (if you want to call them that) must implement....
std::vector< std::shared_ptr< Track > > TrackHolders
an object holding per-project preferred sample rate
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
std::vector< TranslatableString > TranslatableStrings
std::vector< Attribute > AttributesList
An ImportFileHandle for AUP files (pre-AUP3)
TranslatableString mErrorMsg
bool AddSamples(const FilePath &blockFilename, const FilePath &audioFilename, sampleCount len, sampleFormat format, sampleCount origin=0, int channel=0)
struct AUPImportFileHandle::@141 mProjectAttrs
bool HandlePCMAliasBlockFile(XMLTagHandler *&handle)
unsigned long mNumChannels
AUPImportFileHandle(const FilePath &name, AudacityProject *project)
ByteCount GetFileUncompressedBytes() override
AudacityProject & mProject
bool HandleProject(XMLTagHandler *&handle)
bool HandleSilentBlockFile(XMLTagHandler *&handle)
bool HandleLabel(XMLTagHandler *&handle)
void HandleXMLEndTag(const std::string_view &tag) override
bool HandleWaveBlock(XMLTagHandler *&handle)
bool HandleLabelTrack(XMLTagHandler *&handle)
bool HandleXMLTag(const std::string_view &tag, const AttributesList &attrs) override
std::vector< WaveClip * > mClips
TranslatableString GetFileDescription() override
TranslatableString GetErrorMessage() const override
std::map< wxString, std::pair< FilePath, std::shared_ptr< SampleBlock > > > BlockFileMap
bool HandleSequence(XMLTagHandler *&handle)
bool SetError(const TranslatableString &msg)
bool HandleWaveTrack(XMLTagHandler *&handle)
wxInt32 GetStreamCount() override
sampleCount mTotalSamples
std::vector< struct node > stack
bool HandleNoteTrack(XMLTagHandler *&handle)
bool SetWarning(const TranslatableString &msg)
void Import(ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags) override
void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
bool HandleTimeTrack(XMLTagHandler *&handle)
bool HandleControlPoint(XMLTagHandler *&handle)
bool HandleImport(XMLTagHandler *&handle)
bool HandleWaveClip(XMLTagHandler *&handle)
bool HandleTag(XMLTagHandler *&handle)
std::vector< fileinfo > mFiles
bool HandleSimpleBlockFile(XMLTagHandler *&handle)
const TranslatableStrings & GetStreamInfo() override
bool HandleTags(XMLTagHandler *&handle)
bool AddSilence(sampleCount len)
bool HandleEnvelope(XMLTagHandler *&handle)
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
void AddFile(sampleCount len, sampleFormat format, const FilePath &blockFilename=wxEmptyString, const FilePath &audioFilename=wxEmptyString, sampleCount origin=0, int channel=0)
An ImportPlugin for AUP files (pre-AUP3)
TranslatableString GetPluginFormatDescription() override
ImportHandle Open(const FilePath &fileName, AudacityProject *project) override
wxString GetPluginStringID() override
Base class for exceptions specially processed by the application.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Piecewise linear or piecewise exponential function from double to double.
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
bool IsStopped() const noexcept
FilePath GetFilename() const override
bool IsCancelled() const noexcept
unsigned long long ByteCount
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Interface used to report on import state and progress.
virtual void OnImportResult(ImportResult result)=0
Used to report on import result for file handle passed as argument to OnImportFileOpened.
virtual void OnImportProgress(double progress)=0
static void ShowMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Import Project"))
static void FixTracks(TrackList &tracks, const std::function< void(const TranslatableString &)> &onError, const std::function< void(const TranslatableString &)> &onUnlink)
Attempts to find and fix problems in tracks.
bool Import(const FilePath &fileName, bool addToHistory=true)
static ProjectFileManager & Get(AudacityProject &project)
static ProjectHistory & Get(AudacityProject &project)
static ProjectRate & Get(AudacityProject &project)
void SetRate(double rate)
void SetSnapMode(SnapMode mode)
static ProjectSnap & Get(AudacityProject &project)
static const int UndefinedFrequency
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
static const char * Sequence_tag
static const char * WaveBlock_tag
static bool IsValidSampleFormat(const int nValue)
true if nValue is one of the sampleFormat enum values
A kind of Track used to 'warp time'.
BoundedEnvelope * GetEnvelope()
Abstract base class for an object holding data associated with points on a time axis.
static TrackList & Get(AudacityProject &project)
TrackKind * Add(const std::shared_ptr< TrackKind > &t, bool assignIds=true)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Debug() const
Format as an English string for debugging logs and developers' eyes, not for end users.
static ViewInfo & Get(AudacityProject &project)
This allows multiple clips to be a part of one WaveTrack.
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
double GetPlayEndTime() const override
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Envelope & GetEnvelope() noexcept
static const char * WaveClip_tag
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...
static WaveTrackFactory & Get(AudacityProject &project)
A Track that contains audio waveform data.
IntervalHolder RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
void InsertSilence(double t, double len) override
IntervalHolder CreateClip(double offset=.0, const wxString &name=wxEmptyString, const Interval *pToCopy=nullptr, bool copyCutlines=true)
void InsertInterval(const IntervalHolder &interval, bool newClip, bool allowEmpty=false)
static const char * WaveTrack_tag
void SetLegacyFormat(sampleFormat format)
double GetEndTime() const override
Implement WideSampleSequence.
double LongSamplesToTime(sampleCount pos) const
Reads a file and passes the results through an XMLTagHandler.
const TranslatableString & GetErrorStr() const
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
This class is an interface which should be implemented by classes which wish to be able to load and s...
virtual void HandleXMLEndTag(const std::string_view &WXUNUSED(tag))
static bool IsGoodFileString(const FilePath &str)
static bool IsGoodPathName(const FilePath &strPathName)
static bool IsGoodPathString(const FilePath &str)
static bool IsGoodFileName(const FilePath &strFileName, const FilePath &strDirName={})
Positions or offsets within audio files need a wide type.
long long as_long_long() const
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
bool CaseInsensitiveEquals(const std::string_view &lhs, const std::string_view &rhsLower)
AuthorizationHandler handler
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept