Audacity  3.0.3
Public Member Functions | Private Attributes | List of all members
OggImportFileHandle Class Referencefinal
Inheritance diagram for OggImportFileHandle:
[legend]
Collaboration diagram for OggImportFileHandle:
[legend]

Public Member Functions

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

Private Attributes

std::unique_ptr< wxFFile > mFile
 
std::unique_ptr< OggVorbis_File > mVorbisFile
 
ArrayOf< int > mStreamUsage
 
TranslatableStrings mStreamInfo
 
std::list< NewChannelGroupmChannels
 

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

Definition at line 98 of file ImportOGG.cpp.

Constructor & Destructor Documentation

◆ OggImportFileHandle()

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

Definition at line 101 of file ImportOGG.cpp.

104  : ImportFileHandle(filename),
105  mFile(std::move(file)),
106  mVorbisFile(std::move(vorbisFile))
107  , mStreamUsage{ static_cast<size_t>(mVorbisFile->links) }
108  {
109  for (int i = 0; i < mVorbisFile->links; i++)
110  {
111  auto strinfo = XO("Index[%02x] Version[%d], Channels[%d], Rate[%ld]")
112  .Format(
113  (unsigned int) i,
114  mVorbisFile->vi[i].version,
115  mVorbisFile->vi[i].channels,
116  mVorbisFile->vi[i].rate);
117  mStreamInfo.push_back(strinfo);
118  mStreamUsage[i] = 0;
119  }
120 
121  }

References mVorbisFile.

◆ ~OggImportFileHandle()

OggImportFileHandle::~OggImportFileHandle ( )

Definition at line 382 of file ImportOGG.cpp.

383 {
384  ov_clear(mVorbisFile.get());
385  mFile->Detach(); // so that it doesn't try to close the file (ov_clear()
386  // did that already)
387 }

References mFile, and mVorbisFile.

Member Function Documentation

◆ GetFileDescription()

TranslatableString OggImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 217 of file ImportOGG.cpp.

218 {
219  return DESC;
220 }

References DESC.

◆ GetFileUncompressedBytes()

auto OggImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 222 of file ImportOGG.cpp.

223 {
224  // TODO:
225  return 0;
226 }

◆ GetStreamCount()

wxInt32 OggImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 129 of file ImportOGG.cpp.

130  {
131  if (mVorbisFile)
132  return mVorbisFile->links;
133  else
134  return 0;
135  }

References mVorbisFile.

◆ GetStreamInfo()

const TranslatableStrings& OggImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 137 of file ImportOGG.cpp.

138  {
139  return mStreamInfo;
140  }

References mStreamInfo.

◆ Import()

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

Implements ImportFileHandle.

Definition at line 228 of file ImportOGG.cpp.

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

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

Here is the call graph for this function:

◆ SetStreamUsage()

void OggImportFileHandle::SetStreamUsage ( wxInt32  StreamID,
bool  Use 
)
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 142 of file ImportOGG.cpp.

143  {
144  if (mVorbisFile)
145  {
146  if (StreamID < mVorbisFile->links)
147  mStreamUsage[StreamID] = (Use ? 1 : 0);
148  }
149  }

References mStreamUsage, and mVorbisFile.

Member Data Documentation

◆ mChannels

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

Definition at line 157 of file ImportOGG.cpp.

Referenced by Import().

◆ mFile

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

Definition at line 152 of file ImportOGG.cpp.

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

◆ mStreamInfo

TranslatableStrings OggImportFileHandle::mStreamInfo
private

Definition at line 156 of file ImportOGG.cpp.

Referenced by GetStreamInfo().

◆ mStreamUsage

ArrayOf<int> OggImportFileHandle::mStreamUsage
private

Definition at line 155 of file ImportOGG.cpp.

Referenced by Import(), and SetStreamUsage().

◆ mVorbisFile

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

The documentation for this class was generated from the following file:
OggImportFileHandle::mVorbisFile
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:153
OggImportFileHandle::mChannels
std::list< NewChannelGroup > mChannels
Definition: ImportOGG.cpp:157
BasicUI::ProgressResult::Success
@ Success
Tags::HasTag
bool HasTag(const wxString &name) const
Definition: Tags.cpp:452
OggImportFileHandle::mStreamUsage
ArrayOf< int > mStreamUsage
Definition: ImportOGG.cpp:155
DESC
#define DESC
Definition: ImportOGG.cpp:47
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
XO
#define XO(s)
Definition: Internat.h:31
ImportFileHandle::mProgress
std::unique_ptr< ProgressDialog > mProgress
Definition: ImportPlugin.h:159
ImportFileHandle::ImportFileHandle
ImportFileHandle(const FilePath &filename)
Definition: ImportPlugin.cpp:36
ImportFileHandle::CreateProgress
void CreateProgress()
Definition: ImportPlugin.cpp:45
SAMPLES_PER_CALLBACK
#define SAMPLES_PER_CALLBACK
ImportFileHandle::NewWaveTrack
std::shared_ptr< WaveTrack > NewWaveTrack(WaveTrackFactory &trackFactory, sampleFormat effectiveFormat, double rate)
Build a wave track with appropriate format, which will not be narrower than the specified one.
Definition: ImportPlugin.cpp:69
Tags::SetTag
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:486
int16Sample
@ int16Sample
Definition: SampleFormat.h:32
OggImportFileHandle::mStreamInfo
TranslatableStrings mStreamInfo
Definition: ImportOGG.cpp:156
name
const TranslatableString name
Definition: Distortion.cpp:98
UTF8CTOWX
#define UTF8CTOWX(X)
Definition: Internat.h:159
Tags::Clear
void Clear()
Definition: Tags.cpp:337
ImportFileHandle::mFilename
FilePath mFilename
Definition: ImportPlugin.h:158
TAG_YEAR
#define TAG_YEAR
Definition: Tags.h:64
OggImportFileHandle::mFile
std::unique_ptr< wxFFile > mFile
Definition: ImportOGG.cpp:152
ArrayOf
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:27
CODEC_TRANSFER_SIZE
#define CODEC_TRANSFER_SIZE