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

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

◆ ~AUPImportFileHandle()

AUPImportFileHandle::~AUPImportFileHandle ( )

Definition at line 285 of file ImportAUP.cpp.

286{
287}

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

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

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

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

1425{
1426 wxASSERT(mClip || mWaveTrack);
1427
1428 if (mClip)
1429 {
1431 }
1432 else if (mWaveTrack)
1433 {
1436 }
1437
1438 return true;
1439}
double GetPlayEndTime() const override
Definition: WaveClip.cpp:1766
void InsertSilence(double t, double len, double *pEnvelopeValue=nullptr)
Definition: WaveClip.cpp:1229
void InsertSilence(double t, double len) override
Definition: WaveTrack.cpp:2002
double GetEndTime() const override
Implement WideSampleSequence.
Definition: WaveTrack.cpp:2586
double LongSamplesToTime(sampleCount pos) const

References WaveTrack::GetEndTime(), WaveClip::GetPlayEndTime(), WaveTrack::InsertSilence(), WaveClip::InsertSilence(), 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 294 of file ImportAUP.cpp.

295{
296 return mErrorMsg;
297}
TranslatableString mErrorMsg
Definition: ImportAUP.cpp:215

References mErrorMsg.

◆ GetFileDescription()

TranslatableString AUPImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 289 of file ImportAUP.cpp.

290{
291 return DESC;
292}
#define DESC
Definition: ImportAUP.cpp:54

References DESC.

◆ GetFileUncompressedBytes()

auto AUPImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 299 of file ImportAUP.cpp.

300{
301 // TODO: Get Uncompressed byte count.
302 return 0;
303}

◆ GetStreamCount()

wxInt32 AUPImportFileHandle::GetStreamCount ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 497 of file ImportAUP.cpp.

498{
499 return 1;
500}

◆ GetStreamInfo()

const TranslatableStrings & AUPImportFileHandle::GetStreamInfo ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 502 of file ImportAUP.cpp.

503{
504 static TranslatableStrings empty;
505 return empty;
506}
std::vector< TranslatableString > TranslatableStrings

◆ HandleControlPoint()

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

Definition at line 1064 of file ImportAUP.cpp.

1065{
1066 struct node node = mHandlers.back();
1067
1068 if (mParentTag == "envelope")
1069 {
1070 // If an imported timetrack was bypassed, then we want to bypass the
1071 // control points as well. (See HandleTimeTrack and HandleEnvelope)
1072 if (node.handler)
1073 {
1074 Envelope *envelope = static_cast<Envelope *>(node.handler);
1075
1076 handler = envelope->HandleXMLChild(mCurrentTag);
1077 }
1078 }
1079
1080 return true;
1081}
std::string mParentTag
Definition: ImportAUP.cpp:202
std::string mCurrentTag
Definition: ImportAUP.cpp:203
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:346

References AUPImportFileHandle::node::handler, audacity::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 1031 of file ImportAUP.cpp.

1032{
1033 struct node node = mHandlers.back();
1034
1035 if (mParentTag == "timetrack")
1036 {
1037 // If an imported timetrack was bypassed, then we want to bypass the
1038 // envelope as well. (See HandleTimeTrack and HandleControlPoint)
1039 if (node.handler)
1040 {
1041 TimeTrack *timetrack = static_cast<TimeTrack *>(node.handler);
1042
1043 handler = timetrack->GetEnvelope();
1044 }
1045 }
1046 // Earlier versions of Audacity had a single implied waveclip, so for
1047 // these versions, we get or create the only clip in the track.
1049 {
1050 handler = &(*mWaveTrack->RightmostOrNewClip()->Channels().begin())
1051 ->GetEnvelope();
1052 }
1053 // Nested wave clips are cut lines
1055 {
1056 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1057
1058 handler = &waveclip->GetEnvelope();
1059 }
1060
1061 return true;
1062}
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:238
Envelope & GetEnvelope() noexcept
Definition: WaveClip.h:553
static const char * WaveClip_tag
Definition: WaveClip.h:249
static const char * WaveTrack_tag
Definition: WaveTrack.h:206

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

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

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

993{
994 if (mParentTag != "labeltrack")
995 {
996 return false;
997 }
998
999 // The parent handler also handles this tag
1000 handler = mHandlers.back().handler;
1001
1002 return true;
1003}

References audacity::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 865 of file ImportAUP.cpp.

866{
867 handler = TrackList::Get(mProject).Add(std::make_shared<LabelTrack>());
868
869 return true;
870}
TrackKind * Add(const std::shared_ptr< TrackKind > &t, bool assignIds=true)
Definition: Track.h:1048

References TrackList::Add(), TrackList::Get(), audacity::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 872 of file ImportAUP.cpp.

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

References TrackList::Add(), TrackList::Get(), audacity::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 1250 of file ImportAUP.cpp.

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

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

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

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

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

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

955{
956 if (mParentTag != "tags")
957 {
958 return false;
959 }
960
961 wxString n, v;
962
963 for (auto pair : mAttrs)
964 {
965 auto attr = pair.first;
966 auto value = pair.second;
967
968 if (attr == "name")
969 {
970 n = value.ToWString();
971 }
972 else if (attr == "value")
973 {
974 v = value.ToWString();
975 }
976 }
977
978 if (n == wxT("id3v2"))
979 {
980 // LLL: This is obsolete, but it must be handled and ignored.
981 }
982 else
983 {
984 mTags->SetTag(n, v);
985 }
986
987 // Do not set the handler - already handled
988
989 return true;
990}
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 918 of file ImportAUP.cpp.

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

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

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

References TrackList::Add(), TrackList::Get(), audacity::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 1151 of file ImportAUP.cpp.

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

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

1006{
1007 struct node node = mHandlers.back();
1008
1010 {
1011 WaveTrack *wavetrack = static_cast<WaveTrack *>(node.handler);
1012
1013 const auto pInterval = wavetrack->CreateClip();
1014 wavetrack->InsertInterval(pInterval, true, true);
1015 handler = pInterval.get();
1016 }
1018 {
1019 // Nested wave clips are cut lines
1020 WaveClip *waveclip = static_cast<WaveClip *>(node.handler);
1021
1022 handler = waveclip->HandleXMLChild(mCurrentTag);
1023 }
1024
1025 mClip = static_cast<WaveClip *>(handler);
1026 mClips.push_back(mClip);
1027
1028 return true;
1029}
std::vector< WaveClip * > mClips
Definition: ImportAUP.cpp:213
IntervalHolder CreateClip(double offset=.0, const wxString &name=wxEmptyString, const Interval *pToCopy=nullptr, bool copyCutlines=true)
Definition: WaveTrack.cpp:2934
void InsertInterval(const IntervalHolder &interval, bool newClip, bool allowEmpty=false)
Definition: WaveTrack.cpp:3208

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

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

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

References TrackList::Add(), TrackList::Get(), WaveTrackFactory::Get(), audacity::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 546 of file ImportAUP.cpp.

547{
548 return this;
549}

◆ HandleXMLEndTag()

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

Definition at line 551 of file ImportAUP.cpp.

552{
553 if (mHasParseError)
554 {
555 return;
556 }
557
558 struct node node = mHandlers.back();
559
560 if (tag == WaveClip::WaveClip_tag)
561 {
562 mClip = nullptr;
563 }
564
565 if (node.handler)
566 {
567 node.handler->HandleXMLEndTag(tag);
568 }
569
570 if (tag == WaveTrack::WaveTrack_tag)
572
573 mHandlers.pop_back();
574
575 if (mHandlers.size())
576 {
577 node = mHandlers.back();
578 mParentTag = node.parent;
579 mCurrentTag = node.tag;
580 }
581}
void HandleXMLEndTag(const std::string_view &tag) override
Definition: WaveClip.cpp:1020
void SetLegacyFormat(sampleFormat format)
Definition: WaveTrack.cpp:2308

References AUPImportFileHandle::node::handler, XMLTagHandler::HandleXMLEndTag(), mClip, mCurrentTag, mFormat, mHandlers, mHasParseError, mParentTag, mWaveTrack, AUPImportFileHandle::node::parent, WaveTrack::SetLegacyFormat(), AUPImportFileHandle::node::tag, WaveClip::WaveClip_tag, and WaveTrack::WaveTrack_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 583 of file ImportAUP.cpp.

584{
585 if (mHasParseError)
586 {
587 return false;
588 }
589
591 mCurrentTag = std::string(tag);
592 mAttrs = attrs;
593
594 XMLTagHandler *handler = nullptr;
595 bool success = false;
596
597 if (mCurrentTag == "project" ||
598 mCurrentTag == "audacityproject")
599 {
600 success = HandleProject(handler);
601 }
602 else if (mCurrentTag == "labeltrack")
603 {
604 success = HandleLabelTrack(handler);
605 }
606 else if (mCurrentTag == "notetrack")
607 {
608 success = HandleNoteTrack(handler);
609 }
610 else if (mCurrentTag == "timetrack")
611 {
612 success = HandleTimeTrack(handler);
613 }
615 {
616 success = HandleWaveTrack(handler);
617 }
618 else if (mCurrentTag == "tags")
619 {
620 success = HandleTags(handler);
621 }
622 else if (mCurrentTag == "tag")
623 {
624 success = HandleTag(handler);
625 }
626 else if (mCurrentTag == "label")
627 {
628 success = HandleLabel(handler);
629 }
631 {
632 success = HandleWaveClip(handler);
633 }
635 {
636 success = HandleSequence(handler);
637 }
639 {
640 success = HandleWaveBlock(handler);
641 }
642 else if (mCurrentTag == "envelope")
643 {
644 success = HandleEnvelope(handler);
645 }
646 else if (mCurrentTag == "controlpoint")
647 {
648 success = HandleControlPoint(handler);
649 }
650 else if (mCurrentTag == "simpleblockfile")
651 {
653 }
654 else if (mCurrentTag == "silentblockfile")
655 {
657 }
658 else if (mCurrentTag == "pcmaliasblockfile")
659 {
661 }
662 else if (mCurrentTag == "import")
663 {
664 success = HandleImport(handler);
665 }
666
667 if (!success || (handler && !handler->HandleXMLTag(tag, attrs)))
668 {
669 return SetError(XO("Internal error in importer...tag not recognized"));
670 }
671
673
674 return true;
675}
bool HandlePCMAliasBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1250
bool HandleProject(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:677
bool HandleSilentBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1221
bool HandleLabel(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:992
bool HandleWaveBlock(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1151
bool HandleLabelTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:865
bool HandleSequence(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1083
bool HandleWaveTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:904
bool HandleNoteTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:872
bool HandleTimeTrack(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:885
bool HandleControlPoint(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1064
bool HandleImport(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1333
bool HandleTag(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:954
bool HandleSimpleBlockFile(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1174
bool HandleTags(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:918
bool HandleEnvelope(XMLTagHandler *&handle)
Definition: ImportAUP.cpp:1031
static const char * WaveBlock_tag
Definition: Sequence.h:57

References HandleControlPoint(), HandleEnvelope(), HandleImport(), HandleLabel(), HandleLabelTrack(), HandleNoteTrack(), HandlePCMAliasBlockFile(), HandleProject(), audacity::cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, HandleSequence(), HandleSilentBlockFile(), HandleSimpleBlockFile(), HandleTag(), HandleTags(), HandleTimeTrack(), HandleWaveBlock(), HandleWaveClip(), HandleWaveTrack(), mAttrs, mCurrentTag, mHandlers, mHasParseError, mParentTag, Sequence::Sequence_tag, SetError(), Sequence::WaveBlock_tag, WaveClip::WaveClip_tag, WaveTrack::WaveTrack_tag, 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 305 of file ImportAUP.cpp.

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

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

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

1659{
1660 wxLogError(msg.Debug());
1661
1662 if (mErrorMsg.empty() || !mHasParseError)
1663 {
1664 mErrorMsg = msg;
1665 }
1666
1667 mHasParseError = true;
1668 return false;
1669}
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 508 of file ImportAUP.cpp.

509{
510}

◆ SetWarning()

bool AUPImportFileHandle::SetWarning ( const TranslatableString msg)
private

Definition at line 1671 of file ImportAUP.cpp.

1672{
1673 wxLogWarning(msg.Debug());
1674
1675 if (mErrorMsg.empty())
1676 {
1677 mErrorMsg = msg;
1678 }
1679
1680 return false;
1681}

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

Referenced by HandleWaveClip(), and Import().

◆ mCurrentTag

std::string AUPImportFileHandle::mCurrentTag
private

Definition at line 203 of file ImportAUP.cpp.

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

◆ mErrorMsg

TranslatableString AUPImportFileHandle::mErrorMsg
private

Definition at line 215 of file ImportAUP.cpp.

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

◆ mFileMap

BlockFileMap AUPImportFileHandle::mFileMap
private

Definition at line 209 of file ImportAUP.cpp.

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

◆ mFiles

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

Definition at line 195 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 216 of file ImportAUP.cpp.

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

◆ mNumChannels

unsigned long AUPImportFileHandle::mNumChannels
private

Definition at line 199 of file ImportAUP.cpp.

◆ mParentTag

std::string AUPImportFileHandle::mParentTag
private

◆ mProjDir

wxFileName AUPImportFileHandle::mProjDir
private

Definition at line 206 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 196 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: