54#define DESC XO("AUP project files (*.aup)")
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
173#ifdef EXPERIMENTAL_SPECTRAL_EDITING
179 field(selectionformat, wxString);
180 field(audiotimeformat, wxString);
181 field(frequencyformat, wxString);
182 field(bandwidthformat, wxString);
210 std::map<wxString, std::pair<FilePath, std::shared_ptr<SampleBlock>>>;
225 const std::string_view& lhs,
const std::string_view& rhsLower)
227 if (lhs.length() != rhsLower.length())
230 for (
size_t i = 0; i < lhs.length(); ++i)
231 if (std::tolower(lhs[i]) != rhsLower[i])
242 sizeof(
long long) >=
sizeof(uint64_t) &&
243 sizeof(long) >=
sizeof(uint32_t),
244 "Assumptions about sizes in XMLValueChecker calls are invalid!");
253 return wxT(
"legacyaup");
264 auto handle = std::make_unique<AUPImportFileHandle>(fileName, project);
277 "AUP", std::make_unique<AUPImportPlugin>()
312 auto oldNumTracks = tracks.size();
313 auto cleanup =
finally([
this, &tracks, oldNumTracks]{
316 while (oldNumTracks < tracks.size()) {
317 Track *lastTrack = *tracks.Any().rbegin();
318 tracks.Remove(lastTrack);
323 bool isDirty = history.GetDirty() || !tracks.empty();
340 XO(
"Import Project"),
344 return ProgressResult::Failed;
352 XO(
"Import Project"),
359 return ProgressResult::Failed;
378 if (fi.blockFile.empty())
385 fi.len, fi.format, fi.origin, fi.channel);
392 pClip->UpdateEnvelopeTrackLen();
460#ifdef EXPERIMENTAL_SPECTRAL_EDITING
497 int numRead = ff.Read(buf,
sizeof(buf));
501 buf[
sizeof(buf) - 1] =
'\0';
503 if (!wxStrncmp(buf,
wxT(
"AudacityProject"), 15))
506 XO(
"This project was saved by Audacity version 1.0 or earlier. The format has\n"
507 "changed and this version of Audacity is unable to import the project.\n\n"
508 "Use a version of Audacity prior to v3.0.0 to upgrade the project and then\n"
509 "you may import it with this version of Audacity."),
510 XO(
"Import Project"),
517 if (wxStrncmp(buf,
"<?xml", 5) == 0 &&
518 (wxStrstr(buf,
"<audacityproject") ||
519 wxStrstr(buf,
"<project") ))
542 if (tag ==
"waveclip")
574 bool success =
false;
648 return SetError(
XO(
"Internal error in importer...tag not recognized"));
661 int requiredTags = 0;
665 auto attr = pair.first;
666 auto value = pair.second;
670#define set(f, v) (mProjectAttrs.have ## f = true, mProjectAttrs.f = v)
676 if (!value.TryGet(lValue) || (lValue < 0))
678 return SetError(
XO(
"Invalid project 'vpos' attribute."));
681 set(vpos, (
int) lValue);
683 else if (attr ==
"h")
685 if (!value.TryGet(dValue))
687 return SetError(
XO(
"Invalid project 'h' attribute."));
692 else if (attr ==
"zoom")
694 if (!value.TryGet(dValue) || (dValue < 0.0))
696 return SetError(
XO(
"Invalid project 'zoom' attribute."));
702 else if (attr ==
"sel0")
704 if (!value.TryGet(dValue))
706 return SetError(
XO(
"Invalid project 'sel0' attribute."));
711 else if (attr ==
"sel1")
713 if (!value.TryGet(dValue))
715 return SetError(
XO(
"Invalid project 'sel1' attribute."));
720#ifdef EXPERIMENTAL_SPECTRAL_EDITING
721 else if (attr ==
"selLow")
723 if (!value.TryGet(dValue) || (dValue < 0.0))
725 return SetError(
XO(
"Invalid project 'selLow' attribute."));
730 else if (attr ==
"selHigh")
732 if (!value.TryGet(dValue) || (dValue < 0.0))
734 return SetError(
XO(
"Invalid project 'selHigh' attribute."));
737 set(selHigh, dValue);
740 else if (attr ==
"version")
745 else if (attr ==
"audacityversion")
749 else if (attr ==
"projname")
754 wxString altname =
mProjDir.GetName() +
wxT(
"_data");
755 mProjDir.SetFullName(wxEmptyString);
757 wxString projName = value.ToWString();
761 if (!projName.empty())
775 if (projName.empty())
786 if (projName.empty())
789 XO(
"Couldn't find the project data folder: \"%s\"").
Format(value.ToWString()),
790 XO(
"Error Opening Project"),
799 size_t cnt = wxDir::GetAllFiles(
mProjDir.GetFullPath(),
803 for (
const auto &
fn : files)
808 else if (attr ==
"rate")
810 if (!value.TryGet(dValue) || (dValue < 0.0))
812 return SetError(
XO(
"Invalid project 'selLow' attribute."));
818 else if (attr ==
"snapto")
820 set(snapto, (value.ToWString() ==
"on" ?
true :
false));
823 else if (attr ==
"selectionformat")
825 set(selectionformat, value.ToWString());
828 else if (attr ==
"frequencyformat")
830 set(frequencyformat, value.ToWString());
833 else if (attr ==
"bandwidthformat")
835 set(bandwidthformat, value.ToWString());
840 if (requiredTags < 3)
865 XO(
"MIDI tracks found in project file, but this build of Audacity does not include MIDI support, bypassing track."),
866 XO(
"Project Import"),
867 wxOK | wxICON_EXCLAMATION | wxCENTRE,
883 XO(
"The active project already has a time track and one was encountered in the project being imported, bypassing imported time track."),
884 XO(
"Project Import"),
885 wxOK | wxICON_EXCLAMATION | wxCENTRE,
919 auto attr = pair.first;
920 auto value = pair.second;
926 else if (attr ==
"track")
928 n =
wxT(
"TRACKNUMBER");
932 n = std::string(attr);
936 v = value.ToWString();
958 auto attr = pair.first;
959 auto value = pair.second;
963 n = value.ToWString();
965 else if (attr ==
"value")
967 v = value.ToWString();
971 if (n ==
wxT(
"id3v2"))
1090 auto attr = pair.first;
1091 auto value = pair.second;
1093 if (attr ==
"maxsamples")
1097 if (!value.TryGet(llvalue) || (llvalue < 0))
1099 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1105 if ((llvalue < 1024) || (llvalue > 64 * 1024 * 1024))
1107 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1110 else if (attr ==
"sampleformat")
1116 return SetError(
XO(
"Invalid sequence 'sampleformat' attribute."));
1122 else if (attr ==
"numsamples")
1126 if (!value.TryGet(llvalue) || (llvalue < 0))
1128 return SetError(
XO(
"Invalid sequence 'numsamples' attribute."));
1142 auto attr = pair.first;
1143 auto value = pair.second;
1145 if (attr ==
"start")
1149 if (!value.TryGet(llvalue) || (llvalue < 0))
1151 return SetError(
XO(
"Unable to parse the waveblock 'start' attribute"));
1168 auto attr = pair.first;
1169 auto value = pair.second;
1174 const wxString strValue = value.ToWString();
1180 filename =
mFileMap[strValue].first;
1184 SetWarning(
XO(
"Missing project file %s\n\nInserting silence instead.")
1189 else if (attr ==
"len")
1192 if (!value.TryGet(lValue) || (lValue <= 0))
1194 return SetError(
XO(
"Missing or invalid simpleblockfile 'len' attribute."));
1215 auto attr = pair.first;
1216 auto value = pair.second;
1221 if (!value.TryGet(lValue) || !(lValue > 0))
1223 return SetError(
XO(
"Missing or invalid silentblockfile 'len' attribute."));
1239 wxString summaryFilename;
1240 wxFileName filename;
1248 auto attr = pair.first;
1249 auto value = pair.second;
1253 const wxString strValue = value.ToWString();
1257 filename.Assign(strValue);
1262 filename.Assign(
mProjDir.GetPath(), strValue);
1268 SetWarning(
XO(
"Missing alias file %s\n\nInserting silence instead.")
1274 summaryFilename = value.ToWString();
1279 if (!value.TryGet(llValue) || (llValue < 0))
1281 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliasstart' attribute."));
1289 if (!value.TryGet(lValue) || (lValue <= 0))
1291 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1299 if (!value.TryGet(lValue) || (lValue < 0))
1301 return SetError(
XO(
"Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1310 if (filename.IsOk())
1312 summaryFilename, filename.GetFullPath(),
1323 if (
mAttrs.empty() ||
mAttrs.front().first !=
"filename")
1326 wxString strAttr =
mAttrs.front().second.ToWString();
1332 fileName0.SetExt({});
1334 fileName0.GetFullPath() +
wxT(
"_data"), strAttr };
1336 strAttr = fileName.GetFullPath();
1339 wxLogWarning(
wxT(
"Could not import file: %s"), strAttr);
1345 auto oldNumTracks = tracks.size();
1346 Track *pLast =
nullptr;
1347 if (oldNumTracks > 0)
1348 pLast = *tracks.
Any().rbegin();
1358 if (oldNumTracks == tracks.size())
1363 bool bSuccess =
true;
1365 auto range = tracks.Any();
1367 range = range.StartingWith(pLast);
1373 for (
auto pTrack: range.Filter<
WaveTrack>())
1377 bSuccess = pTrack->HandleXMLTag(
"wavetrack",
mAttrs);
1385 auto attr = pair.first;
1386 auto value = pair.second;
1388 if (attr ==
"offset" && value.TryGet(dblValue))
1389 pTrack->SetOffset(dblValue);
1443 auto &pBlock =
mFileMap[wxFileNameFromPath(blockFilename)].second;
1446 pClip->AppendSharedBlock( pBlock );
1453 "Type sf_count_t is too narrow to hold a sampleCount");
1456 memset(&info, 0,
sizeof(info));
1459 SNDFILE *sf =
nullptr;
1460 bool success =
false;
1462#ifndef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1463 const auto uncaughtExceptionsCount = std::uncaught_exceptions();
1466 auto cleanup =
finally([&]
1471 SFCall<int>(sf_close, sf);
1476 SetWarning(
XO(
"Error while processing %s\n\nInserting silence.").
Format(audioFilename));
1480#ifdef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1481 if (!std::uncaught_exception())
1483 if (uncaughtExceptionsCount == std::uncaught_exceptions())
1490 if (!f.Open(audioFilename))
1500 sf = SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE);
1510 if (SFCall<sf_count_t>(sf_seek, sf, origin.
as_long_long(), SEEK_SET) < 0)
1520 int channels = info.channels;
1522 wxASSERT(channels >= 1);
1523 wxASSERT(channel < channels);
1528 size_t framesRead = 0;
1536 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, (
short *) bufptr, cnt);
1540 framesRead = SFCall<sf_count_t>(sf_readf_int, sf, (
int *) bufptr, cnt);
1541 if (framesRead != cnt)
1544 .
Format(cnt, audioFilename));
1552 int *intPtr = (
int *) bufptr;
1553 for (
size_t i = 0; i < framesRead; i++)
1555 intPtr[i] = intPtr[i] >> 8;
1565 short *tmpptr = (
short *) temp.
ptr();
1567 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, tmpptr, cnt);
1568 if (framesRead != cnt)
1571 .
Format(cnt, audioFilename));
1576 for (
size_t i = 0; i < framesRead; i++)
1578 ((
short *)bufptr)[i] = tmpptr[(channels * i) + channel];
1599 float *tmpptr = (
float *) tmpbuf.
ptr();
1601 framesRead = SFCall<sf_count_t>(sf_readf_float, sf, tmpptr, cnt);
1602 if (framesRead != cnt)
1605 .
Format(cnt, audioFilename));
1637 pBlock = pClip->AppendNewBlock(bufptr,
format, cnt);
1648 wxLogError(msg.
Debug());
1663 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...
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
const TranslatableString name
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
std::vector< std::vector< std::shared_ptr< WaveTrack > > > TrackHolders
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....
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
static Settings & settings()
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)
bool HandlePCMAliasBlockFile(XMLTagHandler *&handle)
unsigned long mNumChannels
AUPImportFileHandle(const FilePath &name, AudacityProject *project)
ByteCount GetFileUncompressedBytes() override
struct AUPImportFileHandle::@47 mProjectAttrs
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
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 SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
bool HandleTimeTrack(XMLTagHandler *&handle)
bool HandleControlPoint(XMLTagHandler *&handle)
bool HandleImport(XMLTagHandler *&handle)
bool HandleWaveClip(XMLTagHandler *&handle)
ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
bool HandleTag(XMLTagHandler *&handle)
std::vector< fileinfo > mFiles
bool HandleSimpleBlockFile(XMLTagHandler *&handle)
const TranslatableStrings & GetStreamInfo() override
bool HandleTags(XMLTagHandler *&handle)
ProgressResult mUpdateResult
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
An ImportFileHandle for data.
unsigned long long ByteCount
std::unique_ptr< ProgressDialog > mProgress
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
static NumericFormatSymbol LookupFormat(Type type, const wxString &id)
bool Import(const FilePath &fileName, bool addToHistory=true)
static ProjectFileManager & Get(AudacityProject &project)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSelectionManager & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
double LongSamplesToTime(sampleCount pos) const
Convert correctly between a number of samples and an (absolute) time in seconds.
static const int UndefinedFrequency
static SelectionBar & Get(AudacityProject &project)
bool ConvertToSampleFormat(sampleFormat format, const std::function< void(size_t)> &progressReport={})
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.
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
static TrackList & Get(AudacityProject &project)
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
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
double GetPlayEndTime() const
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.
void InsertSilence(double t, double len) override
WaveClip * CreateClip(double offset=.0, const wxString &name=wxEmptyString)
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
WaveClip * RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
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.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
bool CaseInsensitiveEquals(const std::string_view &lhs, const std::string_view &rhsLower)
AuthorizationHandler handler