Audacity  3.0.3
PCMAliasBlockFile.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  PCMAliasBlockFile.cpp
6 
7  Joshua Haberman
8 
9 **********************************************************************/
10 
11 #include "../Audacity.h"
12 #include "PCMAliasBlockFile.h"
13 
14 #include <wx/file.h>
15 #include <wx/utils.h>
16 #include <wx/wxcrtvararg.h>
17 #include <wx/log.h>
18 
19 #include <sndfile.h>
20 
21 #include "../FileFormats.h"
22 
23 #include "../DirManager.h"
24 
26  wxFileNameWrapper &&fileName,
27  wxFileNameWrapper &&aliasedFileName,
28  sampleCount aliasStart,
29  size_t aliasLen, int aliasChannel)
30 : AliasBlockFile{ std::move(fileName), std::move(aliasedFileName),
31  aliasStart, aliasLen, aliasChannel }
32 {
33  AliasBlockFile::WriteSummary();
34 }
35 
37  wxFileNameWrapper&& fileName,
38  wxFileNameWrapper&& aliasedFileName,
39  sampleCount aliasStart,
40  size_t aliasLen, int aliasChannel,bool writeSummary)
41 : AliasBlockFile{ std::move(fileName), std::move(aliasedFileName),
42  aliasStart, aliasLen, aliasChannel }
43 {
44  if(writeSummary)
45  AliasBlockFile::WriteSummary();
46 }
47 
49  wxFileNameWrapper &&existingSummaryFileName,
50  wxFileNameWrapper &&aliasedFileName,
51  sampleCount aliasStart,
52  size_t aliasLen, int aliasChannel,
53  float min, float max, float rms)
54 : AliasBlockFile{ std::move(existingSummaryFileName), std::move(aliasedFileName),
55  aliasStart, aliasLen,
56  aliasChannel, min, max, rms }
57 {
58 }
59 
61 {
62 }
63 
72  size_t start, size_t len, bool mayThrow) const
73 {
74  if(!mAliasedFileName.IsOk()){ // intentionally silenced
75  memset(data, 0, SAMPLE_SIZE(format) * len);
76  return len;
77  }
78 
79  return CommonReadData( mayThrow,
80  mAliasedFileName, mSilentAliasLog, this, mAliasStart, mAliasChannel,
81  data, format, start, len);
82 }
83 
88 BlockFilePtr PCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
89 {
90  auto newBlockFile = make_blockfile<PCMAliasBlockFile>
91  (std::move(newFileName), wxFileNameWrapper{mAliasedFileName},
92  mAliasStart, mLen, mAliasChannel, mMin, mMax, mRMS);
93 
94  return newBlockFile;
95 }
96 
98 // may throw
99 {
100  xmlFile.StartTag(wxT("pcmaliasblockfile"));
101 
102  xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
103  xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
104  xmlFile.WriteAttr(wxT("aliasstart"),
105  mAliasStart.as_long_long());
106  xmlFile.WriteAttr(wxT("aliaslen"), mLen);
107  xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
108  xmlFile.WriteAttr(wxT("min"), mMin);
109  xmlFile.WriteAttr(wxT("max"), mMax);
110  xmlFile.WriteAttr(wxT("rms"), mRMS);
111 
112  xmlFile.EndTag(wxT("pcmaliasblockfile"));
113 }
114 
115 // BuildFromXML methods should always return a BlockFile, not NULL,
116 // even if the result is flawed (e.g., refers to nonexistent file),
117 // as testing will be done in ProjectFSCK().
118 BlockFilePtr PCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
119 {
120  wxFileNameWrapper summaryFileName;
121  wxFileNameWrapper aliasFileName;
122  int aliasStart=0, aliasLen=0, aliasChannel=0;
123  float min = 0.0f, max = 0.0f, rms = 0.0f;
124  double dblValue;
125  long nValue;
126  long long nnValue;
127 
128  while(*attrs)
129  {
130  const wxChar *attr = *attrs++;
131  const wxChar *value = *attrs++;
132  if (!value)
133  break;
134 
135  const wxString strValue = value;
136  if (!wxStricmp(attr, wxT("summaryfile")) &&
137  // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test.
139  (strValue.length() + 1 + dm.GetProjectDataDir().length() <= PLATFORM_MAX_PATH))
140  {
141  if (!dm.AssignFile(summaryFileName, strValue, false))
142  // Make sure summaryFileName is back to uninitialized state so we can detect problem later.
143  summaryFileName.Clear();
144  }
145  else if (!wxStricmp(attr, wxT("aliasfile")))
146  {
147  if (XMLValueChecker::IsGoodPathName(strValue))
148  aliasFileName.Assign(strValue);
149  else if (XMLValueChecker::IsGoodFileName(strValue, dm.GetProjectDataDir()))
150  // Allow fallback of looking for the file name, located in the data directory.
151  aliasFileName.Assign(dm.GetProjectDataDir(), strValue);
152  else if (XMLValueChecker::IsGoodPathString(strValue))
153  // If the aliased file is missing, we failed XMLValueChecker::IsGoodPathName()
154  // and XMLValueChecker::IsGoodFileName, because both do existence tests,
155  // but we want to keep the reference to the missing file because it's a good path string.
156  aliasFileName.Assign(strValue);
157  }
158  else if ( !wxStricmp(attr, wxT("aliasstart")) )
159  {
160  if (XMLValueChecker::IsGoodInt64(strValue) &&
161  strValue.ToLongLong(&nnValue) && (nnValue >= 0))
162  aliasStart = nnValue;
163  }
164  else if (XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
165  { // integer parameters
166  if (!wxStricmp(attr, wxT("aliaslen")) && (nValue >= 0))
167  aliasLen = nValue;
168  else if (!wxStricmp(attr, wxT("aliaschannel")) && XMLValueChecker::IsValidChannel(aliasChannel))
169  aliasChannel = nValue;
170  else if (!wxStricmp(attr, wxT("min")))
171  min = nValue;
172  else if (!wxStricmp(attr, wxT("max")))
173  max = nValue;
174  else if (!wxStricmp(attr, wxT("rms")) && (nValue >= 0))
175  rms = nValue;
176  }
177  // mchinen: the min/max can be (are?) doubles as well, so handle those cases.
178  // Vaughan: The code to which I added the XMLValueChecker checks
179  // used wxAtoi to convert the string to an int.
180  // So it's possible some prior project formats used ints (?), so am keeping
181  // those above, but yes, we need to handle floats.
182  else if (XMLValueChecker::IsGoodString(strValue) && Internat::CompatibleToDouble(strValue, &dblValue))
183  { // double parameters
184  if (!wxStricmp(attr, wxT("min")))
185  min = dblValue;
186  else if (!wxStricmp(attr, wxT("max")))
187  max = dblValue;
188  else if (!wxStricmp(attr, wxT("rms")) && (dblValue >= 0.0))
189  rms = dblValue;
190  }
191  }
192 
193  return make_blockfile<PCMAliasBlockFile>
194  (std::move(summaryFileName), std::move(aliasFileName),
195  aliasStart, aliasLen, aliasChannel, min, max, rms);
196 }
197 
199 {
200  WriteSummary();
201 }
202 
203 static DirManager::RegisteredBlockFileDeserializer sRegistration {
204  "pcmaliasblockfile",
205  []( DirManager &dm, const wxChar **attrs ){
206  return PCMAliasBlockFile::BuildFromXML( dm, attrs );
207  }
208 };
XMLWriter
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:23
PCMAliasBlockFile::Copy
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override
Definition: PCMAliasBlockFile.cpp:88
XMLWriter::EndTag
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:99
PCMAliasBlockFile::BuildFromXML
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs)
Definition: PCMAliasBlockFile.cpp:118
wxFileNameWrapper
Definition: wxFileNameWrapper.h:21
XMLValueChecker::IsGoodInt
static bool IsGoodInt(const wxString &strInt)
Check that the supplied string can be converted to a long (32bit) integer.
Definition: XMLTagHandler.cpp:157
XMLValueChecker::IsGoodPathName
static bool IsGoodPathName(const FilePath &strPathName)
Definition: XMLTagHandler.cpp:98
XMLValueChecker::IsGoodInt64
static bool IsGoodInt64(const wxString &strInt)
Check that the supplied string can be converted to a 64bit integer.
Definition: XMLTagHandler.cpp:163
SAMPLE_SIZE
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:44
XMLValueChecker::IsGoodString
static bool IsGoodString(const wxString &str)
Definition: XMLTagHandler.cpp:38
PCMAliasBlockFile::SaveXML
void SaveXML(XMLWriter &xmlFile) override
Definition: PCMAliasBlockFile.cpp:97
XMLValueChecker::IsGoodFileName
static bool IsGoodFileName(const FilePath &strFileName, const FilePath &strDirName={})
Definition: XMLTagHandler.cpp:58
format
int format
Definition: ExportPCM.cpp:56
PCMAliasBlockFile::PCMAliasBlockFile
PCMAliasBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&aliasedFileName, sampleCount aliasStart, size_t aliasLen, int aliasChannel)
Constructs a PCMAliasBlockFile, writing the summary to disk.
Definition: PCMAliasBlockFile.cpp:25
PCMAliasBlockFile::Recover
void Recover() override
Definition: PCMAliasBlockFile.cpp:198
sRegistration
static DirManager::RegisteredBlockFileDeserializer sRegistration
Definition: PCMAliasBlockFile.cpp:203
XMLValueChecker::IsGoodFileString
static bool IsGoodFileString(const FilePath &str)
Definition: XMLTagHandler.cpp:70
sampleFormat
sampleFormat
Definition: SampleFormat.h:29
samplePtr
char * samplePtr
Definition: SampleFormat.h:49
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
anonymous_namespace{WaveTrack.cpp}::IsValidChannel
bool IsValidChannel(const int nValue)
Definition: WaveTrack.cpp:1706
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
PCMAliasBlockFile::~PCMAliasBlockFile
virtual ~PCMAliasBlockFile()
Definition: PCMAliasBlockFile.cpp:60
XMLWriter::WriteAttr
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:34
PLATFORM_MAX_PATH
#define PLATFORM_MAX_PATH
Definition: FileNames.h:22
XMLValueChecker::IsGoodPathString
static bool IsGoodPathString(const FilePath &str)
Definition: XMLTagHandler.cpp:105
PCMAliasBlockFile.h
XMLWriter::StartTag
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:76
PCMAliasBlockFile::ReadData
size_t ReadData(samplePtr data, sampleFormat format, size_t start, size_t len, bool mayThrow) const override
Reads the specified data from the aliased file using libsndfile.
Definition: PCMAliasBlockFile.cpp:71
Internat::CompatibleToDouble
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:134