Audacity  2.2.2
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/wxchar.h>
17 #include <wx/log.h>
18 
19 #include <sndfile.h>
20 
21 #include "../AudacityApp.h"
22 #include "../FileFormats.h"
23 #include "../Internat.h"
24 #include "../MemoryX.h"
25 
26 #include "../ondemand/ODManager.h"
27 #include "../AudioIO.h"
28 
29 extern AudioIO *gAudioIO;
30 
32  wxFileNameWrapper &&fileName,
33  wxFileNameWrapper &&aliasedFileName,
34  sampleCount aliasStart,
35  size_t aliasLen, int aliasChannel)
36 : AliasBlockFile{ std::move(fileName), std::move(aliasedFileName),
37  aliasStart, aliasLen, aliasChannel }
38 {
40 }
41 
43  wxFileNameWrapper&& fileName,
44  wxFileNameWrapper&& aliasedFileName,
45  sampleCount aliasStart,
46  size_t aliasLen, int aliasChannel,bool writeSummary)
47 : AliasBlockFile{ std::move(fileName), std::move(aliasedFileName),
48  aliasStart, aliasLen, aliasChannel }
49 {
50  if(writeSummary)
52 }
53 
55  wxFileNameWrapper &&existingSummaryFileName,
56  wxFileNameWrapper &&aliasedFileName,
57  sampleCount aliasStart,
58  size_t aliasLen, int aliasChannel,
59  float min, float max, float rms)
60 : AliasBlockFile{ std::move(existingSummaryFileName), std::move(aliasedFileName),
61  aliasStart, aliasLen,
62  aliasChannel, min, max, rms }
63 {
64 }
65 
67 {
68 }
69 
77 size_t PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
78  size_t start, size_t len, bool mayThrow) const
79 {
80  if(!mAliasedFileName.IsOk()){ // intentionally silenced
81  memset(data, 0, SAMPLE_SIZE(format) * len);
82  return len;
83  }
84 
85  return CommonReadData( mayThrow,
87  data, format, start, len);
88 }
89 
95 {
96  auto newBlockFile = make_blockfile<PCMAliasBlockFile>
97  (std::move(newFileName), wxFileNameWrapper{mAliasedFileName},
99 
100  return newBlockFile;
101 }
102 
104 // may throw
105 {
106  xmlFile.StartTag(wxT("pcmaliasblockfile"));
107 
108  xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
109  xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
110  xmlFile.WriteAttr(wxT("aliasstart"),
111  mAliasStart.as_long_long());
112  xmlFile.WriteAttr(wxT("aliaslen"), mLen);
113  xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
114  xmlFile.WriteAttr(wxT("min"), mMin);
115  xmlFile.WriteAttr(wxT("max"), mMax);
116  xmlFile.WriteAttr(wxT("rms"), mRMS);
117 
118  xmlFile.EndTag(wxT("pcmaliasblockfile"));
119 }
120 
121 // BuildFromXML methods should always return a BlockFile, not NULL,
122 // even if the result is flawed (e.g., refers to nonexistent file),
123 // as testing will be done in DirManager::ProjectFSCK().
125 {
126  wxFileNameWrapper summaryFileName;
127  wxFileNameWrapper aliasFileName;
128  int aliasStart=0, aliasLen=0, aliasChannel=0;
129  float min = 0.0f, max = 0.0f, rms = 0.0f;
130  double dblValue;
131  long nValue;
132  long long nnValue;
133 
134  while(*attrs)
135  {
136  const wxChar *attr = *attrs++;
137  const wxChar *value = *attrs++;
138  if (!value)
139  break;
140 
141  const wxString strValue = value;
142  if (!wxStricmp(attr, wxT("summaryfile")) &&
143  // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test.
145  (strValue.Length() + 1 + dm.GetProjectDataDir().Length() <= PLATFORM_MAX_PATH))
146  {
147  if (!dm.AssignFile(summaryFileName, strValue, false))
148  // Make sure summaryFileName is back to uninitialized state so we can detect problem later.
149  summaryFileName.Clear();
150  }
151  else if (!wxStricmp(attr, wxT("aliasfile")))
152  {
153  if (XMLValueChecker::IsGoodPathName(strValue))
154  aliasFileName.Assign(strValue);
155  else if (XMLValueChecker::IsGoodFileName(strValue, dm.GetProjectDataDir()))
156  // Allow fallback of looking for the file name, located in the data directory.
157  aliasFileName.Assign(dm.GetProjectDataDir(), strValue);
158  else if (XMLValueChecker::IsGoodPathString(strValue))
159  // If the aliased file is missing, we failed XMLValueChecker::IsGoodPathName()
160  // and XMLValueChecker::IsGoodFileName, because both do existence tests,
161  // but we want to keep the reference to the missing file because it's a good path string.
162  aliasFileName.Assign(strValue);
163  }
164  else if ( !wxStricmp(attr, wxT("aliasstart")) )
165  {
166  if (XMLValueChecker::IsGoodInt64(strValue) &&
167  strValue.ToLongLong(&nnValue) && (nnValue >= 0))
168  aliasStart = nnValue;
169  }
170  else if (XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue))
171  { // integer parameters
172  if (!wxStricmp(attr, wxT("aliaslen")) && (nValue >= 0))
173  aliasLen = nValue;
174  else if (!wxStricmp(attr, wxT("aliaschannel")) && XMLValueChecker::IsValidChannel(aliasChannel))
175  aliasChannel = nValue;
176  else if (!wxStricmp(attr, wxT("min")))
177  min = nValue;
178  else if (!wxStricmp(attr, wxT("max")))
179  max = nValue;
180  else if (!wxStricmp(attr, wxT("rms")) && (nValue >= 0))
181  rms = nValue;
182  }
183  // mchinen: the min/max can be (are?) doubles as well, so handle those cases.
184  // Vaughan: The code to which I added the XMLValueChecker checks
185  // used wxAtoi to convert the string to an int.
186  // So it's possible some prior project formats used ints (?), so am keeping
187  // those above, but yes, we need to handle floats.
188  else if (XMLValueChecker::IsGoodString(strValue) && Internat::CompatibleToDouble(strValue, &dblValue))
189  { // double parameters
190  if (!wxStricmp(attr, wxT("min")))
191  min = dblValue;
192  else if (!wxStricmp(attr, wxT("max")))
193  max = dblValue;
194  else if (!wxStricmp(attr, wxT("rms")) && (dblValue >= 0.0))
195  rms = dblValue;
196  }
197  }
198 
199  return make_blockfile<PCMAliasBlockFile>
200  (std::move(summaryFileName), std::move(aliasFileName),
201  aliasStart, aliasLen, aliasChannel, min, max, rms);
202 }
203 
205 {
206  WriteSummary();
207 }
208 
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs)
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.
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:143
AudioIO * gAudioIO
Definition: AudioIO.cpp:481
Creates and manages BlockFile objects.
Definition: DirManager.h:54
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override
const int mAliasChannel
Definition: BlockFile.h:299
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:78
wxFileNameWrapper mFileName
Definition: BlockFile.h:243
virtual void WriteAttr(const wxString &name, const wxString &value)
Definition: XMLWriter.cpp:131
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:101
static bool IsValidChannel(const int nValue)
static bool IsGoodInt64(const wxString &strInt)
Check that the supplied string can be converted to a 64bit integer.
void SaveXML(XMLWriter &xmlFile) override
Stores a representation of this file in XML.
static bool IsGoodPathName(const wxString &strPathName)
float mMin
Definition: BlockFile.h:246
wxFileNameWrapper mAliasedFileName
Definition: BlockFile.h:297
static bool IsGoodPathString(const wxString &str)
static bool IsGoodInt(const wxString &strInt)
Check that the supplied string can be converted to a long (32bit) integer.
#define PLATFORM_MAX_PATH
Definition: Audacity.h:118
std::shared_ptr< BlockFile > BlockFilePtr
Definition: BlockFile.h:48
int format
Definition: ExportPCM.cpp:56
static bool IsGoodString(const wxString &str)
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:121
void Recover() override
if the on-disk state disappeared, either recover it (if it was
float mRMS
Definition: BlockFile.h:246
int min(int a, int b)
wxString GetProjectDataDir()
Definition: DirManager.cpp:679
bool mSilentAliasLog
Definition: BlockFile.h:300
sampleCount mAliasStart
Definition: BlockFile.h:298
size_t mLen
Definition: BlockFile.h:244
static size_t CommonReadData(bool mayThrow, const wxFileName &fileName, bool &mSilentLog, const AliasBlockFile *pAliasFile, sampleCount origin, unsigned channel, samplePtr data, sampleFormat format, size_t start, size_t len, const sampleFormat *pLegacyFormat=nullptr, size_t legacyLen=0)
Definition: BlockFile.cpp:483
static bool IsGoodFileString(const wxString &str)
A BlockFile that refers to data in an existing file.
Definition: BlockFile.h:259
static bool IsGoodFileName(const wxString &strFileName, const wxString &strDirName=wxEmptyString)
virtual void WriteSummary()
Write the summary to disk, using the derived ReadData() to get the data.
Definition: BlockFile.cpp:675
float mMax
Definition: BlockFile.h:246
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:22
PCMAliasBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&aliasedFileName, sampleCount aliasStart, size_t aliasLen, int aliasChannel)
Constructs a PCMAliasBlockFile, writing the summary to disk.
bool AssignFile(wxFileNameWrapper &filename, const wxString &value, bool check)
Definition: DirManager.cpp:752