56#define DESC XO("AUP project files (*.aup)")
100 Tags *tags)
override;
106 void SetStreamUsage(wxInt32 WXUNUSED(StreamID),
bool WXUNUSED(Use))
override;
117 using stack = std::vector<struct node>;
144 const FilePath &blockFilename = wxEmptyString,
145 const FilePath &audioFilename = wxEmptyString,
167 #define field(n, t) bool have##n; t n
175#ifdef EXPERIMENTAL_SPECTRAL_EDITING
181 field(selectionformat, wxString);
182 field(audiotimeformat, wxString);
183 field(frequencyformat, wxString);
184 field(bandwidthformat, wxString);
212 std::map<wxString, std::pair<FilePath, std::shared_ptr<SampleBlock>>>;
227 const std::string_view& lhs,
const std::string_view& rhsLower)
229 if (lhs.length() != rhsLower.length())
232 for (
size_t i = 0; i < lhs.length(); ++i)
233 if (std::tolower(lhs[i]) != rhsLower[i])
244 sizeof(
long long) >=
sizeof(uint64_t) &&
245 sizeof(long) >=
sizeof(uint32_t),
246 "Assumptions about sizes in XMLValueChecker calls are invalid!");
255 return wxT(
"legacyaup");
266 auto handle = std::make_unique<AUPImportFileHandle>(fileName,
project);
279 "AUP", std::make_unique<AUPImportPlugin>()
324 auto oldNumTracks =
tracks.Size();
325 auto cleanup =
finally([
this, &
tracks, oldNumTracks]{
328 while (oldNumTracks <
tracks.Size())
333 bool isDirty = history.GetDirty() || !
tracks.empty();
378 if (fi.blockFile.empty())
385 fi.len, fi.format, fi.origin, fi.channel))
396 pClip->UpdateEnvelopeTrackLen();
431 selman.SSBL_SetFrequencySelectionFormatName(
440 selman.SSBL_SetBandwidthSelectionFormatName(
473#ifdef EXPERIMENTAL_SPECTRAL_EDITING
510 int numRead = ff.Read(buf,
sizeof(buf));
514 buf[
sizeof(buf) - 1] =
'\0';
516 if (!wxStrncmp(buf,
wxT(
"AudacityProject"), 15))
519 XO(
"This project was saved by Audacity version 1.0 or earlier. The format has\n"
520 "changed and this version of Audacity is unable to import the project.\n\n"
521 "Use a version of Audacity prior to v3.0.0 to upgrade the project and then\n"
522 "you may import it with this version of Audacity."));
526 if (wxStrncmp(buf,
"<?xml", 5) == 0 &&
527 (wxStrstr(buf,
"<audacityproject") ||
528 wxStrstr(buf,
"<project") ))
551 if (tag ==
"waveclip")
583 bool success =
false;
657 return SetError(
XO(
"Internal error in importer...tag not recognized"));
670 int requiredTags = 0;
674 auto attr = pair.first;
675 auto value = pair.second;
679#define set(f, v) (mProjectAttrs.have ## f = true, mProjectAttrs.f = v)
685 if (!value.TryGet(lValue) || (lValue < 0))
687 return SetError(
XO(
"Invalid project 'vpos' attribute."));
690 set(vpos, (
int) lValue);
692 else if (attr ==
"h")
694 if (!value.TryGet(dValue))
696 return SetError(
XO(
"Invalid project 'h' attribute."));
701 else if (attr ==
"zoom")
703 if (!value.TryGet(dValue) || (dValue < 0.0))
705 return SetError(
XO(
"Invalid project 'zoom' attribute."));
711 else if (attr ==
"sel0")
713 if (!value.TryGet(dValue))
715 return SetError(
XO(
"Invalid project 'sel0' attribute."));
720 else if (attr ==
"sel1")
722 if (!value.TryGet(dValue))
724 return SetError(
XO(
"Invalid project 'sel1' attribute."));
729#ifdef EXPERIMENTAL_SPECTRAL_EDITING
730 else if (attr ==
"selLow")
732 if (!value.TryGet(dValue) || (dValue < 0.0))
734 return SetError(
XO(
"Invalid project 'selLow' attribute."));
739 else if (attr ==
"selHigh")
741 if (!value.TryGet(dValue) || (dValue < 0.0))
743 return SetError(
XO(
"Invalid project 'selHigh' attribute."));
746 set(selHigh, dValue);
749 else if (attr ==
"version")
754 else if (attr ==
"audacityversion")
758 else if (attr ==
"projname")
763 wxString altname =
mProjDir.GetName() +
wxT(
"_data");
764 mProjDir.SetFullName(wxEmptyString);
766 wxString projName = value.ToWString();
770 if (!projName.empty())
784 if (projName.empty())
795 if (projName.empty())
798 XO(
"Couldn't find the project data folder: \"%s\"").
Format(value.ToWString()));
804 size_t cnt = wxDir::GetAllFiles(
mProjDir.GetFullPath(),
808 for (
const auto &
fn : files)
813 else if (attr ==
"rate")
815 if (!value.TryGet(dValue) || (dValue < 0.0))
817 return SetError(
XO(
"Invalid project 'selLow' attribute."));
823 else if (attr ==
"snapto")
825 set(snapto, (value.ToWString() ==
"on" ?
true :
false));
828 else if (attr ==
"selectionformat")
830 set(selectionformat, value.ToWString());
833 else if (attr ==
"frequencyformat")
835 set(frequencyformat, value.ToWString());
838 else if (attr ==
"bandwidthformat")
840 set(bandwidthformat, value.ToWString());
845 if (requiredTags < 3)
870 XO(
"MIDI tracks found in project file, but this build of Audacity does not include MIDI support, bypassing track."));
884 XO(
"The active project already has a time track and one was encountered in the project being imported, bypassing imported time track."));
916 auto attr = pair.first;
917 auto value = pair.second;
923 else if (attr ==
"track")
925 n =
wxT(
"TRACKNUMBER");
929 n = std::string(attr);
933 v = value.ToWString();
955 auto attr = pair.first;
956 auto value = pair.second;
960 n = value.ToWString();
962 else if (attr ==
"value")
964 v = value.ToWString();
968 if (n ==
wxT(
"id3v2"))
1088 for (
auto pair :
mAttrs) {
1089 auto attr = pair.first;
1090 auto value = pair.second;
1092 if (attr ==
"maxsamples")
1096 if (!value.TryGet(llvalue) || (llvalue < 0))
1098 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1104 if ((llvalue < 1024) || (llvalue > 64 * 1024 * 1024))
1106 return SetError(
XO(
"Invalid sequence 'maxsamples' attribute."));
1109 else if (attr ==
"sampleformat")
1115 return SetError(
XO(
"Invalid sequence 'sampleformat' attribute."));
1120 pSequence->ConvertToSampleFormat(
mFormat);
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.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>()) {
1376 bSuccess = pTrack->HandleXMLTag(
"wavetrack",
mAttrs);
1381 for (
auto pair :
mAttrs) {
1382 auto attr = pair.first;
1383 auto value = pair.second;
1384 if (attr ==
"offset" && value.TryGet(dblValue))
1385 pTrack->MoveTo(dblValue);
1442 auto &pBlock =
mFileMap[wxFileNameFromPath(blockFilename)].second;
1445 if (pClip->GetWidth() != 1)
1447 pClip->AppendSharedBlock( pBlock );
1454 "Type sf_count_t is too narrow to hold a sampleCount");
1457 memset(&info, 0,
sizeof(info));
1460 SNDFILE *sf =
nullptr;
1461 bool success =
false;
1463#ifndef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1464 const auto uncaughtExceptionsCount = std::uncaught_exceptions();
1467 auto cleanup =
finally([&]
1472 SFCall<int>(sf_close, sf);
1477 SetWarning(
XO(
"Error while processing %s\n\nInserting silence.").
Format(audioFilename));
1481#ifdef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1482 if (!std::uncaught_exception())
1484 if (uncaughtExceptionsCount == std::uncaught_exceptions())
1491 if (!f.Open(audioFilename))
1501 sf = SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE);
1511 if (SFCall<sf_count_t>(sf_seek, sf, origin.
as_long_long(), SEEK_SET) < 0)
1521 int channels = info.channels;
1523 wxASSERT(channels >= 1);
1524 wxASSERT(channel < channels);
1529 size_t framesRead = 0;
1537 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, (
short *) bufptr, cnt);
1541 framesRead = SFCall<sf_count_t>(sf_readf_int, sf, (
int *) bufptr, cnt);
1542 if (framesRead != cnt)
1545 .
Format(cnt, audioFilename));
1553 int *intPtr = (
int *) bufptr;
1554 for (
size_t i = 0; i < framesRead; i++)
1556 intPtr[i] = intPtr[i] >> 8;
1566 short *tmpptr = (
short *) temp.
ptr();
1568 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, tmpptr, cnt);
1569 if (framesRead != cnt)
1572 .
Format(cnt, audioFilename));
1577 for (
size_t i = 0; i < framesRead; i++)
1579 ((
short *)bufptr)[i] = tmpptr[(channels * i) + channel];
1600 float *tmpptr = (
float *) tmpbuf.
ptr();
1602 framesRead = SFCall<sf_count_t>(sf_readf_float, sf, tmpptr, cnt);
1603 if (framesRead != cnt)
1606 .
Format(cnt, audioFilename));
1638 if (pClip->GetWidth() != 1)
1640 pBlock = pClip->AppendNewBlock(bufptr,
format, cnt);
1651 wxLogError(msg.
Debug());
1664 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...
const TranslatableString name
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< TrackList > > TrackHolders
const NumericConverterType & NumericConverterType_BANDWIDTH()
const NumericConverterType & NumericConverterType_FREQUENCY()
const NumericConverterType & NumericConverterType_TIME()
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
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)
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 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)
void Import(ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
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
static FormatterContext ProjectContext(const AudacityProject &project)
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"))
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)
static ProjectSelectionManager & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
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 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
double GetPlayEndTime() const override
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
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)
Create new clip and add it to this track.
bool IsLeader() const override
double GetEndTime() const override
Implement WideSampleSequence.
WaveClip * RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
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.
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