Audacity 3.2.0
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 ()
 
virtual TranslatableString GetFileDescription ()=0
 
virtual ByteCount GetFileUncompressedBytes ()=0
 
virtual wxInt32 GetStreamCount ()=0
 
virtual const TranslatableStringsGetStreamInfo ()=0
 
virtual void SetStreamUsage (wxInt32 StreamID, bool Use)=0
 
virtual ProgressResult Import (WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags)=0
 

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 95 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 98 of file ImportOGG.cpp.

101 : ImportFileHandle(filename),
102 mFile(std::move(file)),
103 mVorbisFile(std::move(vorbisFile))
104 , mStreamUsage{ static_cast<size_t>(mVorbisFile->links) }
105 {
106 for (int i = 0; i < mVorbisFile->links; i++)
107 {
108 auto strinfo = XO("Index[%02x] Version[%d], Channels[%d], Rate[%ld]")
109 .Format(
110 (unsigned int) i,
111 mVorbisFile->vi[i].version,
112 mVorbisFile->vi[i].channels,
113 mVorbisFile->vi[i].rate);
114 mStreamInfo.push_back(strinfo);
115 mStreamUsage[i] = 0;
116 }
117
118 }
XO("Cut/Copy/Paste")
ImportFileHandle(const FilePath &filename)
std::unique_ptr< wxFFile > mFile
Definition: ImportOGG.cpp:149
ArrayOf< int > mStreamUsage
Definition: ImportOGG.cpp:152
TranslatableStrings mStreamInfo
Definition: ImportOGG.cpp:153
std::unique_ptr< OggVorbis_File > mVorbisFile
Definition: ImportOGG.cpp:150

References mStreamInfo, mStreamUsage, mVorbisFile, and XO().

Here is the call graph for this function:

◆ ~OggImportFileHandle()

OggImportFileHandle::~OggImportFileHandle ( )

Definition at line 380 of file ImportOGG.cpp.

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

References mFile, and mVorbisFile.

Member Function Documentation

◆ GetFileDescription()

TranslatableString OggImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 214 of file ImportOGG.cpp.

215{
216 return DESC;
217}
#define DESC
Definition: ImportOGG.cpp:46

References DESC.

◆ GetFileUncompressedBytes()

auto OggImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 219 of file ImportOGG.cpp.

220{
221 // TODO:
222 return 0;
223}

◆ GetStreamCount()

wxInt32 OggImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 126 of file ImportOGG.cpp.

127 {
128 if (mVorbisFile)
129 return mVorbisFile->links;
130 else
131 return 0;
132 }

References mVorbisFile.

◆ GetStreamInfo()

const TranslatableStrings & OggImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 134 of file ImportOGG.cpp.

135 {
136 return mStreamInfo;
137 }

References mStreamInfo.

◆ Import()

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

Implements ImportFileHandle.

Definition at line 225 of file ImportOGG.cpp.

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

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, UTF8CTOWX, and wxT().

Here is the call graph for this function:

◆ SetStreamUsage()

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

Implements ImportFileHandle.

Definition at line 139 of file ImportOGG.cpp.

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

References mStreamUsage, and mVorbisFile.

Member Data Documentation

◆ mChannels

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

Definition at line 154 of file ImportOGG.cpp.

Referenced by Import().

◆ mFile

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

Definition at line 149 of file ImportOGG.cpp.

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

◆ mStreamInfo

TranslatableStrings OggImportFileHandle::mStreamInfo
private

Definition at line 153 of file ImportOGG.cpp.

Referenced by GetStreamInfo(), and OggImportFileHandle().

◆ mStreamUsage

ArrayOf<int> OggImportFileHandle::mStreamUsage
private

Definition at line 152 of file ImportOGG.cpp.

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

◆ mVorbisFile

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

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