Audacity  3.0.3
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 void SetStreamUsage (wxInt32 StreamID, bool Use)=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 121 of file ImportLOF.cpp.

Constructor & Destructor Documentation

◆ LOFImportFileHandle()

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

Definition at line 166 of file ImportLOF.cpp.

169  , mTextFile(std::move(file))
170  , mLOFFileName{name}
171  , mProject{ pProject }
172 {
173 }

References name.

◆ ~LOFImportFileHandle()

LOFImportFileHandle::~LOFImportFileHandle ( )

Definition at line 570 of file ImportLOF.cpp.

571 {
572 }

Member Function Documentation

◆ doDurationAndScrollOffset()

void LOFImportFileHandle::doDurationAndScrollOffset ( )
private

Definition at line 544 of file ImportLOF.cpp.

545 {
546  if (!mProject)
547  return;
548 
550  bool doSomething = callDurationFactor || callScrollOffset;
551 
552  if (callDurationFactor)
553  {
554  double longestDuration = TrackList::Get( *mProject ).GetEndTime();
555  ProjectWindow::Get( *mProject ).ZoomBy(longestDuration / durationFactor);
556  callDurationFactor = false;
557  }
558 
559  if (callScrollOffset)
560  {
562  callScrollOffset = false;
563  }
564 
565  if (doSomething)
566  // Amend last undo state
567  ProjectHistory::Get( *mProject ).ModifyState(false);
568 }

References callDurationFactor, callScrollOffset, durationFactor, ProjectHistory::Get(), ProjectWindow::Get(), TrackList::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 262 of file ImportLOF.cpp.

263 {
264  return DESC;
265 }

References DESC.

◆ GetFileUncompressedBytes()

auto LOFImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 267 of file ImportLOF.cpp.

268 {
269  return 0;
270 }

◆ GetStreamCount()

wxInt32 LOFImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 133 of file ImportLOF.cpp.

133 { return 1; }

◆ GetStreamInfo()

const TranslatableStrings& LOFImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 135 of file ImportLOF.cpp.

136  {
137  static TranslatableStrings empty;
138  return empty;
139  }

◆ Import()

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

Implements ImportFileHandle.

Definition at line 272 of file ImportLOF.cpp.

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

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 349 of file ImportLOF.cpp.

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

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, 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 141 of file ImportLOF.cpp.

142  {}

Member Data Documentation

◆ callDurationFactor

bool LOFImportFileHandle::callDurationFactor { false }
private

Definition at line 158 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ callScrollOffset

bool LOFImportFileHandle::callScrollOffset { false }
private

Definition at line 162 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ durationFactor

double LOFImportFileHandle::durationFactor { 1 }
private

Definition at line 159 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 150 of file ImportLOF.cpp.

Referenced by lofOpenFiles().

◆ mProject

AudacityProject* LOFImportFileHandle::mProject {}
private

Definition at line 152 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

◆ mTextFile

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

Definition at line 149 of file ImportLOF.cpp.

Referenced by Import().

◆ nFilesInGroup

int LOFImportFileHandle::nFilesInGroup { 0 }
private

Definition at line 155 of file ImportLOF.cpp.

Referenced by lofOpenFiles().

◆ scrollOffset

double LOFImportFileHandle::scrollOffset { 0 }
private

Definition at line 163 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().


The documentation for this class was generated from the following file:
LOFImportFileHandle::mTextFile
std::unique_ptr< wxTextFile > mTextFile
Definition: ImportLOF.cpp:149
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
BasicUI::ProgressResult::Success
@ Success
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
LOFImportFileHandle::mLOFFileName
wxFileName mLOFFileName
Definition: ImportLOF.cpp:150
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
LOFImportFileHandle::callScrollOffset
bool callScrollOffset
Definition: ImportLOF.cpp:162
ProjectWindow::TP_ScrollWindow
void TP_ScrollWindow(double scrollto) override
Definition: ProjectWindow.cpp:969
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1484
LOFImportFileHandle::doDurationAndScrollOffset
void doDurationAndScrollOffset()
Definition: ImportLOF.cpp:544
XO
#define XO(s)
Definition: Internat.h:31
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:535
ProjectManager::OpenProject
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.
Definition: ProjectManager.cpp:949
ProjectWindow::ZoomBy
void ZoomBy(double multiplier)
Definition: ProjectWindow.cpp:1590
TrackList::GetEndTime
double GetEndTime() const
Definition: Track.cpp:1038
FileNames::IsMidi
FILES_API bool IsMidi(const FilePath &fName)
ImportFileHandle::ImportFileHandle
ImportFileHandle(const FilePath &filename)
Definition: ImportPlugin.cpp:36
LOFImportFileHandle::durationFactor
double durationFactor
Definition: ImportLOF.cpp:159
LOFImportFileHandle::nFilesInGroup
int nFilesInGroup
Definition: ImportLOF.cpp:155
name
const TranslatableString name
Definition: Distortion.cpp:98
LOFImportFileHandle::lofOpenFiles
void lofOpenFiles(wxString *ln)
Processes a single line from a LOF text file, doing whatever is indicated on the line.
Definition: ImportLOF.cpp:349
DoImportMIDIProject
static AudacityProject * DoImportMIDIProject(AudacityProject *pProject, const FilePath &fileName)
Definition: ImportLOF.cpp:325
LOFImportFileHandle::scrollOffset
double scrollOffset
Definition: ImportLOF.cpp:163
LOFImportFileHandle::mProject
AudacityProject * mProject
Definition: ImportLOF.cpp:152
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
LOFImportFileHandle::callDurationFactor
bool callDurationFactor
Definition: ImportLOF.cpp:158
DESC
#define DESC
Definition: ImportLOF.cpp:98
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
Internat::CompatibleToDouble
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:134