Audacity 3.2.0
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
AUPImportFileHandle Class Referencefinal

An ImportFileHandle for AUP files (pre-AUP3) More...

Inheritance diagram for AUPImportFileHandle:
[legend]
Collaboration diagram for AUPImportFileHandle:
[legend]

Classes

struct  fileinfo
 
struct  node
 

Public Member Functions

 AUPImportFileHandle (const FilePath &name, AudacityProject *project)
 
 ~AUPImportFileHandle ()
 
TranslatableString GetErrorMessage () const override
 
TranslatableString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
void Import (ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags) override
 
wxInt32 GetStreamCount () override
 
const TranslatableStringsGetStreamInfo () override
 
void SetStreamUsage (wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
 
bool Open ()
 
- Public Member Functions inherited from ImportFileHandleEx
 ImportFileHandleEx (const FilePath &filename)
 
FilePath GetFilename () const override
 
void Cancel () override
 
void Stop () override
 
- Public Member Functions inherited from ImportFileHandle
virtual ~ImportFileHandle ()
 
virtual FilePath GetFilename () const =0
 
virtual TranslatableString GetErrorMessage () const
 
virtual TranslatableString GetFileDescription ()=0
 
virtual ByteCount GetFileUncompressedBytes ()=0
 
virtual wxInt32 GetStreamCount ()=0
 
virtual const TranslatableStringsGetStreamInfo ()=0
 
virtual void SetStreamUsage (wxInt32 StreamID, bool Use)=0
 
virtual void Import (ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &acidTags)=0
 
virtual void Cancel ()=0
 
virtual void Stop ()=0
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 

Private Types

using stack = std::vector< struct node >
 
using BlockFileMap = std::map< wxString, std::pair< FilePath, std::shared_ptr< SampleBlock > > >
 

Private Member Functions

bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
void HandleXMLEndTag (const std::string_view &tag) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
bool HandleProject (XMLTagHandler *&handle)
 
bool HandleLabelTrack (XMLTagHandler *&handle)
 
bool HandleNoteTrack (XMLTagHandler *&handle)
 
bool HandleTimeTrack (XMLTagHandler *&handle)
 
bool HandleWaveTrack (XMLTagHandler *&handle)
 
bool HandleTags (XMLTagHandler *&handle)
 
bool HandleTag (XMLTagHandler *&handle)
 
bool HandleLabel (XMLTagHandler *&handle)
 
bool HandleWaveClip (XMLTagHandler *&handle)
 
bool HandleSequence (XMLTagHandler *&handle)
 
bool HandleWaveBlock (XMLTagHandler *&handle)
 
bool HandleEnvelope (XMLTagHandler *&handle)
 
bool HandleControlPoint (XMLTagHandler *&handle)
 
bool HandleSimpleBlockFile (XMLTagHandler *&handle)
 
bool HandleSilentBlockFile (XMLTagHandler *&handle)
 
bool HandlePCMAliasBlockFile (XMLTagHandler *&handle)
 
bool HandleImport (XMLTagHandler *&handle)
 
void AddFile (sampleCount len, sampleFormat format, const FilePath &blockFilename=wxEmptyString, const FilePath &audioFilename=wxEmptyString, sampleCount origin=0, int channel=0)
 
bool AddSilence (sampleCount len)
 
bool AddSamples (const FilePath &blockFilename, const FilePath &audioFilename, sampleCount len, sampleFormat format, sampleCount origin=0, int channel=0)
 
bool SetError (const TranslatableString &msg)
 
bool SetWarning (const TranslatableString &msg)
 

Private Attributes

AudacityProjectmProject
 
TagsmTags
 
struct {
mProjectAttrs
 
std::vector< fileinfomFiles
 
sampleCount mTotalSamples
 
sampleFormat mFormat
 
unsigned long mNumChannels
 
stack mHandlers
 
std::string mParentTag
 
std::string mCurrentTag
 
AttributesList mAttrs
 
wxFileName mProjDir
 
BlockFileMap mFileMap
 
WaveTrackmWaveTrack
 
WaveClipmClip
 
std::vector< WaveClip * > mClips
 
TranslatableString mErrorMsg
 
bool mHasParseError { false }
 

Additional Inherited Members

- Public Types inherited from ImportFileHandle
using ByteCount = unsigned long long
 
- Protected Member Functions inherited from ImportFileHandleEx
void BeginImport ()
 
bool IsCancelled () const noexcept
 
bool IsStopped () const noexcept
 

Detailed Description

An ImportFileHandle for AUP files (pre-AUP3)

Definition at line 81 of file ImportAUP.cpp.

Member Typedef Documentation

◆ BlockFileMap

using AUPImportFileHandle::BlockFileMap = std::map<wxString, std::pair<FilePath, std::shared_ptr<SampleBlock> >>
private

Definition at line 209 of file ImportAUP.cpp.

◆ stack

using AUPImportFileHandle::stack = std::vector<struct node>
private

Definition at line 115 of file ImportAUP.cpp.

Constructor & Destructor Documentation

◆ AUPImportFileHandle()

AUPImportFileHandle::AUPImportFileHandle ( const FilePath name,
AudacityProject project 
)

Definition at line 280 of file ImportAUP.cpp.

282: ImportFileHandleEx(fileName),
284{
285}
const auto project
AudacityProject & mProject
Definition: ImportAUP.cpp:160
ImportFileHandleEx(const FilePath &filename)

◆ ~AUPImportFileHandle()

AUPImportFileHandle::~AUPImportFileHandle ( )

Definition at line 287 of file ImportAUP.cpp.

288{
289}

Member Function Documentation

◆ AddFile()

void AUPImportFileHandle::AddFile ( sampleCount  len,
sampleFormat  format,
const FilePath blockFilename = wxEmptyString,
const FilePath audioFilename = wxEmptyString,
sampleCount  origin = 0,
int  channel = 0 
)
private

Definition at line 1405 of file ImportAUP.cpp.

1411{
1412 fileinfo fi = {};
1413 fi.track = mWaveTrack;
1414 fi.clip = mClip;
1415 fi.blockFile = blockFilename;
1416 fi.audioFile = audioFilename;
1417 fi.len = len;
1418 fi.format = format,
1419 fi.origin = origin,
1420 fi.channel = channel;
1421
1422 mFiles.push_back(fi);
1423
1424 mTotalSamples += len;
1425}
WaveTrack * mWaveTrack
Definition: ImportAUP.cpp:213
sampleCount mTotalSamples
Definition: ImportAUP.cpp:198
std::vector< fileinfo > mFiles
Definition: ImportAUP.cpp:197

References AUPImportFileHandle::fileinfo::audioFile, AUPImportFileHandle::fileinfo::blockFile, AUPImportFileHandle::fileinfo::channel, AUPImportFileHandle::fileinfo::clip, AUPImportFileHandle::fileinfo::format, anonymous_namespace{ExportPCM.cpp}::format, AUPImportFileHandle::fileinfo::len, mClip, mFiles, mTotalSamples, mWaveTrack, AUPImportFileHandle::fileinfo::origin, and AUPImportFileHandle::fileinfo::track.

Referenced by HandlePCMAliasBlockFile(), HandleSilentBlockFile(), and HandleSimpleBlockFile().

Here is the caller graph for this function:

◆ AddSamples()

bool AUPImportFileHandle::AddSamples ( const FilePath blockFilename,
const FilePath audioFilename,
sampleCount  len,
sampleFormat  format,
sampleCount  origin = 0,
int  channel = 0 
)
private

Definition at line 1448 of file ImportAUP.cpp.

1454{
1455 auto pClip = mClip ? mClip : mWaveTrack->RightmostOrNewClip();
1456 auto &pBlock = mFileMap[wxFileNameFromPath(blockFilename)].second;
1457 if (pBlock) {
1458 // Replicate the sharing of blocks
1459 if (pClip->GetWidth() != 1)
1460 return false;
1461 pClip->AppendSharedBlock( pBlock );
1462 return true;
1463 }
1464
1465 // Third party library has its own type alias, check it before
1466 // adding origin + size_t
1467 static_assert(sizeof(sampleCount::type) <= sizeof(sf_count_t),
1468 "Type sf_count_t is too narrow to hold a sampleCount");
1469
1470 SF_INFO info;
1471 memset(&info, 0, sizeof(info));
1472
1473 wxFile f; // will be closed when it goes out of scope
1474 SNDFILE *sf = nullptr;
1475 bool success = false;
1476
1477#ifndef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1478 const auto uncaughtExceptionsCount = std::uncaught_exceptions();
1479#endif
1480
1481 auto cleanup = finally([&]
1482 {
1483 // Do this before any throwing might happen
1484 if (sf)
1485 {
1486 SFCall<int>(sf_close, sf);
1487 }
1488
1489 if (!success)
1490 {
1491 SetWarning(XO("Error while processing %s\n\nInserting silence.").Format(audioFilename));
1492
1493 // If we are unwinding for an exception, don't do another
1494 // potentially throwing operation
1495#ifdef UNCAUGHT_EXCEPTIONS_UNAVAILABLE
1496 if (!std::uncaught_exception())
1497#else
1498 if (uncaughtExceptionsCount == std::uncaught_exceptions())
1499#endif
1500 // If this does throw, let that propagate, don't guard the call
1501 AddSilence(len);
1502 }
1503 });
1504
1505 if (!f.Open(audioFilename))
1506 {
1507 SetWarning(XO("Failed to open %s").Format(audioFilename));
1508
1509 return true;
1510 }
1511
1512 // Even though there is an sf_open() that takes a filename, use the one that
1513 // takes a file descriptor since wxWidgets can open a file with a Unicode name and
1514 // libsndfile can't (under Windows).
1515 sf = SFCall<SNDFILE*>(sf_open_fd, f.fd(), SFM_READ, &info, FALSE);
1516 if (!sf)
1517 {
1518 SetWarning(XO("Failed to open %s").Format(audioFilename));
1519
1520 return true;
1521 }
1522
1523 if (origin > 0)
1524 {
1525 if (SFCall<sf_count_t>(sf_seek, sf, origin.as_long_long(), SEEK_SET) < 0)
1526 {
1527 SetWarning(XO("Failed to seek to position %lld in %s")
1528 .Format(origin.as_long_long(), audioFilename));
1529
1530 return true;
1531 }
1532 }
1533
1534 sf_count_t cnt = len.as_size_t();
1535 int channels = info.channels;
1536
1537 wxASSERT(channels >= 1);
1538 wxASSERT(channel < channels);
1539
1540 SampleBuffer buffer(cnt, format);
1541 samplePtr bufptr = buffer.ptr();
1542
1543 size_t framesRead = 0;
1544
1545 // These cases preserve the logic formerly in BlockFile.cpp,
1546 // which was deleted at commit 98d1468.
1547 if (channels == 1 && format == int16Sample && sf_subtype_is_integer(info.format))
1548 {
1549 // If both the src and dest formats are integer formats,
1550 // read integers directly from the file, conversions not needed
1551 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, (short *) bufptr, cnt);
1552 }
1553 else if (channels == 1 && format == int24Sample && sf_subtype_is_integer(info.format))
1554 {
1555 framesRead = SFCall<sf_count_t>(sf_readf_int, sf, (int *) bufptr, cnt);
1556 if (framesRead != cnt)
1557 {
1558 SetWarning(XO("Unable to read %lld samples from %s")
1559 .Format(cnt, audioFilename));
1560
1561 return true;
1562 }
1563
1564 // libsndfile gave us the 3 byte sample in the 3 most
1565 // significant bytes -- we want it in the 3 least
1566 // significant bytes.
1567 int *intPtr = (int *) bufptr;
1568 for (size_t i = 0; i < framesRead; i++)
1569 {
1570 intPtr[i] = intPtr[i] >> 8;
1571 }
1572 }
1573 else if (format == int16Sample && !sf_subtype_more_than_16_bits(info.format))
1574 {
1575 // Special case: if the file is in 16-bit (or less) format,
1576 // and the calling method wants 16-bit data, go ahead and
1577 // read 16-bit data directly. This is a pretty common
1578 // case, as most audio files are 16-bit.
1579 SampleBuffer temp(cnt * channels, int16Sample);
1580 short *tmpptr = (short *) temp.ptr();
1581
1582 framesRead = SFCall<sf_count_t>(sf_readf_short, sf, tmpptr, cnt);
1583 if (framesRead != cnt)
1584 {
1585 SetWarning(XO("Unable to read %lld samples from %s")
1586 .Format(cnt, audioFilename));
1587
1588 return true;
1589 }
1590
1591 for (size_t i = 0; i < framesRead; i++)
1592 {
1593 ((short *)bufptr)[i] = tmpptr[(channels * i) + channel];
1594 }
1595 }
1596 else
1597 {
1598 /*
1599 Therefore none of the three cases above:
1600 !(channels == 1 && format == int16Sample && sf_subtype_is_integer(info.format))
1601 &&
1602 !(channels == 1 && format == int24Sample && sf_subtype_is_integer(info.format))
1603 &&
1604 !(format == int16Sample && !sf_subtype_more_than_16_bits(info.format))
1605
1606 So format is not 16 bits with wider file format (third conjunct),
1607 but still maybe it is 24 bits with float file format (second conjunct).
1608 */
1609
1610 // Otherwise, let libsndfile handle the conversion and
1611 // scaling, and pass us normalized data as floats. We can
1612 // then convert to whatever format we want.
1613 SampleBuffer tmpbuf(cnt * channels, floatSample);
1614 float *tmpptr = (float *) tmpbuf.ptr();
1615
1616 framesRead = SFCall<sf_count_t>(sf_readf_float, sf, tmpptr, cnt);
1617 if (framesRead != cnt)
1618 {
1619 SetWarning(XO("Unable to read %lld samples from %s")
1620 .Format(cnt, audioFilename));
1621
1622 return true;
1623 }
1624
1625 /*
1626 Dithering will happen in CopySamples if format is 24 bits.
1627 Should that be done?
1628
1629 Either the file is an ordinary simple block file -- and presumably the
1630 track was saved specifying a matching format, so format is float and
1631 there is no dithering.
1632
1633 Or else this is the very unusual case of an .auf file, importing PCM data
1634 on demand. The destination format is narrower, requiring dither, only
1635 if the user also specified a narrow format for the track. In such a
1636 case, dithering is right.
1637 */
1638 CopySamples((samplePtr)(tmpptr + channel),
1640 bufptr,
1641 format,
1642 framesRead,
1643 gHighQualityDither /* high quality by default */,
1644 channels /* source stride */);
1645 }
1646
1647 wxASSERT(mClip || mWaveTrack);
1648
1649 // Add the samples to the clip/track
1650 if (pClip)
1651 {
1652 if (pClip->GetWidth() != 1)
1653 return false;
1654 pBlock = pClip->AppendNewBlock(bufptr, format, cnt);
1655 }
1656
1657 // Let the finally block know everything is good
1658 success = true;
1659
1660 return true;
1661}
bool sf_subtype_is_integer(unsigned int format)
bool sf_subtype_more_than_16_bits(unsigned int format)
XO("Cut/Copy/Paste")
DitherType gHighQualityDither
void CopySamples(constSamplePtr src, sampleFormat srcFormat, samplePtr dst, sampleFormat dstFormat, size_t len, DitherType ditherType, unsigned int srcStride, unsigned int dstStride)
Copy samples from any format to any other format; apply dithering only if narrowing the format.
char * samplePtr
Definition: SampleFormat.h:57
BlockFileMap mFileMap
Definition: ImportAUP.cpp:211
bool SetWarning(const TranslatableString &msg)
Definition: ImportAUP.cpp:1676
bool AddSilence(sampleCount len)
Definition: ImportAUP.cpp:1427
Abstract base class used in importing a file.
WaveClip * RightmostOrNewClip()
Get access to the last (rightmost) clip, or create a clip, if there is not already one.
Definition: WaveTrack.cpp:3844
long long as_long_long() const
Definition: SampleCount.h:48
long long type
Definition: SampleCount.h:21
size_t as_size_t() const
Definition: SampleCount.cpp:16

References AddSilence(), sampleCount::as_long_long(), sampleCount::as_size_t(), CopySamples(), floatSample, anonymous_namespace{ExportPCM.cpp}::format, gHighQualityDither, int16Sample, int24Sample, mClip, mFileMap, mWaveTrack, SampleBuffer::ptr(), WaveTrack::RightmostOrNewClip(), SetWarning(), sf_subtype_is_integer(), sf_subtype_more_than_16_bits(), and XO().

Referenced by Import().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddSilence()

bool AUPImportFileHandle::AddSilence ( sampleCount  len)
private

Definition at line 1427 of file ImportAUP.cpp.

1428{
1429 wxASSERT(mClip || mWaveTrack);
1430
1431 if (mClip)
1432 {
1434 }
1435 else if (mWaveTrack)
1436 {
1437 // Assume alignment of clips and insert silence into leader only
1438 if (mWaveTrack->IsLeader())
1441 }
1442
1443 return true;
1444}
double GetPlayEndTime() const override
Definition: WaveClip.cpp:1353
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Definition: WaveClip.cpp:836
void InsertSilence(double t, double len) override
Definition: WaveTrack.cpp:2490
bool IsLeader() const override
Definition: WaveTrack.cpp:2833
double GetEndTime() const override
Implement WideSampleSequence.
Definition: WaveTrack.cpp:3105
double LongSamplesToTime(sampleCount pos) const

References WaveTrack::GetEndTime(), WaveClip::GetPlayEndTime(), WaveTrack::InsertSilence(), WaveClip::InsertSilence(), WaveTrack::IsLeader(), WideSampleSequence::LongSamplesToTime(), mClip, and mWaveTrack.

Referenced by AddSamples(), and Import().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetErrorMessage()

TranslatableString AUPImportFileHandle::GetErrorMessage ( ) const
overridevirtual

Reimplemented from ImportFileHandle.

Definition at line 296 of file ImportAUP.cpp.

297{
298 return mErrorMsg;
299}
TranslatableString mErrorMsg
Definition: ImportAUP.cpp:217

References mErrorMsg.

◆ GetFileDescription()

TranslatableString AUPImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 291 of file ImportAUP.cpp.

292{
293 return DESC;
294}
#define DESC
Definition: ImportAUP.cpp:54

References DESC.

◆ GetFileUncompressedBytes()

auto AUPImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 301 of file ImportAUP.cpp.

302{
303 // TODO: Get Uncompressed byte count.
304 return 0;
305}

◆ GetStreamCount()

wxInt32 AUPImportFileHandle::GetStreamCount ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 501 of file ImportAUP.cpp.

502{
503 return 1;
504}

◆ GetStreamInfo()

const TranslatableStrings & AUPImportFileHandle::GetStreamInfo ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 506 of file ImportAUP.cpp.

507{
508 static TranslatableStrings empty;
509 return empty;
510}
std::vector< TranslatableString > TranslatableStrings

◆ HandleControlPoint()

bool AUPImportFileHandle::HandleControlPoint ( XMLTagHandler *&  handle)
private

Definition at line 1067 of file ImportAUP.cpp.

1068{
1069 struct node node = mHandlers.back();
1070
1071 if (mParentTag == "envelope")
1072 {
1073 // If an imported timetrack was bypassed, then we want to bypass the
1074 // control points as well. (See HandleTimeTrack and HandleEnvelope)
1075 if (node.handler)
1076 {
1077 Envelope *envelope = static_cast<Envelope *>(node.handler);
1078
1079 handler = envelope->HandleXMLChild(mCurrentTag);
1080 }
1081 }
1082
1083 return true;
1084}
std::string mParentTag
Definition: ImportAUP.cpp:204
std::string mCurrentTag
Definition: ImportAUP.cpp:205
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: Envelope.cpp:334

References AUPImportFileHandle::node::handler, cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, Envelope::HandleXMLChild(), mCurrentTag, mHandlers, and mParentTag.

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleEnvelope()

bool AUPImportFileHandle::HandleEnvelope ( XMLTagHandler *&  handle)
private

Definition at line 1035 of file ImportAUP.cpp.

1036{
1037 struct node node = mHandlers.back();
1038
1039 if (mParentTag == "timetrack")
1040 {
1041 // If an imported timetrack was bypassed, then we want to bypass the
1042 // envelope as well. (See HandleTimeTrack and HandleControlPoint)
1043 if (node.handler)
1044 {
1045 TimeTrack *timetrack = static_cast<TimeTrack *>(node.handler);
1046
1047 handler = timetrack->GetEnvelope();
1048 }
1049 }
1050 // Earlier versions of Audacity had a single implied waveclip, so for
1051 // these versions, we get or create the only clip in the track.
1052 else if (mParentTag == "wavetrack")
1053 {
1055 }
1056 // Nested wave clips are cut lines
1057 else if (mParentTag == "waveclip")
1058 {
1059 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1060
1061 handler = waveclip->GetEnvelope();
1062 }
1063
1064 return true;
1065}
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
BoundedEnvelope * GetEnvelope()
Definition: TimeTrack.h:83
This allows multiple clips to be a part of one WaveTrack.
Definition: WaveClip.h:138
Envelope * GetEnvelope()
Definition: WaveClip.h:441

References TimeTrack::GetEnvelope(), WaveClip::GetEnvelope(), AUPImportFileHandle::node::handler, cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mHandlers, mParentTag, mWaveTrack, and WaveTrack::RightmostOrNewClip().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleImport()

bool AUPImportFileHandle::HandleImport ( XMLTagHandler *&  handle)
private

Definition at line 1336 of file ImportAUP.cpp.

1337{
1338 // Adapted from ImportXMLTagHandler::HandleXMLTag as in version 2.4.2
1339 if (mAttrs.empty() || mAttrs.front().first != "filename")
1340 return false;
1341
1342 wxString strAttr = mAttrs.front().second.ToWString();
1343
1344 if (!XMLValueChecker::IsGoodPathName(strAttr))
1345 {
1346 // Maybe strAttr is just a fileName, not the full path. Try the project data directory.
1347 wxFileNameWrapper fileName0{ GetFilename() };
1348 fileName0.SetExt({});
1349 wxFileNameWrapper fileName{
1350 fileName0.GetFullPath() + wxT("_data"), strAttr };
1351 if (XMLValueChecker::IsGoodFileName(strAttr, fileName.GetPath(wxPATH_GET_VOLUME)))
1352 strAttr = fileName.GetFullPath();
1353 else
1354 {
1355 wxLogWarning(wxT("Could not import file: %s"), strAttr);
1356 return false;
1357 }
1358 }
1359
1361 auto oldNumTracks = tracks.Size();
1362 Track *pLast = nullptr;
1363 if (oldNumTracks > 0)
1364 pLast = *tracks.rbegin();
1365
1366 // Guard this call so that C++ exceptions don't propagate through
1367 // the expat library
1369 [&] { ProjectFileManager::Get(mProject).Import(strAttr, false); },
1370 [&](AudacityException*) {});
1371
1372 if (oldNumTracks == tracks.Size())
1373 return false;
1374
1375 // Handle other attributes, now that we have the tracks.
1376 // Apply them to all new wave tracks.
1377 bool bSuccess = true;
1378
1379 auto range = tracks.Any();
1380 if (pLast) {
1381 range = range.StartingWith(pLast);
1382 ++range.first;
1383 }
1384
1385 mAttrs.erase(mAttrs.begin());
1386
1387 for (auto pTrack: range.Filter<WaveTrack>()) {
1388 // Most of the "import" tag attributes are the same as for "wavetrack" tags,
1389 // so apply them via WaveTrack::HandleXMLTag().
1390 bSuccess = pTrack->HandleXMLTag("wavetrack", mAttrs);
1391
1392 // "offset" tag is ignored in WaveTrack::HandleXMLTag except for legacy projects,
1393 // so handle it here.
1394 double dblValue;
1395 for (auto pair : mAttrs) {
1396 auto attr = pair.first;
1397 auto value = pair.second;
1398 if (attr == "offset" && value.TryGet(dblValue))
1399 pTrack->MoveTo(dblValue);
1400 }
1401 }
1402 return bSuccess;
1403}
wxT("CloseDown"))
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 auto tracks
AttributesList mAttrs
Definition: ImportAUP.cpp:206
Base class for exceptions specially processed by the application.
FilePath GetFilename() const override
bool Import(const std::vector< FilePath > &fileNames, bool addToHistory=true)
static ProjectFileManager & Get(AudacityProject &project)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:122
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347
A Track that contains audio waveform data.
Definition: WaveTrack.h:227
static bool IsGoodPathName(const FilePath &strPathName)
static bool IsGoodFileName(const FilePath &strFileName, const FilePath &strDirName={})

References TrackList::Get(), ProjectFileManager::Get(), ImportFileHandleEx::GetFilename(), GuardedCall(), ProjectFileManager::Import(), XMLValueChecker::IsGoodFileName(), XMLValueChecker::IsGoodPathName(), mAttrs, mProject, tracks, and wxT().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleLabel()

bool AUPImportFileHandle::HandleLabel ( XMLTagHandler *&  handle)
private

Definition at line 998 of file ImportAUP.cpp.

999{
1000 if (mParentTag != "labeltrack")
1001 {
1002 return false;
1003 }
1004
1005 // The parent handler also handles this tag
1006 handler = mHandlers.back().handler;
1007
1008 return true;
1009}

References cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mHandlers, and mParentTag.

Referenced by HandleXMLTag().

Here is the caller graph for this function:

◆ HandleLabelTrack()

bool AUPImportFileHandle::HandleLabelTrack ( XMLTagHandler *&  handle)
private

Definition at line 871 of file ImportAUP.cpp.

872{
873 handler = TrackList::Get(mProject).Add(std::make_shared<LabelTrack>());
874
875 return true;
876}
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1201

References TrackList::Add(), TrackList::Get(), cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, and mProject.

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleNoteTrack()

bool AUPImportFileHandle::HandleNoteTrack ( XMLTagHandler *&  handle)
private

Definition at line 878 of file ImportAUP.cpp.

879{
880#if defined(USE_MIDI)
881 handler = TrackList::Get(mProject).Add(std::make_shared<NoteTrack>());
882
883 return true;
884#else
886 XO("MIDI tracks found in project file, but this build of Audacity does not include MIDI support, bypassing track."));
887 return false;
888#endif
889}
static void ShowMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Import Project"))
Definition: ImportUtils.cpp:43

References TrackList::Add(), TrackList::Get(), cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mProject, ImportUtils::ShowMessageBox(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandlePCMAliasBlockFile()

bool AUPImportFileHandle::HandlePCMAliasBlockFile ( XMLTagHandler *&  handle)
private

Definition at line 1253 of file ImportAUP.cpp.

1254{
1255 wxString summaryFilename;
1256 wxFileName filename;
1257 sampleCount start = 0;
1258 size_t len = 0;
1259 int channel = 0;
1260 wxString name;
1261
1262 for (auto pair : mAttrs)
1263 {
1264 auto attr = pair.first;
1265 auto value = pair.second;
1266
1267 if (CaseInsensitiveEquals(attr, "aliasfile"))
1268 {
1269 const wxString strValue = value.ToWString();
1270
1271 if (XMLValueChecker::IsGoodPathName(strValue))
1272 {
1273 filename.Assign(strValue);
1274 }
1275 else if (XMLValueChecker::IsGoodFileName(strValue, mProjDir.GetPath()))
1276 {
1277 // Allow fallback of looking for the file name, located in the data directory.
1278 filename.Assign(mProjDir.GetPath(), strValue);
1279 }
1280 else if (XMLValueChecker::IsGoodPathString(strValue))
1281 {
1282 // If the aliased file is missing, we failed XMLValueChecker::IsGoodPathName()
1283 // and XMLValueChecker::IsGoodFileName, because both do existence tests.
1284 SetWarning(XO("Missing alias file %s\n\nInserting silence instead.")
1285 .Format(strValue));
1286 }
1287 }
1288 else if (CaseInsensitiveEquals(attr, "summaryfile"))
1289 {
1290 summaryFilename = value.ToWString();
1291 }
1292 else if (CaseInsensitiveEquals(attr, "aliasstart"))
1293 {
1294 long long llValue;
1295 if (!value.TryGet(llValue) || (llValue < 0))
1296 {
1297 return SetError(XO("Missing or invalid pcmaliasblockfile 'aliasstart' attribute."));
1298 }
1299
1300 start = llValue;
1301 }
1302 else if (CaseInsensitiveEquals(attr, "aliaslen"))
1303 {
1304 long lValue;
1305 if (!value.TryGet(lValue) || (lValue <= 0))
1306 {
1307 return SetError(XO("Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1308 }
1309
1310 len = lValue;
1311 }
1312 else if (CaseInsensitiveEquals(attr, "aliaschannel"))
1313 {
1314 long lValue;
1315 if (!value.TryGet(lValue) || (lValue < 0))
1316 {
1317 return SetError(XO("Missing or invalid pcmaliasblockfile 'aliaslen' attribute."));
1318 }
1319
1320 channel = lValue;
1321 }
1322 }
1323
1324 // Do not set the handler - already handled
1325
1326 if (filename.IsOk())
1327 AddFile(len, mFormat,
1328 summaryFilename, filename.GetFullPath(),
1329 start, channel);
1330 else
1331 AddFile(len, mFormat); // will add silence instead
1332
1333 return true;
1334}
const TranslatableString name
Definition: Distortion.cpp:76
sampleFormat mFormat
Definition: ImportAUP.cpp:200
wxFileName mProjDir
Definition: ImportAUP.cpp:208
bool SetError(const TranslatableString &msg)
Definition: ImportAUP.cpp:1663
void AddFile(sampleCount len, sampleFormat format, const FilePath &blockFilename=wxEmptyString, const FilePath &audioFilename=wxEmptyString, sampleCount origin=0, int channel=0)
Definition: ImportAUP.cpp:1405
static bool IsGoodPathString(const FilePath &str)
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
bool CaseInsensitiveEquals(const std::string_view &lhs, const std::string_view &rhsLower)
Definition: ImportAUP.cpp:224

References AddFile(), anonymous_namespace{ImportAUP.cpp}::CaseInsensitiveEquals(), XMLValueChecker::IsGoodFileName(), XMLValueChecker::IsGoodPathName(), XMLValueChecker::IsGoodPathString(), mAttrs, mFormat, mProjDir, name, SetError(), SetWarning(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleProject()

bool AUPImportFileHandle::HandleProject ( XMLTagHandler *&  handle)
private

Definition at line 681 of file ImportAUP.cpp.

682{
683 auto &fileMan = ProjectFileManager::Get(mProject);
684 auto &window = GetProjectFrame(mProject);
685
686 int requiredTags = 0;
687
688 for (auto pair : mAttrs)
689 {
690 auto attr = pair.first;
691 auto value = pair.second;
692
693 double dValue;
694
695#define set(f, v) (mProjectAttrs.have ## f = true, mProjectAttrs.f = v)
696
697 // ViewInfo
698 if (attr == "vpos")
699 {
700 long lValue;
701 if (!value.TryGet(lValue) || (lValue < 0))
702 {
703 return SetError(XO("Invalid project 'vpos' attribute."));
704 }
705
706 set(vpos, (int) lValue);
707 }
708 else if (attr == "h")
709 {
710 if (!value.TryGet(dValue))
711 {
712 return SetError(XO("Invalid project 'h' attribute."));
713 }
714
715 set(h, dValue);
716 }
717 else if (attr == "zoom")
718 {
719 if (!value.TryGet(dValue) || (dValue < 0.0))
720 {
721 return SetError(XO("Invalid project 'zoom' attribute."));
722 }
723
724 set(zoom, dValue);
725 }
726 // Viewinfo.SelectedRegion
727 else if (attr == "sel0")
728 {
729 if (!value.TryGet(dValue))
730 {
731 return SetError(XO("Invalid project 'sel0' attribute."));
732 }
733
734 set(sel0, dValue);
735 }
736 else if (attr == "sel1")
737 {
738 if (!value.TryGet(dValue))
739 {
740 return SetError(XO("Invalid project 'sel1' attribute."));
741 }
742
743 set(sel1, dValue);
744 }
745#ifdef EXPERIMENTAL_SPECTRAL_EDITING
746 else if (attr == "selLow")
747 {
748 if (!value.TryGet(dValue) || (dValue < 0.0))
749 {
750 return SetError(XO("Invalid project 'selLow' attribute."));
751 }
752
753 set(selLow, dValue);
754 }
755 else if (attr == "selHigh")
756 {
757 if (!value.TryGet(dValue) || (dValue < 0.0))
758 {
759 return SetError(XO("Invalid project 'selHigh' attribute."));
760 }
761
762 set(selHigh, dValue);
763 }
764#endif
765 else if (attr == "version")
766 {
767 requiredTags++;
768 }
769
770 else if (attr == "audacityversion")
771 {
772 requiredTags++;
773 }
774 else if (attr == "projname")
775 {
776 requiredTags++;
777
779 wxString altname = mProjDir.GetName() + wxT("_data");
780 mProjDir.SetFullName(wxEmptyString);
781
782 wxString projName = value.ToWString();
783 bool found = false;
784
785 // First try to load the data files based on the _data dir given in the .aup file
786 if (!projName.empty())
787 {
788 mProjDir.AppendDir(projName);
789 if (!mProjDir.DirExists())
790 {
791 mProjDir.RemoveLastDir();
792 projName.clear();
793 }
794 }
795
796 // If that fails then try to use the filename of the .aup as the base directory
797 // This is because unzipped projects e.g. those that get transferred between mac-pc
798 // may have encoding issues and end up expanding the wrong filenames for certain
799 // international characters (such as capital 'A' with an umlaut.)
800 if (projName.empty())
801 {
802 projName = altname;
803 mProjDir.AppendDir(projName);
804 if (!mProjDir.DirExists())
805 {
806 projName.clear();
807 }
808 }
809
810 // No luck...complain and bail
811 if (projName.empty())
812 {
814 XO("Couldn't find the project data folder: \"%s\"").Format(value.ToWString()));
815 return false;
816 }
817
818 // Collect and hash the file names within the project directory
819 wxArrayString files;
820 size_t cnt = wxDir::GetAllFiles(mProjDir.GetFullPath(),
821 &files,
822 "*.*");
823
824 for (const auto &fn : files)
825 {
826 mFileMap[wxFileNameFromPath(fn)] = {fn, {}};
827 }
828 }
829 else if (attr == "rate")
830 {
831 if (!value.TryGet(dValue) || (dValue < 0.0))
832 {
833 return SetError(XO("Invalid project 'selLow' attribute."));
834 }
835
836 set(rate, dValue);
837 }
838
839 else if (attr == "snapto")
840 {
841 set(snapto, (value.ToWString() == "on" ? true : false));
842 }
843
844 else if (attr == "selectionformat")
845 {
846 set(selectionformat, value.ToWString());
847 }
848
849 else if (attr == "frequencyformat")
850 {
851 set(frequencyformat, value.ToWString());
852 }
853
854 else if (attr == "bandwidthformat")
855 {
856 set(bandwidthformat, value.ToWString());
857 }
858#undef set
859 }
860
861 if (requiredTags < 3)
862 {
863 return false;
864 }
865
866 // Do not set the handler - already handled
867
868 return true;
869}
#define set(f, v)
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 ...
static const auto fn

References fn, ProjectFileManager::Get(), ImportFileHandleEx::GetFilename(), GetProjectFrame(), mAttrs, mFileMap, mProjDir, mProject, set, SetError(), ImportUtils::ShowMessageBox(), wxT(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleSequence()

bool AUPImportFileHandle::HandleSequence ( XMLTagHandler *&  handle)
private

Definition at line 1086 of file ImportAUP.cpp.

1087{
1088 struct node node = mHandlers.back();
1089
1090 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1091
1092 // Earlier versions of Audacity had a single implied waveclip, so for
1093 // these versions, we get or create the only clip in the track.
1094 if (mParentTag == "wavetrack")
1095 {
1096 XMLTagHandler *dummy;
1097 HandleWaveClip(dummy);
1098 waveclip = mClip;
1099 }
1100
1101 auto pSequence =
1102 static_cast<Sequence*>(waveclip->HandleXMLChild("sequence"));
1103
1104 for (auto pair : mAttrs) {
1105 auto attr = pair.first;
1106 auto value = pair.second;
1107
1108 if (attr == "maxsamples")
1109 {
1110 // This attribute is a sample count, so can be 64bit
1111 long long llvalue;
1112 if (!value.TryGet(llvalue) || (llvalue < 0))
1113 {
1114 return SetError(XO("Invalid sequence 'maxsamples' attribute."));
1115 }
1116
1117 // Dominic, 12/10/2006:
1118 // Let's check that maxsamples is >= 1024 and <= 64 * 1024 * 1024
1119 // - that's a pretty wide range of reasonable values.
1120 if ((llvalue < 1024) || (llvalue > 64 * 1024 * 1024))
1121 {
1122 return SetError(XO("Invalid sequence 'maxsamples' attribute."));
1123 }
1124 }
1125 else if (attr == "sampleformat")
1126 {
1127 // This attribute is a sample format, normal int
1128 long fValue;
1129 if (!value.TryGet(fValue) || (fValue < 0) || !Sequence::IsValidSampleFormat(fValue))
1130 {
1131 return SetError(XO("Invalid sequence 'sampleformat' attribute."));
1132 }
1133
1134 mFormat = (sampleFormat) fValue;
1135 // Assume old AUP format file never had wide clips
1136 pSequence->ConvertToSampleFormat(mFormat);
1137 }
1138 else if (attr == "numsamples")
1139 {
1140 // This attribute is a sample count, so can be 64bit
1141 long long llvalue;
1142 if (!value.TryGet(llvalue) || (llvalue < 0))
1143 {
1144 return SetError(XO("Invalid sequence 'numsamples' attribute."));
1145 }
1146 }
1147 }
1148
1149 // Do not set the handler - already handled
1150
1151 return true;
1152}
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
bool HandleWaveClip(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1011
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53
static bool IsValidSampleFormat(const int nValue)
true if nValue is one of the sampleFormat enum values
Definition: Sequence.cpp:1875
XMLTagHandler * HandleXMLChild(const std::string_view &tag) override
Definition: WaveClip.cpp:668
This class is an interface which should be implemented by classes which wish to be able to load and s...
Definition: XMLTagHandler.h:42

References AUPImportFileHandle::node::handler, HandleWaveClip(), WaveClip::HandleXMLChild(), Sequence::IsValidSampleFormat(), mAttrs, mClip, mFormat, mHandlers, mParentTag, SetError(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleSilentBlockFile()

bool AUPImportFileHandle::HandleSilentBlockFile ( XMLTagHandler *&  handle)
private

Definition at line 1224 of file ImportAUP.cpp.

1225{
1226 FilePath filename;
1227 size_t len = 0;
1228
1229 for (auto pair : mAttrs)
1230 {
1231 auto attr = pair.first;
1232 auto value = pair.second;
1233
1234 if (attr == "len")
1235 {
1236 long lValue;
1237 if (!value.TryGet(lValue) || !(lValue > 0))
1238 {
1239 return SetError(XO("Missing or invalid silentblockfile 'len' attribute."));
1240 }
1241
1242 len = lValue;
1243 }
1244 }
1245
1246 // Do not set the handler - already handled
1247
1248 AddFile(len, mFormat);
1249
1250 return true;
1251}
wxString FilePath
Definition: Project.h:21

References AddFile(), mAttrs, mFormat, SetError(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleSimpleBlockFile()

bool AUPImportFileHandle::HandleSimpleBlockFile ( XMLTagHandler *&  handle)
private

Definition at line 1177 of file ImportAUP.cpp.

1178{
1179 FilePath filename;
1180 size_t len = 0;
1181
1182 for (auto pair : mAttrs)
1183 {
1184 auto attr = pair.first;
1185 auto value = pair.second;
1186
1187 // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test.
1188 if (CaseInsensitiveEquals(attr, "filename"))
1189 {
1190 const wxString strValue = value.ToWString();
1191
1193 {
1194 if (mFileMap.find(strValue) != mFileMap.end())
1195 {
1196 filename = mFileMap[strValue].first;
1197 }
1198 else
1199 {
1200 SetWarning(XO("Missing project file %s\n\nInserting silence instead.")
1201 .Format(strValue));
1202 }
1203 }
1204 }
1205 else if (attr == "len")
1206 {
1207 long lValue;
1208 if (!value.TryGet(lValue) || (lValue <= 0))
1209 {
1210 return SetError(XO("Missing or invalid simpleblockfile 'len' attribute."));
1211 }
1212
1213 len = lValue;
1214 }
1215 }
1216
1217 // Do not set the handler - already handled
1218
1219 AddFile(len, mFormat, filename, filename);
1220
1221 return true;
1222}
static bool IsGoodFileString(const FilePath &str)

References AddFile(), anonymous_namespace{ImportAUP.cpp}::CaseInsensitiveEquals(), XMLValueChecker::IsGoodFileString(), mAttrs, mFileMap, mFormat, SetError(), SetWarning(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleTag()

bool AUPImportFileHandle::HandleTag ( XMLTagHandler *&  handle)
private

Definition at line 960 of file ImportAUP.cpp.

961{
962 if (mParentTag != "tags")
963 {
964 return false;
965 }
966
967 wxString n, v;
968
969 for (auto pair : mAttrs)
970 {
971 auto attr = pair.first;
972 auto value = pair.second;
973
974 if (attr == "name")
975 {
976 n = value.ToWString();
977 }
978 else if (attr == "value")
979 {
980 v = value.ToWString();
981 }
982 }
983
984 if (n == wxT("id3v2"))
985 {
986 // LLL: This is obsolete, but it must be handled and ignored.
987 }
988 else
989 {
990 mTags->SetTag(n, v);
991 }
992
993 // Do not set the handler - already handled
994
995 return true;
996}
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:431

References mAttrs, mParentTag, mTags, Tags::SetTag(), and wxT().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleTags()

bool AUPImportFileHandle::HandleTags ( XMLTagHandler *&  handle)
private

Definition at line 924 of file ImportAUP.cpp.

925{
926 wxString n;
927 wxString v;
928
929 // Support for legacy tags
930 for (auto pair : mAttrs)
931 {
932 auto attr = pair.first;
933 auto value = pair.second;
934
935 if (attr == "id3v2")
936 {
937 continue;
938 }
939 else if (attr == "track")
940 {
941 n = wxT("TRACKNUMBER");
942 }
943 else
944 {
945 n = std::string(attr);
946 n.MakeUpper();
947 }
948
949 v = value.ToWString();
950
951 if (!v.empty())
952 mTags->SetTag(n, value.ToWString());
953 }
954
955 // Do not set the handler - already handled
956
957 return true;
958}

References mAttrs, mTags, Tags::SetTag(), and wxT().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleTimeTrack()

bool AUPImportFileHandle::HandleTimeTrack ( XMLTagHandler *&  handle)
private

Definition at line 891 of file ImportAUP.cpp.

892{
894
895 // Bypass this timetrack if the project already has one
896 // (See HandleTimeEnvelope and HandleControlPoint also)
897 if (*tracks.Any<TimeTrack>().begin())
898 {
900 XO("The active project already has a time track and one was encountered in the project being imported, bypassing imported time track."));
901 return true;
902 }
903
904 handler =
905 TrackList::Get(mProject).Add(std::make_shared<TimeTrack>());
906
907 return true;
908}

References TrackList::Add(), TrackList::Get(), cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mProject, ImportUtils::ShowMessageBox(), tracks, and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleWaveBlock()

bool AUPImportFileHandle::HandleWaveBlock ( XMLTagHandler *&  handle)
private

Definition at line 1154 of file ImportAUP.cpp.

1155{
1156 for (auto pair : mAttrs)
1157 {
1158 auto attr = pair.first;
1159 auto value = pair.second;
1160
1161 if (attr == "start")
1162 {
1163 // making sure that values > 2^31 are OK because long clips will need them.
1164 long long llvalue;
1165 if (!value.TryGet(llvalue) || (llvalue < 0))
1166 {
1167 return SetError(XO("Unable to parse the waveblock 'start' attribute"));
1168 }
1169 }
1170 }
1171
1172 // Do not set the handler - already handled
1173
1174 return true;
1175}

References mAttrs, SetError(), and XO().

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleWaveClip()

bool AUPImportFileHandle::HandleWaveClip ( XMLTagHandler *&  handle)
private

Definition at line 1011 of file ImportAUP.cpp.

1012{
1013 struct node node = mHandlers.back();
1014
1015 if (mParentTag == "wavetrack")
1016 {
1017 WaveTrack *wavetrack = static_cast<WaveTrack *>(node.handler);
1018
1019 handler = wavetrack->CreateClip();
1020 }
1021 else if (mParentTag == "waveclip")
1022 {
1023 // Nested wave clips are cut lines
1024 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1025
1026 handler = waveclip->HandleXMLChild(mCurrentTag);
1027 }
1028
1029 mClip = static_cast<WaveClip *>(handler);
1030 mClips.push_back(mClip);
1031
1032 return true;
1033}
std::vector< WaveClip * > mClips
Definition: ImportAUP.cpp:215
WaveClip * CreateClip(double offset=.0, const wxString &name=wxEmptyString)
Create new clip and add it to this track.
Definition: WaveTrack.cpp:3814

References WaveTrack::CreateClip(), AUPImportFileHandle::node::handler, cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, WaveClip::HandleXMLChild(), mClip, mClips, mCurrentTag, mHandlers, and mParentTag.

Referenced by HandleSequence(), and HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleWaveTrack()

bool AUPImportFileHandle::HandleWaveTrack ( XMLTagHandler *&  handle)
private

Definition at line 910 of file ImportAUP.cpp.

911{
912 auto &trackFactory = WaveTrackFactory::Get(mProject);
914 TrackList::Get(mProject).Add(trackFactory.Create());
915
916 // No active clip. In early versions of Audacity, there was a single
917 // implied clip so we'll create a clip when the first "sequence" is
918 // found.
919 mClip = nullptr;
920
921 return true;
922}
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:4529

References TrackList::Add(), TrackList::Get(), WaveTrackFactory::Get(), cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mClip, mProject, and mWaveTrack.

Referenced by HandleXMLTag().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * AUPImportFileHandle::HandleXMLChild ( const std::string_view &  tag)
overrideprivatevirtual

Implements XMLTagHandler.

Definition at line 550 of file ImportAUP.cpp.

551{
552 return this;
553}

◆ HandleXMLEndTag()

void AUPImportFileHandle::HandleXMLEndTag ( const std::string_view &  tag)
overrideprivate

Definition at line 555 of file ImportAUP.cpp.

556{
557 if (mHasParseError)
558 {
559 return;
560 }
561
562 struct node node = mHandlers.back();
563
564 if (tag == "waveclip")
565 {
566 mClip = nullptr;
567 }
568
569 if (node.handler)
570 {
571 node.handler->HandleXMLEndTag(tag);
572 }
573
574 if (tag == "wavetrack")
576
577 mHandlers.pop_back();
578
579 if (mHandlers.size())
580 {
581 node = mHandlers.back();
582 mParentTag = node.parent;
583 mCurrentTag = node.tag;
584 }
585}
void HandleXMLEndTag(const std::string_view &tag) override
Definition: WaveClip.cpp:654
void SetLegacyFormat(sampleFormat format)
Definition: WaveTrack.cpp:2796

References AUPImportFileHandle::node::handler, XMLTagHandler::HandleXMLEndTag(), mClip, mCurrentTag, mFormat, mHandlers, mHasParseError, mParentTag, mWaveTrack, AUPImportFileHandle::node::parent, WaveTrack::SetLegacyFormat(), and AUPImportFileHandle::node::tag.

Here is the call graph for this function:

◆ HandleXMLTag()

bool AUPImportFileHandle::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overrideprivatevirtual

Implements XMLTagHandler.

Definition at line 587 of file ImportAUP.cpp.

588{
589 if (mHasParseError)
590 {
591 return false;
592 }
593
595 mCurrentTag = std::string(tag);
596 mAttrs = attrs;
597
598 XMLTagHandler *handler = nullptr;
599 bool success = false;
600
601 if (mCurrentTag == "project" ||
602 mCurrentTag == "audacityproject")
603 {
604 success = HandleProject(handler);
605 }
606 else if (mCurrentTag == "labeltrack")
607 {
608 success = HandleLabelTrack(handler);
609 }
610 else if (mCurrentTag == "notetrack")
611 {
612 success = HandleNoteTrack(handler);
613 }
614 else if (mCurrentTag == "timetrack")
615 {
616 success = HandleTimeTrack(handler);
617 }
618 else if (mCurrentTag == "wavetrack")
619 {
620 success = HandleWaveTrack(handler);
621 }
622 else if (mCurrentTag == "tags")
623 {
624 success = HandleTags(handler);
625 }
626 else if (mCurrentTag == "tag")
627 {
628 success = HandleTag(handler);
629 }
630 else if (mCurrentTag == "label")
631 {
632 success = HandleLabel(handler);
633 }
634 else if (mCurrentTag == "waveclip")
635 {
636 success = HandleWaveClip(handler);
637 }
638 else if (mCurrentTag == "sequence")
639 {
640 success = HandleSequence(handler);
641 }
642 else if (mCurrentTag == "waveblock")
643 {
644 success = HandleWaveBlock(handler);
645 }
646 else if (mCurrentTag == "envelope")
647 {
648 success = HandleEnvelope(handler);
649 }
650 else if (mCurrentTag == "controlpoint")
651 {
652 success = HandleControlPoint(handler);
653 }
654 else if (mCurrentTag == "simpleblockfile")
655 {
657 }
658 else if (mCurrentTag == "silentblockfile")
659 {
661 }
662 else if (mCurrentTag == "pcmaliasblockfile")
663 {
665 }
666 else if (mCurrentTag == "import")
667 {
668 success = HandleImport(handler);
669 }
670
671 if (!success || (handler && !handler->HandleXMLTag(tag, attrs)))
672 {
673 return SetError(XO("Internal error in importer...tag not recognized"));
674 }
675
677
678 return true;
679}
bool HandlePCMAliasBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1253
bool HandleProject(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:681
bool HandleSilentBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1224
bool HandleLabel(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:998
bool HandleWaveBlock(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1154
bool HandleLabelTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:871
bool HandleSequence(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1086
bool HandleWaveTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:910
bool HandleNoteTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:878
bool HandleTimeTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:891
bool HandleControlPoint(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1067
bool HandleImport(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1336
bool HandleTag(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:960
bool HandleSimpleBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1177
bool HandleTags(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:924
bool HandleEnvelope(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1035

References HandleControlPoint(), HandleEnvelope(), HandleImport(), HandleLabel(), HandleLabelTrack(), HandleNoteTrack(), HandlePCMAliasBlockFile(), HandleProject(), cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, HandleSequence(), HandleSilentBlockFile(), HandleSimpleBlockFile(), HandleTag(), HandleTags(), HandleTimeTrack(), HandleWaveBlock(), HandleWaveClip(), HandleWaveTrack(), mAttrs, mCurrentTag, mHandlers, mHasParseError, mParentTag, SetError(), and XO().

Here is the call graph for this function:

◆ Import()

void AUPImportFileHandle::Import ( ImportProgressListener progressListener,
WaveTrackFactory trackFactory,
TrackHolders outTracks,
Tags tags,
std::optional< LibFileFormats::AcidizerTags > &  outAcidTags 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 307 of file ImportAUP.cpp.

310{
311 BeginImport();
312
313 mHasParseError = false;
314
315 auto &history = ProjectHistory::Get(mProject);
317 auto &viewInfo = ViewInfo::Get(mProject);
318 auto &formats = ProjectNumericFormats::Get(mProject);
319
320 auto oldNumTracks = tracks.Size();
321 auto cleanup = finally([this, &tracks, oldNumTracks]{
322 if (mHasParseError || IsCancelled()) {
323 // Revoke additions of tracks
324 while (oldNumTracks < tracks.Size())
325 tracks.Remove(**tracks.end().advance(-1));
326 }
327 });
328
329 bool isDirty = history.GetDirty() || !tracks.empty();
330
331 mTotalSamples = 0;
332
333 mTags = tags;
334
335 XMLFileReader xmlFile;
336
337 bool success = xmlFile.Parse(this, GetFilename());
338 if (!success)
339 {
340 mErrorMsg = XO("Couldn't import the project:\n\n%s").Format(xmlFile.GetErrorStr());
342 return;
343 }
344
346 {
348 return;
349 }
350 if(!mErrorMsg.empty())//i.e. warning
351 {
353 mErrorMsg = {};
354 }
355
356 // (If we keep this entire source file at all)
357
358 sampleCount processed = 0;
359 for (auto fi : mFiles)
360 {
361 if(mTotalSamples.as_double() > 0)
362 progressListener.OnImportProgress(processed.as_double() / mTotalSamples.as_double());
363 if(IsCancelled())
364 {
366 return;
367 }
368 else if(IsStopped())
369 {
371 return;
372 }
373 mClip = fi.clip;
374 mWaveTrack = fi.track;
375
376 if (fi.blockFile.empty())
377 {
378 AddSilence(fi.len);
379 }
380 else
381 {
382 if (!AddSamples(fi.blockFile, fi.audioFile,
383 fi.len, fi.format, fi.origin, fi.channel))
384 {
386 return;
387 }
388 }
389
390 processed += fi.len;
391 }
392
393 for (auto pClip : mClips)
394 pClip->UpdateEnvelopeTrackLen();
395
397 tracks,
398 [&](const auto& errorMessage) { SetError(errorMessage); },
399 [&](const auto& unlinkReason) { SetWarning(XO(
400//i18n-hint: Text of the message dialog that may appear on attempt
401//to import an AUP project.
402//%s will be replaced with an explanation of the actual reason of
403//project modification.
404"%s\n"
405"This feature is not supported in Audacity versions past 3.3.3.\n"
406"These stereo tracks have been split into mono tracks.\n"
407"Please verify that everything works as intended before saving.")
408 .Format(unlinkReason));
409 }
410 );
411
413 {
415 return;
416 }
417 if(!mErrorMsg.empty())
418 {
420 mErrorMsg = {};
421 }
422
423 // If the active project is "dirty", then bypass the below updates as we don't
424 // want to going changing things the user may have already set up.
425 if (isDirty)
426 {
428 return;
429 }
430
431 if (mProjectAttrs.haverate)
433
434 if (mProjectAttrs.havesnapto)
435 {
438 }
439
440 if (mProjectAttrs.haveselectionformat)
441 {
442 formats.SetSelectionFormat(mProjectAttrs.selectionformat);
443 }
444
445 if (mProjectAttrs.haveaudiotimeformat)
446 {
447 formats.SetAudioTimeFormat(mProjectAttrs.audiotimeformat);
448 }
449
450 if (mProjectAttrs.havefrequencyformat)
451 {
452 formats.SetFrequencySelectionFormatName(mProjectAttrs.frequencyformat);
453 }
454
455 if (mProjectAttrs.havebandwidthformat)
456 {
457 formats.SetBandwidthSelectionFormatName(mProjectAttrs.bandwidthformat);
458 }
459
460 // PRL: It seems this must happen after SetSnapTo
461 if (mProjectAttrs.havevpos)
462 {
463 viewInfo.vpos = mProjectAttrs.vpos;
464 }
465
466 if (mProjectAttrs.haveh)
467 {
468 viewInfo.hpos = mProjectAttrs.h;
469 }
470
471 if (mProjectAttrs.havezoom)
472 {
473 viewInfo.SetZoom(mProjectAttrs.zoom);
474 }
475
476 if (mProjectAttrs.havesel0)
477 {
478 viewInfo.selectedRegion.setT0(mProjectAttrs.sel0);
479 }
480
481 if (mProjectAttrs.havesel1)
482 {
483 viewInfo.selectedRegion.setT1(mProjectAttrs.sel1);
484 }
485
486#ifdef EXPERIMENTAL_SPECTRAL_EDITING
487 if (mProjectAttrs.haveselLow)
488 {
489 viewInfo.selectedRegion.setF0(mProjectAttrs.selLow);
490 }
491
492 if (mProjectAttrs.haveselHigh)
493 {
494 viewInfo.selectedRegion.setF1(mProjectAttrs.selHigh);
495 }
496#endif
497
499}
bool AddSamples(const FilePath &blockFilename, const FilePath &audioFilename, sampleCount len, sampleFormat format, sampleCount origin=0, int channel=0)
Definition: ImportAUP.cpp:1448
struct AUPImportFileHandle::@135 mProjectAttrs
bool IsStopped() const noexcept
bool IsCancelled() const noexcept
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 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.
static ProjectHistory & Get(AudacityProject &project)
static ProjectNumericFormats & Get(AudacityProject &project)
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:28
void SetRate(double rate)
Definition: ProjectRate.cpp:58
void SetSnapMode(SnapMode mode)
Definition: ProjectSnap.cpp:41
static ProjectSnap & Get(AudacityProject &project)
Definition: ProjectSnap.cpp:27
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
Reads a file and passes the results through an XMLTagHandler.
Definition: XMLFileReader.h:19
const TranslatableString & GetErrorStr() const
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
double as_double() const
Definition: SampleCount.h:46

References AddSamples(), AddSilence(), sampleCount::as_double(), ImportFileHandleEx::BeginImport(), ImportProgressListener::Cancelled, TranslatableString::empty(), ImportProgressListener::Error, ProjectFileManager::FixTracks(), ProjectNumericFormats::Get(), ProjectHistory::Get(), ProjectRate::Get(), ProjectSnap::Get(), ViewInfo::Get(), TrackList::Get(), XMLFileReader::GetErrorStr(), ImportFileHandleEx::GetFilename(), ImportFileHandleEx::IsCancelled(), ImportFileHandleEx::IsStopped(), mClip, mClips, mErrorMsg, mFiles, mHasParseError, mProject, mProjectAttrs, mTags, mTotalSamples, mWaveTrack, ImportProgressListener::OnImportProgress(), ImportProgressListener::OnImportResult(), XMLFileReader::Parse(), SetError(), ProjectRate::SetRate(), ProjectSnap::SetSnapMode(), SetWarning(), ImportUtils::ShowMessageBox(), SNAP_NEAREST, SNAP_OFF, ImportProgressListener::Stopped, ImportProgressListener::Success, tracks, and XO().

Here is the call graph for this function:

◆ Open()

bool AUPImportFileHandle::Open ( )

Definition at line 516 of file ImportAUP.cpp.

517{
518 wxFFile ff(GetFilename(), wxT("rb"));
519 if (ff.IsOpened())
520 {
521 char buf[256];
522
523 int numRead = ff.Read(buf, sizeof(buf));
524
525 ff.Close();
526
527 buf[sizeof(buf) - 1] = '\0';
528
529 if (!wxStrncmp(buf, wxT("AudacityProject"), 15))
530 {
532 XO("This project was saved by Audacity version 1.0 or earlier. The format has\n"
533 "changed and this version of Audacity is unable to import the project.\n\n"
534 "Use a version of Audacity prior to v3.0.0 to upgrade the project and then\n"
535 "you may import it with this version of Audacity."));
536 return false;
537 }
538
539 if (wxStrncmp(buf, "<?xml", 5) == 0 &&
540 (wxStrstr(buf, "<audacityproject") ||
541 wxStrstr(buf, "<project") ))
542 {
543 return true;
544 }
545 }
546
547 return false;
548}

References ImportFileHandleEx::GetFilename(), ImportUtils::ShowMessageBox(), wxT(), and XO().

Here is the call graph for this function:

◆ SetError()

bool AUPImportFileHandle::SetError ( const TranslatableString msg)
private

Definition at line 1663 of file ImportAUP.cpp.

1664{
1665 wxLogError(msg.Debug());
1666
1667 if (mErrorMsg.empty() || !mHasParseError)
1668 {
1669 mErrorMsg = msg;
1670 }
1671
1672 mHasParseError = true;
1673 return false;
1674}
wxString Debug() const
Format as an English string for debugging logs and developers' eyes, not for end users.

References TranslatableString::Debug(), TranslatableString::empty(), mErrorMsg, and mHasParseError.

Referenced by HandlePCMAliasBlockFile(), HandleProject(), HandleSequence(), HandleSilentBlockFile(), HandleSimpleBlockFile(), HandleWaveBlock(), HandleXMLTag(), and Import().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetStreamUsage()

void AUPImportFileHandle::SetStreamUsage ( wxInt32   WXUNUSEDStreamID,
bool   WXUNUSEDUse 
)
override

Definition at line 512 of file ImportAUP.cpp.

513{
514}

◆ SetWarning()

bool AUPImportFileHandle::SetWarning ( const TranslatableString msg)
private

Definition at line 1676 of file ImportAUP.cpp.

1677{
1678 wxLogWarning(msg.Debug());
1679
1680 if (mErrorMsg.empty())
1681 {
1682 mErrorMsg = msg;
1683 }
1684
1685 return false;
1686}

References TranslatableString::Debug(), TranslatableString::empty(), and mErrorMsg.

Referenced by AddSamples(), HandlePCMAliasBlockFile(), HandleSimpleBlockFile(), and Import().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mAttrs

AttributesList AUPImportFileHandle::mAttrs
private

◆ mClip

WaveClip* AUPImportFileHandle::mClip
private

◆ mClips

std::vector<WaveClip *> AUPImportFileHandle::mClips
private

Definition at line 215 of file ImportAUP.cpp.

Referenced by HandleWaveClip(), and Import().

◆ mCurrentTag

std::string AUPImportFileHandle::mCurrentTag
private

Definition at line 205 of file ImportAUP.cpp.

Referenced by HandleControlPoint(), HandleWaveClip(), HandleXMLEndTag(), and HandleXMLTag().

◆ mErrorMsg

TranslatableString AUPImportFileHandle::mErrorMsg
private

Definition at line 217 of file ImportAUP.cpp.

Referenced by GetErrorMessage(), Import(), SetError(), and SetWarning().

◆ mFileMap

BlockFileMap AUPImportFileHandle::mFileMap
private

Definition at line 211 of file ImportAUP.cpp.

Referenced by AddSamples(), HandleProject(), and HandleSimpleBlockFile().

◆ mFiles

std::vector<fileinfo> AUPImportFileHandle::mFiles
private

Definition at line 197 of file ImportAUP.cpp.

Referenced by AddFile(), and Import().

◆ mFormat

sampleFormat AUPImportFileHandle::mFormat
private

◆ mHandlers

stack AUPImportFileHandle::mHandlers
private

◆ mHasParseError

bool AUPImportFileHandle::mHasParseError { false }
private

Definition at line 218 of file ImportAUP.cpp.

Referenced by HandleXMLEndTag(), HandleXMLTag(), Import(), and SetError().

◆ mNumChannels

unsigned long AUPImportFileHandle::mNumChannels
private

Definition at line 201 of file ImportAUP.cpp.

◆ mParentTag

std::string AUPImportFileHandle::mParentTag
private

◆ mProjDir

wxFileName AUPImportFileHandle::mProjDir
private

Definition at line 208 of file ImportAUP.cpp.

Referenced by HandlePCMAliasBlockFile(), and HandleProject().

◆ mProject

AudacityProject& AUPImportFileHandle::mProject
private

◆ 

struct { ... } AUPImportFileHandle::mProjectAttrs

Referenced by Import().

◆ mTags

Tags* AUPImportFileHandle::mTags
private

Definition at line 161 of file ImportAUP.cpp.

Referenced by HandleTag(), HandleTags(), and Import().

◆ mTotalSamples

sampleCount AUPImportFileHandle::mTotalSamples
private

Definition at line 198 of file ImportAUP.cpp.

Referenced by AddFile(), and Import().

◆ mWaveTrack

WaveTrack* AUPImportFileHandle::mWaveTrack
private

The documentation for this class was generated from the following file: