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) 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)=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 1408 of file ImportAUP.cpp.

1414{
1415 fileinfo fi = {};
1416 fi.track = mWaveTrack;
1417 fi.clip = mClip;
1418 fi.blockFile = blockFilename;
1419 fi.audioFile = audioFilename;
1420 fi.len = len;
1421 fi.format = format,
1422 fi.origin = origin,
1423 fi.channel = channel;
1424
1425 mFiles.push_back(fi);
1426
1427 mTotalSamples += len;
1428}
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 1451 of file ImportAUP.cpp.

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

1431{
1432 wxASSERT(mClip || mWaveTrack);
1433
1434 if (mClip)
1435 {
1437 }
1438 else if (mWaveTrack)
1439 {
1440 // Assume alignment of clips and insert silence into leader only
1441 if (mWaveTrack->IsLeader())
1444 }
1445
1446 return true;
1447}
double GetPlayEndTime() const override
Definition: WaveClip.cpp:1267
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Definition: WaveClip.cpp:778
void InsertSilence(double t, double len) override
Definition: WaveTrack.cpp:2434
bool IsLeader() const override
Definition: WaveTrack.cpp:2778
double GetEndTime() const override
Implement WideSampleSequence.
Definition: WaveTrack.cpp:3050
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 502 of file ImportAUP.cpp.

503{
504 return 1;
505}

◆ GetStreamInfo()

const TranslatableStrings & AUPImportFileHandle::GetStreamInfo ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 507 of file ImportAUP.cpp.

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

◆ HandleControlPoint()

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

Definition at line 1068 of file ImportAUP.cpp.

1069{
1070 struct node node = mHandlers.back();
1071
1072 if (mParentTag == "envelope")
1073 {
1074 // If an imported timetrack was bypassed, then we want to bypass the
1075 // control points as well. (See HandleTimeTrack and HandleEnvelope)
1076 if (node.handler)
1077 {
1078 Envelope *envelope = static_cast<Envelope *>(node.handler);
1079
1080 handler = envelope->HandleXMLChild(mCurrentTag);
1081 }
1082 }
1083
1084 return true;
1085}
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 1036 of file ImportAUP.cpp.

1037{
1038 struct node node = mHandlers.back();
1039
1040 if (mParentTag == "timetrack")
1041 {
1042 // If an imported timetrack was bypassed, then we want to bypass the
1043 // envelope as well. (See HandleTimeTrack and HandleControlPoint)
1044 if (node.handler)
1045 {
1046 TimeTrack *timetrack = static_cast<TimeTrack *>(node.handler);
1047
1048 handler = timetrack->GetEnvelope();
1049 }
1050 }
1051 // Earlier versions of Audacity had a single implied waveclip, so for
1052 // these versions, we get or create the only clip in the track.
1053 else if (mParentTag == "wavetrack")
1054 {
1056 }
1057 // Nested wave clips are cut lines
1058 else if (mParentTag == "waveclip")
1059 {
1060 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1061
1062 handler = waveclip->GetEnvelope();
1063 }
1064
1065 return true;
1066}
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:103
Envelope * GetEnvelope()
Definition: WaveClip.h:388

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 1337 of file ImportAUP.cpp.

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

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

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 872 of file ImportAUP.cpp.

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

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 879 of file ImportAUP.cpp.

880{
881#if defined(USE_MIDI)
882 handler = TrackList::Get(mProject).Add(std::make_shared<NoteTrack>());
883
884 return true;
885#else
887 XO("MIDI tracks found in project file, but this build of Audacity does not include MIDI support, bypassing track."));
888 return false;
889#endif
890}
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 1254 of file ImportAUP.cpp.

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

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

1088{
1089 struct node node = mHandlers.back();
1090
1091 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1092
1093 // Earlier versions of Audacity had a single implied waveclip, so for
1094 // these versions, we get or create the only clip in the track.
1095 if (mParentTag == "wavetrack")
1096 {
1097 XMLTagHandler *dummy;
1098 HandleWaveClip(dummy);
1099 waveclip = mClip;
1100 }
1101
1102 auto pSequence =
1103 static_cast<Sequence*>(waveclip->HandleXMLChild("sequence"));
1104
1105 for (auto pair : mAttrs) {
1106 auto attr = pair.first;
1107 auto value = pair.second;
1108
1109 if (attr == "maxsamples")
1110 {
1111 // This attribute is a sample count, so can be 64bit
1112 long long llvalue;
1113 if (!value.TryGet(llvalue) || (llvalue < 0))
1114 {
1115 return SetError(XO("Invalid sequence 'maxsamples' attribute."));
1116 }
1117
1118 // Dominic, 12/10/2006:
1119 // Let's check that maxsamples is >= 1024 and <= 64 * 1024 * 1024
1120 // - that's a pretty wide range of reasonable values.
1121 if ((llvalue < 1024) || (llvalue > 64 * 1024 * 1024))
1122 {
1123 return SetError(XO("Invalid sequence 'maxsamples' attribute."));
1124 }
1125 }
1126 else if (attr == "sampleformat")
1127 {
1128 // This attribute is a sample format, normal int
1129 long fValue;
1130 if (!value.TryGet(fValue) || (fValue < 0) || !Sequence::IsValidSampleFormat(fValue))
1131 {
1132 return SetError(XO("Invalid sequence 'sampleformat' attribute."));
1133 }
1134
1135 mFormat = (sampleFormat) fValue;
1136 // Assume old AUP format file never had wide clips
1137 pSequence->ConvertToSampleFormat(mFormat);
1138 }
1139 else if (attr == "numsamples")
1140 {
1141 // This attribute is a sample count, so can be 64bit
1142 long long llvalue;
1143 if (!value.TryGet(llvalue) || (llvalue < 0))
1144 {
1145 return SetError(XO("Invalid sequence 'numsamples' attribute."));
1146 }
1147 }
1148 }
1149
1150 // Do not set the handler - already handled
1151
1152 return true;
1153}
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:1012
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:613
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 1225 of file ImportAUP.cpp.

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

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

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

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 925 of file ImportAUP.cpp.

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

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 892 of file ImportAUP.cpp.

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

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 1155 of file ImportAUP.cpp.

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

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 1012 of file ImportAUP.cpp.

