Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
LOFImportFileHandle Class Referencefinal

An ImportFileHandle for LOF data. More...

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

Public Member Functions

 LOFImportFileHandle (AudacityProject *pProject, const FilePath &name, std::unique_ptr< wxTextFile > &&file)
 
 ~LOFImportFileHandle ()
 
TranslatableString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
ProgressResult Import (WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
 
wxInt32 GetStreamCount () override
 
const TranslatableStringsGetStreamInfo () override
 
void SetStreamUsage (wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
 
- Public Member Functions inherited from ImportFileHandle
 ImportFileHandle (const FilePath &filename)
 
virtual ~ImportFileHandle ()
 
void CreateProgress ()
 
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 ProgressResult Import (WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags)=0
 

Private Member Functions

void lofOpenFiles (wxString *ln)
 Processes a single line from a LOF text file, doing whatever is indicated on the line. More...
 
void doDurationAndScrollOffset ()
 

Private Attributes

std::unique_ptr< wxTextFile > mTextFile
 
wxFileName mLOFFileName
 
AudacityProjectmProject {}
 
int nFilesInGroup { 0 }
 
bool callDurationFactor { false }
 
double durationFactor { 1 }
 
bool callScrollOffset { false }
 
double scrollOffset { 0 }
 

Additional Inherited Members

- Public Types inherited from ImportFileHandle
using ProgressResult = BasicUI::ProgressResult
 
using ByteCount = unsigned long long
 
- Static Public Member Functions inherited from ImportFileHandle
static sampleFormat ChooseFormat (sampleFormat effectiveFormat)
 Choose appropriate format, which will not be narrower than the specified one. More...
 
- Protected Member Functions inherited from ImportFileHandle
std::shared_ptr< WaveTrackNewWaveTrack (WaveTrackFactory &trackFactory, sampleFormat effectiveFormat, double rate)
 Build a wave track with appropriate format, which will not be narrower than the specified one. More...
 
- Protected Attributes inherited from ImportFileHandle
FilePath mFilename
 
std::unique_ptr< ProgressDialogmProgress
 

Detailed Description

An ImportFileHandle for LOF data.

Supports the opening of ".lof" files which are text files that contain a list of individual files to open in audacity in specific formats. Files may be file names (in the same directory as the LOF file), absolute paths or relative paths relative to the directory of the LOF file.

(In BNF) The syntax for an LOF file, denoted by <lof>:

  <lof> ::= [<window> | <file> | <#>]*
  <window> ::= window [<window-parameter>]* <newline>
  <window-parameter> ::= offset <time> | duration <time>
  <time> ::= [<digit>]+ [ . [<digit>]* ]
  <file> ::= file [<file-parameter>]* <newline>
  <file-parameter> ::= offset <time>
  <#> ::= <comment> <newline>

EXAMPLE LOF file:

  # everything following the hash character is ignored
  window # an initial window command is implicit and optional
  file "C:\folder1\sample1.wav"    # sample1.wav is displayed
  file "C:\sample2.wav" offset 5   # sample2 is displayed with a 5s offset
  File "C:\sample3.wav"            # sample3 is displayed with no offset
  File "foo.aiff" # foo is loaded from the same directory as the LOF file
  window offset 5 duration 10      # open a NEW window, zoom to display
  # 10 seconds total starting at 5 (ending at 15) seconds
  file "C:\sample3.wav" offset 2.5

SEMANTICS:

There are two commands: "window" creates a NEW window, and "file" appends a track to the current window and displays the file there. The first file is always placed in a NEW window, whether or not an initial "window" command is given.

Commands have optional keyword parameters that may be listed in any order. A parameter should only occur once per command. The "offset" parameter specifies a time offset. For windows, this is the leftmost time displayed in the window. For files, the offset is an amount by which the file is shifted in time before display (only enabled for audio; not midi). The offset is specified as an integer or decimal number of seconds, and the default value is zero.

Windows may also have a "duration" parameter, which specifies how much time should be displayed in the window. The default duration is equal to the duration of the longest track currently displayed.

Definition at line 118 of file ImportLOF.cpp.

Constructor & Destructor Documentation

◆ LOFImportFileHandle()

LOFImportFileHandle::LOFImportFileHandle ( AudacityProject pProject,
const FilePath name,
std::unique_ptr< wxTextFile > &&  file 
)

Definition at line 163 of file ImportLOF.cpp.

166 , mTextFile(std::move(file))
168 , mProject{ pProject }
169{
170}
const TranslatableString name
Definition: Distortion.cpp:74
ImportFileHandle(const FilePath &filename)
std::unique_ptr< wxTextFile > mTextFile
Definition: ImportLOF.cpp:146
AudacityProject * mProject
Definition: ImportLOF.cpp:149
wxFileName mLOFFileName
Definition: ImportLOF.cpp:147

◆ ~LOFImportFileHandle()

LOFImportFileHandle::~LOFImportFileHandle ( )

Definition at line 567 of file ImportLOF.cpp.

568{
569}

Member Function Documentation

◆ doDurationAndScrollOffset()

void LOFImportFileHandle::doDurationAndScrollOffset ( )
private

Definition at line 541 of file ImportLOF.cpp.

542{
543 if (!mProject)
544 return;
545
547 bool doSomething = callDurationFactor || callScrollOffset;
548
550 {
551 double longestDuration = TrackList::Get( *mProject ).GetEndTime();
552 ProjectWindow::Get( *mProject ).ZoomBy(longestDuration / durationFactor);
553 callDurationFactor = false;
554 }
555
557 {
559 callScrollOffset = false;
560 }
561
562 if (doSomething)
563 // Amend last undo state
564 ProjectHistory::Get( *mProject ).ModifyState(false);
565}
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
void ZoomBy(double multiplier)
static ProjectWindow & Get(AudacityProject &project)
void TP_ScrollWindow(double scrollto) override
double GetEndTime() const
Definition: Track.cpp:1052
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486

References callDurationFactor, callScrollOffset, durationFactor, ProjectHistory::Get(), TrackList::Get(), ProjectWindow::Get(), TrackList::GetEndTime(), ProjectHistory::ModifyState(), mProject, scrollOffset, ProjectWindow::TP_ScrollWindow(), and ProjectWindow::ZoomBy().

Referenced by Import(), and lofOpenFiles().

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

◆ GetFileDescription()

TranslatableString LOFImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 259 of file ImportLOF.cpp.

260{
261 return DESC;
262}
#define DESC
Definition: ImportLOF.cpp:95

References DESC.

◆ GetFileUncompressedBytes()

auto LOFImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 264 of file ImportLOF.cpp.

265{
266 return 0;
267}

◆ GetStreamCount()

wxInt32 LOFImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 130 of file ImportLOF.cpp.

130{ return 1; }

◆ GetStreamInfo()

const TranslatableStrings & LOFImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 132 of file ImportLOF.cpp.

133 {
134 static TranslatableStrings empty;
135 return empty;
136 }
std::vector< TranslatableString > TranslatableStrings

◆ Import()

ProgressResult LOFImportFileHandle::Import ( WaveTrackFactory trackFactory,
TrackHolders outTracks,
Tags tags 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 269 of file ImportLOF.cpp.

272{
273 // Unlike other ImportFileHandle subclasses, this one never gives any tracks
274 // back to the caller.
275 // Instead, it recursively calls AudacityProject::Import for each file listed
276 // in the .lof file.
277 // Each importation creates a NEW undo state.
278 // If there is an error or exception during one of them, only that one's
279 // side effects are rolled back, and the rest of the import list is skipped.
280 // The file may have "window" directives that cause NEW AudacityProjects
281 // to be created, and the undo states are pushed onto the latest project.
282 // If a project is created but the first file import into it fails, destroy
283 // the project.
284
285 outTracks.clear();
286
287 wxASSERT(mTextFile->IsOpened());
288
289 if(mTextFile->Eof())
290 {
291 mTextFile->Close();
292 return ProgressResult::Failed;
293 }
294
295 wxString line = mTextFile->GetFirstLine();
296
297 while (!mTextFile->Eof())
298 {
299 lofOpenFiles(&line);
300 line = mTextFile->GetNextLine();
301 }
302
303 // for last line
304 lofOpenFiles(&line);
305
306 if(!mTextFile->Close())
307 return ProgressResult::Failed;
308
309 // set any duration/offset factors for last window, as all files were called
311
313}
void lofOpenFiles(wxString *ln)
Processes a single line from a LOF text file, doing whatever is indicated on the line.
Definition: ImportLOF.cpp:346
void doDurationAndScrollOffset()
Definition: ImportLOF.cpp:541

References doDurationAndScrollOffset(), lofOpenFiles(), mTextFile, and BasicUI::Success.

Here is the call graph for this function:

◆ lofOpenFiles()

void LOFImportFileHandle::lofOpenFiles ( wxString *  ln)
private

Processes a single line from a LOF text file, doing whatever is indicated on the line.

This function should just return for lines it cannot deal with, and the caller will continue to the next line of the input file

Definition at line 346 of file ImportLOF.cpp.

347{
348 wxStringTokenizer tok(*ln, wxT(" "));
349 wxStringTokenizer temptok1(*ln, wxT("\""));
350 wxStringTokenizer temptok2(*ln, wxT(" "));
351 int tokenplace = 0;
352
353 wxString targetfile;
354 wxString tokenholder = tok.GetNextToken();
355
356
357 if (tokenholder.IsSameAs(wxT("window"), false))
358 {
359 // set any duration/offset factors for last window, as all files were called
361
362 if (nFilesInGroup > 0 )
363 // Cause a project to be created with the next import
364 mProject = nullptr;
365
366 nFilesInGroup = 0;
367
368 while (tok.HasMoreTokens())
369 {
370 tokenholder = tok.GetNextToken();
371
372 if (tokenholder.IsSameAs(wxT("offset"), false))
373 {
374 if (tok.HasMoreTokens())
375 tokenholder = tok.GetNextToken();
376
378 {
379 callScrollOffset = true;
380 }
381 else
382 {
384 /* i18n-hint: You do not need to translate "LOF" */
385 XO("Invalid window offset in LOF file."),
386 /* i18n-hint: You do not need to translate "LOF" */
387 XO("LOF Error"),
388 wxOK | wxCENTRE);
389 }
390
391 if (tok.HasMoreTokens())
392 tokenholder = tok.GetNextToken();
393 }
394
395 if (tokenholder.IsSameAs(wxT("duration"), false))
396 {
397 if (tok.HasMoreTokens())
398 tokenholder = tok.GetNextToken();
399
401 {
402 callDurationFactor = true;
403 }
404 else
405 {
407 /* i18n-hint: You do not need to translate "LOF" */
408 XO("Invalid duration in LOF file."),
409 /* i18n-hint: You do not need to translate "LOF" */
410 XO("LOF Error"),
411 wxOK | wxCENTRE);
412 }
413 } // End if statement
414
415 if (tokenholder == wxT("#"))
416 {
417 // # indicates comments; ignore line
418 tok = wxStringTokenizer(wxT(""), wxT(" "));
419 }
420 } // End while loop
421 } // End if statement handling "window" lines
422
423 else if (tokenholder.IsSameAs(wxT("file"), false))
424 {
426 // To identify filename and open it
427 tokenholder = temptok1.GetNextToken();
428 wxString targettoken = temptok1.GetNextToken();
429 targetfile = targettoken;
430
431 // If path is relative, make absolute path from LOF path
432 if(!wxIsAbsolutePath(targetfile)) {
433 wxFileName fName(targetfile);
434 fName.Normalize(wxPATH_NORM_ALL, mLOFFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
435 if(fName.FileExists()) {
436 targetfile = fName.GetFullPath();
437 }
438 }
439
440 // Do recursive call to import
441
442#ifdef USE_MIDI
443 // If file is a midi
444 if (FileNames::IsMidi(targetfile))
445 {
447 }
448
449 // If not a midi, open audio file
450 else
451
452#else // !USE_MIDI
453 /* if we don't have midi support, go straight on to opening as an
454 * audio file. TODO: Some sort of message here? */
455
456#endif // USE_MIDI
458 true /* addtohistory */, true /* reuseNonemptyProject */ );
459
460 // Set tok to right after filename
461 temptok2.SetString(targettoken);
462 tokenplace = temptok2.CountTokens();
463
464 for (int i = 0; i < tokenplace; i++)
465 tokenholder = tok.GetNextToken();
466
467 if (tok.HasMoreTokens())
468 {
469 tokenholder = tok.GetNextToken();
470
471 if (tokenholder == wxT("#"))
472 {
473 // # indicates comments; ignore line
474 tok = wxStringTokenizer(wxT(""), wxT(" "));
475 }
476
477 if (tokenholder.IsSameAs(wxT("offset"), false))
478 {
479 if (tok.HasMoreTokens())
480 tokenholder = tok.GetNextToken();
481 double offset;
482
483 // handle an "offset" specifier
484 if (!mProject)
485 // there was an import error,
486 // presumably with its own error message
487 ;
488 else if (Internat::CompatibleToDouble(tokenholder, &offset))
489 {
490 auto &tracks = TrackList::Get( *mProject );
491 auto t = *tracks.Leaders().rbegin();
492
493 // t is now the last track in the project, unless the import of
494 // all tracks failed, in which case it will be null. In that
495 // case we return because we cannot offset a non-existent track.
496 if (t == NULL)
497 return;
498#ifdef USE_MIDI
499 if (targetfile.AfterLast(wxT('.')).IsSameAs(wxT("mid"), false) ||
500 targetfile.AfterLast(wxT('.')).IsSameAs(wxT("midi"), false))
501 {
503 XO("MIDI tracks cannot be offset individually, only audio files can be."),
504 XO("LOF Error"),
505 wxOK | wxCENTRE);
506 }
507 else
508#endif
509 {
510 for (auto channel : TrackList::Channels(t))
511 channel->SetOffset(offset);
512 }
513
514 // Amend the undo transaction made by import
515 ProjectHistory::Get( *mProject ).ModifyState(false);
516 } // end of converting "offset" argument
517 else
518 {
520 /* i18n-hint: You do not need to translate "LOF" */
521 XO("Invalid track offset in LOF file."),
522 /* i18n-hint: You do not need to translate "LOF" */
523 XO("LOF Error"),
524 wxOK | wxCENTRE);
525 }
526 } // End if statement for "offset" parameters
527 } // End if statement (more tokens after file name)
528 } // End if statement "file" lines
529
530 else if (tokenholder == wxT("#"))
531 {
532 // # indicates comments; ignore line
533 tok = wxStringTokenizer(wxT(""), wxT(" "));
534 }
535 else
536 {
537 // Couldn't parse a line
538 }
539}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
XO("Cut/Copy/Paste")
static AudacityProject * DoImportMIDIProject(AudacityProject *pProject, const FilePath &fileName)
Definition: ImportLOF.cpp:322
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:133
static AudacityProject * OpenProject(AudacityProject *pGivenProject, const FilePath &fileNameArg, bool addtohistory, bool reuseNonemptyProject)
Open a file into an AudacityProject, returning the project, or nullptr for failure.
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1541
FILES_API bool IsMidi(const FilePath &fName)

References AudacityMessageBox(), callDurationFactor, callScrollOffset, TrackList::Channels(), Internat::CompatibleToDouble(), doDurationAndScrollOffset(), DoImportMIDIProject(), durationFactor, ProjectHistory::Get(), TrackList::Get(), FileNames::IsMidi(), mLOFFileName, ProjectHistory::ModifyState(), mProject, nFilesInGroup, ProjectManager::OpenProject(), scrollOffset, wxT(), and XO().

Referenced by Import().

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

◆ SetStreamUsage()

void LOFImportFileHandle::SetStreamUsage ( wxInt32   WXUNUSEDStreamID,
bool   WXUNUSEDUse 
)
inlineoverride

Definition at line 138 of file ImportLOF.cpp.

139 {}

Member Data Documentation

◆ callDurationFactor

bool LOFImportFileHandle::callDurationFactor { false }
private

Definition at line 155 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ callScrollOffset

bool LOFImportFileHandle::callScrollOffset { false }
private

Definition at line 159 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ durationFactor

double LOFImportFileHandle::durationFactor { 1 }
private

Definition at line 156 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ mLOFFileName

wxFileName LOFImportFileHandle::mLOFFileName
private

The name of the LOF file, which is used to interpret relative paths in it

Definition at line 147 of file ImportLOF.cpp.

Referenced by lofOpenFiles().

◆ mProject

AudacityProject* LOFImportFileHandle::mProject {}
private

Definition at line 149 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ mTextFile

std::unique_ptr<wxTextFile> LOFImportFileHandle::mTextFile
private

Definition at line 146 of file ImportLOF.cpp.

Referenced by Import().

◆ nFilesInGroup

int LOFImportFileHandle::nFilesInGroup { 0 }
private

Definition at line 152 of file ImportLOF.cpp.

Referenced by lofOpenFiles().

◆ scrollOffset

double LOFImportFileHandle::scrollOffset { 0 }
private

Definition at line 160 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().


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