Audacity  2.3.1
Public Member Functions | Private Attributes | List of all members
OggImportFileHandle Class Referencefinal
Inheritance diagram for OggImportFileHandle:
ImportFileHandle

Public Member Functions

 OggImportFileHandle (const wxString &filename, std::unique_ptr< wxFFile > &&file, std::unique_ptr< OggVorbis_File > &&vorbisFile)
 
 ~OggImportFileHandle ()
 
wxString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
ProgressResult Import (TrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
 
wxInt32 GetStreamCount () override
 
const wxArrayString & GetStreamInfo () override
 
void SetStreamUsage (wxInt32 StreamID, bool Use) override
 
- Public Member Functions inherited from ImportFileHandle
 ImportFileHandle (const wxString &filename)
 
virtual ~ImportFileHandle ()
 
void CreateProgress ()
 

Private Attributes

std::unique_ptr< wxFFile > mFile
 
std::unique_ptr< OggVorbis_File > mVorbisFile
 
ArrayOf< int > mStreamUsage
 
wxArrayString mStreamInfo
 
std::list< NewChannelGroupmChannels
 
sampleFormat mFormat
 

Additional Inherited Members

- Public Types inherited from ImportFileHandle
using ByteCount = unsigned long long
 
- Protected Attributes inherited from ImportFileHandle
wxString mFilename
 
Maybe< ProgressDialogmProgress
 

Detailed Description

Definition at line 101 of file ImportOGG.cpp.

Constructor & Destructor Documentation

OggImportFileHandle::OggImportFileHandle ( const wxString &  filename,
std::unique_ptr< wxFFile > &&  file,
std::unique_ptr< OggVorbis_File > &&  vorbisFile 
)
inline

Definition at line 104 of file ImportOGG.cpp.

References GetFileDescription(), GetFileUncompressedBytes(), Import(), mFormat, mStreamInfo, mStreamUsage, mVorbisFile, QualityPrefs::SampleFormatChoice(), and ~OggImportFileHandle().

107  : ImportFileHandle(filename),
108  mFile(std::move(file)),
109  mVorbisFile(std::move(vorbisFile))
110  , mStreamUsage{ static_cast<size_t>(mVorbisFile->links) }
111  {
113 
114  for (int i = 0; i < mVorbisFile->links; i++)
115  {
116  wxString strinfo;
117  strinfo.Printf(wxT("Index[%02x] Version[%d], Channels[%d], Rate[%ld]"), (unsigned int) i,mVorbisFile->vi[i].version,mVorbisFile->vi[i].channels,mVorbisFile->vi[i].rate);
118  mStreamInfo.Add(strinfo);
119  mStreamUsage[i] = 0;
120  }
121 
122  }
ArrayOf< int > mStreamUsage
Definition: ImportOGG.cpp:156
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:154
ImportFileHandle(const wxString &filename)
Definition: ImportPlugin.h:122
wxArrayString mStreamInfo
Definition: ImportOGG.cpp:157
sampleFormat mFormat
Definition: ImportOGG.cpp:160
static sampleFormat SampleFormatChoice()
std::unique_ptr< wxFFile > mFile
Definition: ImportOGG.cpp:153
OggImportFileHandle::~OggImportFileHandle ( )

Definition at line 384 of file ImportOGG.cpp.

References mFile, and mVorbisFile.

Referenced by OggImportFileHandle().

385 {
386  ov_clear(mVorbisFile.get());
387  mFile->Detach(); // so that it doesn't try to close the file (ov_clear()
388  // did that already)
389 }
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:154
std::unique_ptr< wxFFile > mFile
Definition: ImportOGG.cpp:153

Member Function Documentation

wxString OggImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 220 of file ImportOGG.cpp.

References DESC.

Referenced by OggImportFileHandle().

221 {
222  return DESC;
223 }
#define DESC
Definition: ImportOGG.cpp:48
auto OggImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 225 of file ImportOGG.cpp.

Referenced by OggImportFileHandle().

226 {
227  // TODO:
228  return 0;
229 }
wxInt32 OggImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 130 of file ImportOGG.cpp.

References mVorbisFile.

131  {
132  if (mVorbisFile)
133  return mVorbisFile->links;
134  else
135  return 0;
136  }
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:154
const wxArrayString& OggImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 138 of file ImportOGG.cpp.

References mStreamInfo.

139  {
140  return mStreamInfo;
141  }
wxArrayString mStreamInfo
Definition: ImportOGG.cpp:157
ProgressResult OggImportFileHandle::Import ( TrackFactory trackFactory,
TrackHolders outTracks,
Tags tags 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 231 of file ImportOGG.cpp.

References Cancelled, Tags::Clear(), CODEC_TRANSFER_SIZE, ImportFileHandle::CreateProgress(), Failed, Tags::HasTag(), int16Sample, mChannels, mFile, ImportFileHandle::mFilename, mFormat, ImportFileHandle::mProgress, mStreamUsage, mVorbisFile, name, TrackFactory::NewWaveTrack(), SAMPLES_PER_CALLBACK, Tags::SetTag(), Success, TAG_YEAR, ProgressDialog::Update(), and UTF8CTOWX.

Referenced by OggImportFileHandle().

234 {
235  outTracks.clear();
236 
237  wxASSERT(mFile->IsOpened());
238 
239  CreateProgress();
240 
241  //Number of streams used may be less than mVorbisFile->links,
242  //but this way bitstream matches array index.
243  mChannels.resize(mVorbisFile->links);
244 
245  int i = -1;
246  for (auto &link : mChannels)
247  {
248  ++i;
249 
250  //Stream is not used
251  if (mStreamUsage[i] == 0)
252  {
253  //This is just a padding to keep bitstream number and
254  //array indices matched.
255  continue;
256  }
257 
258  vorbis_info *vi = ov_info(mVorbisFile.get(), i);
259 
260  link.resize(vi->channels);
261 
262  for (auto &channel : link)
263  channel = trackFactory->NewWaveTrack(mFormat, vi->rate);
264  }
265 
266  /* The number of bytes to get from the codec in each run */
267 #define CODEC_TRANSFER_SIZE 4096u
268 
269  /* The number of samples to read between calls to the callback.
270  * Balance between responsiveness of the GUI and throughput of import. */
271 #define SAMPLES_PER_CALLBACK 100000
272 
273  auto updateResult = ProgressResult::Success;
274  long bytesRead = 0;
275  {
276  ArrayOf<short> mainBuffer{ CODEC_TRANSFER_SIZE };
277 
278  /* determine endianness (clever trick courtesy of Nicholas Devillard,
279  * (http://www.eso.org/~ndevilla/endian/) */
280  int testvar = 1, endian;
281  if (*(char *)&testvar)
282  endian = 0; // little endian
283  else
284  endian = 1; // big endian
285 
286  /* number of samples currently in each channel's buffer */
287  long samplesRead = 0;
288  int bitstream = 0;
289  int samplesSinceLastCallback = 0;
290 
291  // You would think that the stream would already be seeked to 0, and
292  // indeed it is if the file is legit. But I had several ogg files on
293  // my hard drive that have malformed headers, and this added call
294  // causes them to be read correctly. Otherwise they have lots of
295  // zeros inserted at the beginning
296  ov_pcm_seek(mVorbisFile.get(), 0);
297 
298  do {
299  /* get data from the decoder */
300  bytesRead = ov_read(mVorbisFile.get(), (char *)mainBuffer.get(),
302  endian,
303  2, // word length (2 for 16 bit samples)
304  1, // signed
305  &bitstream);
306 
307  if (bytesRead == OV_HOLE) {
308  wxFileName ff(mFilename);
309  wxLogError(wxT("Ogg Vorbis importer: file %s is malformed, ov_read() reported a hole"),
310  ff.GetFullName());
311  /* http://lists.xiph.org/pipermail/vorbis-dev/2001-February/003223.html
312  * is the justification for doing this - best effort for malformed file,
313  * hence the message.
314  */
315  continue;
316  }
317  else if (bytesRead < 0) {
318  /* Malformed Ogg Vorbis file. */
319  /* TODO: Return some sort of meaningful error. */
320  wxLogError(wxT("Ogg Vorbis importer: ov_read() returned error %i"),
321  bytesRead);
322  break;
323  }
324 
325  samplesRead = bytesRead / mVorbisFile->vi[bitstream].channels / sizeof(short);
326 
327  /* give the data to the wavetracks */
328  auto iter = mChannels.begin();
329  std::advance(iter, bitstream);
330  if (mStreamUsage[bitstream] != 0)
331  {
332  auto iter2 = iter->begin();
333  for (int c = 0; c < mVorbisFile->vi[bitstream].channels; ++iter2, ++c)
334  iter2->get()->Append((char *)(mainBuffer.get() + c),
335  int16Sample,
336  samplesRead,
337  mVorbisFile->vi[bitstream].channels);
338  }
339 
340  samplesSinceLastCallback += samplesRead;
341  if (samplesSinceLastCallback > SAMPLES_PER_CALLBACK) {
342  updateResult = mProgress->Update(ov_time_tell(mVorbisFile.get()),
343  ov_time_total(mVorbisFile.get(), bitstream));
344  samplesSinceLastCallback -= SAMPLES_PER_CALLBACK;
345  }
346  } while (updateResult == ProgressResult::Success && bytesRead != 0);
347  }
348 
349  auto res = updateResult;
350  if (bytesRead < 0)
352 
353  if (res == ProgressResult::Failed || res == ProgressResult::Cancelled) {
354  return res;
355  }
356 
357  for (auto &link : mChannels)
358  {
359  for (auto &channel : link)
360  channel->Flush();
361  outTracks.push_back(std::move(link));
362  }
363 
364  //\todo { Extract comments from each stream? }
365  if (mVorbisFile->vc[0].comments > 0) {
366  tags->Clear();
367  for (int c = 0; c < mVorbisFile->vc[0].comments; c++) {
368  wxString comment = UTF8CTOWX(mVorbisFile->vc[0].user_comments[c]);
369  wxString name = comment.BeforeFirst(wxT('='));
370  wxString value = comment.AfterFirst(wxT('='));
371  if (name.Upper() == wxT("DATE") && !tags->HasTag(TAG_YEAR)) {
372  long val;
373  if (value.Length() == 4 && value.ToLong(&val)) {
374  name = TAG_YEAR;
375  }
376  }
377  tags->SetTag(name, value);
378  }
379  }
380 
381  return res;
382 }
void SetTag(const wxString &name, const wxString &value)
Definition: Tags.cpp:449
ArrayOf< int > mStreamUsage
Definition: ImportOGG.cpp:156
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:154
std::list< NewChannelGroup > mChannels
Definition: ImportOGG.cpp:158
#define UTF8CTOWX(X)
Definition: Internat.h:179
void Clear()
Definition: Tags.cpp:300
#define CODEC_TRANSFER_SIZE
ProgressResult Update(int value, const wxString &message=wxEmptyString)
Maybe< ProgressDialog > mProgress
Definition: ImportPlugin.h:176
std::unique_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:78
const wxChar * name
Definition: Distortion.cpp:94
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
Definition: MemoryX.h:82
sampleFormat mFormat
Definition: ImportOGG.cpp:160
#define SAMPLES_PER_CALLBACK
std::unique_ptr< wxFFile > mFile
Definition: ImportOGG.cpp:153
wxString mFilename
Definition: ImportPlugin.h:175
#define TAG_YEAR
Definition: Tags.h:64
bool HasTag(const wxString &name) const
Definition: Tags.cpp:415
void OggImportFileHandle::SetStreamUsage ( wxInt32  StreamID,
bool  Use 
)
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 143 of file ImportOGG.cpp.

References mStreamUsage, and mVorbisFile.

144  {
145  if (mVorbisFile)
146  {
147  if (StreamID < mVorbisFile->links)
148  mStreamUsage[StreamID] = (Use ? 1 : 0);
149  }
150  }
ArrayOf< int > mStreamUsage
Definition: ImportOGG.cpp:156
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:154

Member Data Documentation

std::list<NewChannelGroup> OggImportFileHandle::mChannels
private

Definition at line 158 of file ImportOGG.cpp.

Referenced by Import().

std::unique_ptr<wxFFile> OggImportFileHandle::mFile
private

Definition at line 153 of file ImportOGG.cpp.

Referenced by Import(), and ~OggImportFileHandle().

sampleFormat OggImportFileHandle::mFormat
private

Definition at line 160 of file ImportOGG.cpp.

Referenced by Import(), and OggImportFileHandle().

wxArrayString OggImportFileHandle::mStreamInfo
private

Definition at line 157 of file ImportOGG.cpp.

Referenced by GetStreamInfo(), and OggImportFileHandle().

ArrayOf<int> OggImportFileHandle::mStreamUsage
private

Definition at line 156 of file ImportOGG.cpp.

Referenced by Import(), OggImportFileHandle(), and SetStreamUsage().

std::unique_ptr<OggVorbis_File> OggImportFileHandle::mVorbisFile
private

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