1013{
1014 struct node node = mHandlers.back();
1015
1016 if (mParentTag == "wavetrack")
1017 {
1018 WaveTrack *wavetrack = static_cast<WaveTrack *>(node.handler);
1019
1020 handler = wavetrack->CreateClip();
1021 }
1022 else if (mParentTag == "waveclip")
1023 {
1024 // Nested wave clips are cut lines
1025 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1026
1027 handler = waveclip->HandleXMLChild(mCurrentTag);
1028 }
1029
1030 mClip = static_cast<WaveClip *>(handler);
1031 mClips.push_back(mClip);
1032
1033 return true;
1034}
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:3760

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 911 of file ImportAUP.cpp.

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

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 551 of file ImportAUP.cpp.

552{
553 return this;
554}

◆ HandleXMLEndTag()

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

Definition at line 556 of file ImportAUP.cpp.

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

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 588 of file ImportAUP.cpp.

589{
590 if (mHasParseError)
591 {
592 return false;
593 }
594
596 mCurrentTag = std::string(tag);
597 mAttrs = attrs;
598
599 XMLTagHandler *handler = nullptr;
600 bool success = false;
601
602 if (mCurrentTag == "project" ||
603 mCurrentTag == "audacityproject")
604 {
605 success = HandleProject(handler);
606 }
607 else if (mCurrentTag == "labeltrack")
608 {
609 success = HandleLabelTrack(handler);
610 }
611 else if (mCurrentTag == "notetrack")
612 {
613 success = HandleNoteTrack(handler);
614 }
615 else if (mCurrentTag == "timetrack")
616 {
617 success = HandleTimeTrack(handler);
618 }
619 else if (mCurrentTag == "wavetrack")
620 {
621 success = HandleWaveTrack(handler);
622 }
623 else if (mCurrentTag == "tags")
624 {
625 success = HandleTags(handler);
626 }
627 else if (mCurrentTag == "tag")
628 {
629 success = HandleTag(handler);
630 }
631 else if (mCurrentTag == "label")
632 {
633 success = HandleLabel(handler);
634 }
635 else if (mCurrentTag == "waveclip")
636 {
637 success = HandleWaveClip(handler);
638 }
639 else if (mCurrentTag == "sequence")
640 {
641 success = HandleSequence(handler);
642 }
643 else if (mCurrentTag == "waveblock")
644 {
645 success = HandleWaveBlock(handler);
646 }
647 else if (mCurrentTag == "envelope")
648 {
649 success = HandleEnvelope(handler);
650 }
651 else if (mCurrentTag == "controlpoint")
652 {
653 success = HandleControlPoint(handler);
654 }
655 else if (mCurrentTag == "simpleblockfile")
656 {
658 }
659 else if (mCurrentTag == "silentblockfile")
660 {
662 }
663 else if (mCurrentTag == "pcmaliasblockfile")
664 {
666 }
667 else if (mCurrentTag == "import")
668 {
669 success = HandleImport(handler);
670 }
671
672 if (!success || (handler && !handler->HandleXMLTag(tag, attrs)))
673 {
674 return SetError(XO("Internal error in importer...tag not recognized"));
675 }
676
678
679 return true;
680}
bool HandlePCMAliasBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1254
bool HandleProject(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:682
bool HandleSilentBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1225
bool HandleLabel(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:999
bool HandleWaveBlock(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1155
bool HandleLabelTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:872
bool HandleSequence(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1087
bool HandleWaveTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:911
bool HandleNoteTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:879
bool HandleTimeTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:892
bool HandleControlPoint(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1068
bool HandleImport(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1337
bool HandleTag(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:961
bool HandleSimpleBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1178
bool HandleTags(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:925
bool HandleEnvelope(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1036

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 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 307 of file ImportAUP.cpp.

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

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

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 1666 of file ImportAUP.cpp.

1667{
1668 wxLogError(msg.Debug());
1669
1670 if (mErrorMsg.empty() || !mHasParseError)
1671 {
1672 mErrorMsg = msg;
1673 }
1674
1675 mHasParseError = true;
1676 return false;
1677}
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 513 of file ImportAUP.cpp.

514{
515}

◆ SetWarning()

bool AUPImportFileHandle::SetWarning ( const TranslatableString msg)
private

Definition at line 1679 of file ImportAUP.cpp.

1680{
1681 wxLogWarning(msg.Debug());
1682
1683 if (mErrorMsg.empty())
1684 {
1685 mErrorMsg = msg;
1686 }
1687
1688 return false;
1689}

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: