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

Public Member Functions

 OpusImportFileHandle (const FilePath &filename)
 
 ~OpusImportFileHandle ()
 
bool IsOpen () const
 
TranslatableString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
void Import (ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &outAcidTags) override
 
wxInt32 GetStreamCount () override
 
const TranslatableStringsGetStreamInfo () override
 
void SetStreamUsage (wxInt32 StreamID, bool Use) override
 
- Public Member Functions inherited from ImportFileHandleEx
 ImportFileHandleEx (const FilePath &filename)
 
FilePath GetFilename () const override
 
void Cancel () override
 
void Stop () override
 
- Public Member Functions inherited from ImportFileHandle
virtual ~ImportFileHandle ()
 
virtual FilePath GetFilename () const =0
 
virtual TranslatableString GetErrorMessage () const
 
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 void Import (ImportProgressListener &progressListener, WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags, std::optional< LibFileFormats::AcidizerTags > &acidTags)=0
 
virtual void Cancel ()=0
 
virtual void Stop ()=0
 

Private Member Functions

void LogOpusError (const char *method, int error)
 
void NotifyImportFailed (ImportProgressListener &progressListener, int error)
 
void NotifyImportFailed (ImportProgressListener &progressListener, const TranslatableString &error)
 

Static Private Member Functions

static int OpusReadCallback (void *stream, unsigned char *ptr, int nbytes)
 
static int OpusSeekCallback (void *stream, opus_int64 offset, int whence)
 
static opus_int64 OpusTellCallback (void *stream)
 
static int OpusCloseCallback (void *stream)
 
static TranslatableString GetOpusErrorString (int error)
 

Private Attributes

wxFile mFile
 
OpusFileCallbacks mCallbacks
 
OggOpusFile * mOpusFile {}
 
int mNumChannels {}
 
int64_t mNumSamples {}
 
const double mSampleRate { 48000.0 }
 
const sampleFormat mFormat { floatSample }
 

Additional Inherited Members

- Public Types inherited from ImportFileHandle
using ByteCount = unsigned long long
 
- Protected Member Functions inherited from ImportFileHandleEx
void BeginImport ()
 
bool IsCancelled () const noexcept
 
bool IsStopped () const noexcept
 

Detailed Description

Definition at line 49 of file ImportOpus.cpp.

Constructor & Destructor Documentation

◆ OpusImportFileHandle()

OpusImportFileHandle::OpusImportFileHandle ( const FilePath filename)
explicit

Definition at line 137 of file ImportOpus.cpp.

138 : ImportFileHandleEx { filename }
139{
140 // Try to open the file for reading
141 if (!mFile.Open(filename, wxFile::read))
142 return;
143
144 OpusFileCallbacks callbacks = {
149 };
150
151 int error = 0;
152 mOpusFile = op_open_callbacks(this, &callbacks, nullptr, 0, &error);
153
154 if (mOpusFile == nullptr)
155 {
156 LogOpusError("Error while opening Opus file", error);
157 return;
158 }
159
160 mNumChannels = op_channel_count(mOpusFile, -1);
161 mNumSamples = op_pcm_total(mOpusFile, -1);
162}
static opus_int64 OpusTellCallback(void *stream)
Definition: ImportOpus.cpp:330
OggOpusFile * mOpusFile
Definition: ImportOpus.cpp:82
void LogOpusError(const char *method, int error)
Definition: ImportOpus.cpp:378
static int OpusCloseCallback(void *stream)
Definition: ImportOpus.cpp:337
static int OpusReadCallback(void *stream, unsigned char *ptr, int nbytes)
Definition: ImportOpus.cpp:302
static int OpusSeekCallback(void *stream, opus_int64 offset, int whence)
Definition: ImportOpus.cpp:315

References LogOpusError(), mFile, mNumChannels, mNumSamples, mOpusFile, OpusCloseCallback(), OpusReadCallback(), OpusSeekCallback(), and OpusTellCallback().

Here is the call graph for this function:

◆ ~OpusImportFileHandle()

OpusImportFileHandle::~OpusImportFileHandle ( )

Definition at line 417 of file ImportOpus.cpp.

418{
419 if (mOpusFile != nullptr)
420 op_free(mOpusFile);
421}

References mOpusFile.

Member Function Documentation

◆ GetFileDescription()

TranslatableString OpusImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 164 of file ImportOpus.cpp.

165{
166 return DESC;
167}
#define DESC
Definition: ImportOpus.cpp:33

References DESC.

◆ GetFileUncompressedBytes()

auto OpusImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 169 of file ImportOpus.cpp.

170{
171 return 0;
172}

◆ GetOpusErrorString()

TranslatableString OpusImportFileHandle::GetOpusErrorString ( int  error)
staticprivate

Definition at line 347 of file ImportOpus.cpp.

348{
349 switch (error)
350 {
351 case OP_EREAD:
352 return XO("IO error reading from file");
353 case OP_EFAULT:
354 return XO("internal error");
355 case OP_EIMPL:
356 return XO("not implemented");
357 case OP_EINVAL:
358 return XO("invalid argument");
359 case OP_ENOTFORMAT:
360 return XO("not an Opus file");
361 case OP_EBADHEADER:
362 return XO("invalid header");
363 case OP_EVERSION:
364 return XO("unsupported version");
365 case OP_EBADPACKET:
366 return XO("invalid packet");
367 case OP_EBADLINK:
368 return XO("invalid stream structure");
369 case OP_ENOSEEK:
370 return XO("stream is not seekable");
371 case OP_EBADTIMESTAMP:
372 return XO("invalid timestamp");
373 default:
374 return {};
375 }
376}
XO("Cut/Copy/Paste")

References XO().

Referenced by LogOpusError(), and NotifyImportFailed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetStreamCount()

wxInt32 OpusImportFileHandle::GetStreamCount ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 287 of file ImportOpus.cpp.

288{
289 return 1;
290}

◆ GetStreamInfo()

const TranslatableStrings & OpusImportFileHandle::GetStreamInfo ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 292 of file ImportOpus.cpp.

293{
294 static TranslatableStrings empty;
295 return empty;
296}
std::vector< TranslatableString > TranslatableStrings

◆ Import()

void OpusImportFileHandle::Import ( ImportProgressListener progressListener,
WaveTrackFactory trackFactory,
TrackHolders outTracks,
Tags tags,
std::optional< LibFileFormats::AcidizerTags > &  outAcidTags 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 174 of file ImportOpus.cpp.

178{
179 BeginImport();
180
181 outTracks.clear();
182
183 auto track = ImportUtils::NewWaveTrack(
184 *trackFactory,
186 mFormat,
188
189 /* The number of samples to read in each loop */
190 const size_t SAMPLES_TO_READ = track->GetMaxBlockSize();
191 uint64_t totalSamplesRead = 0;
192
193 const auto bufferSize = mNumChannels * SAMPLES_TO_READ;
194
195 ArrayOf<float> floatBuffer { bufferSize };
196
197 uint64_t samplesRead = 0;
198
199 do
200 {
201 int linkIndex { -1 };
202 auto samplesPerChannelRead = op_read_float(mOpusFile, floatBuffer.get(), SAMPLES_TO_READ, &linkIndex);
203
204 if (samplesPerChannelRead < 0 && samplesPerChannelRead != OP_HOLE)
205 {
206 NotifyImportFailed(progressListener, samplesPerChannelRead);
207 return;
208 }
209
210 auto linkChannels = op_head(mOpusFile, linkIndex)->channel_count;
211
212 if (linkChannels != mNumChannels)
213 {
214 NotifyImportFailed(progressListener, XO("File has changed the number of channels in the middle."));
215 return;
216 }
217
218 unsigned chn = 0;
219 ImportUtils::ForEachChannel(*track, [&](auto& channel)
220 {
221 channel.AppendBuffer(
222 reinterpret_cast<constSamplePtr>(floatBuffer.get() +
223 chn), mFormat, samplesRead, mNumChannels, mFormat
224 );
225 ++chn;
226 });
227
228 samplesRead = samplesPerChannelRead;
229 totalSamplesRead += samplesRead;
230
231 progressListener.OnImportProgress(double(totalSamplesRead) / mNumSamples);
232 } while (!IsCancelled() && !IsStopped() && samplesRead != 0);
233
234 if (IsCancelled())
235 {
236 progressListener.OnImportResult(
238 return;
239 }
240
241 if (totalSamplesRead < mNumSamples && !IsStopped())
242 {
244 return;
245 }
246
247 ImportUtils::FinalizeImport(outTracks, *track);
248
249 auto opusTags = op_tags(mOpusFile, -1);
250
251 if (opusTags != nullptr)
252 {
253 for (int i = 0; i < opusTags->comments; ++i)
254 {
255 const auto comment = opusTags->user_comments[i];
256 const auto commentLength = opusTags->comment_lengths[i];
257
258 std::string_view tag { comment,
259 std::string_view::size_type(commentLength) };
260
261 const auto separator = tag.find('=');
262
263 if (separator != std::string_view::npos)
264 {
265 auto name = audacity::ToWXString(tag.substr(0, separator));
266 const auto value = audacity::ToWXString(tag.substr(separator + 1));
267
268 // See: ImportOGG.cpp tags parsing
269 if (name.Upper() == wxT("DATE") && !tags->HasTag(TAG_YEAR))
270 {
271 long val;
272
273 if (value.length() == 4 && value.ToLong(&val))
274 name = TAG_YEAR;
275 }
276
277 tags->SetTag(name, value);
278 }
279 }
280 }
281
282 progressListener.OnImportResult(IsStopped()
285}
wxT("CloseDown"))
const TranslatableString name
Definition: Distortion.cpp:76
const char * constSamplePtr
Definition: SampleFormat.h:58
#define TAG_YEAR
Definition: Tags.h:62
bool IsStopped() const noexcept
bool IsCancelled() const noexcept
virtual void OnImportResult(ImportResult result)=0
Used to report on import result for file handle passed as argument to OnImportFileOpened.
virtual void OnImportProgress(double progress)=0
static std::shared_ptr< WaveTrack > NewWaveTrack(WaveTrackFactory &trackFactory, unsigned nChannels, sampleFormat effectiveFormat, double rate)
Definition: ImportUtils.cpp:35
static void ForEachChannel(TrackList &trackList, const std::function< void(WaveChannel &)> &op)
Iterates over channels in each wave track from the list.
Definition: ImportUtils.cpp:73
static void FinalizeImport(TrackHolders &outTracks, const std::vector< std::shared_ptr< WaveTrack > > &importedStreams)
Flushes the given channels and moves them to outTracks.
Definition: ImportUtils.cpp:49
const sampleFormat mFormat
Definition: ImportOpus.cpp:93
const double mSampleRate
Definition: ImportOpus.cpp:89
void NotifyImportFailed(ImportProgressListener &progressListener, int error)
Definition: ImportOpus.cpp:389
bool HasTag(const wxString &name) const
Definition: Tags.cpp:397
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:431
constexpr size_t npos(-1)
wxString ToWXString(const std::string &str)

References ImportFileHandleEx::BeginImport(), ImportProgressListener::Cancelled, ImportProgressListener::Error, ImportUtils::FinalizeImport(), ImportUtils::ForEachChannel(), Tags::HasTag(), ImportFileHandleEx::IsCancelled(), ImportFileHandleEx::IsStopped(), mFormat, mNumChannels, mNumSamples, mOpusFile, mSampleRate, name, ImportUtils::NewWaveTrack(), NotifyImportFailed(), Tuple::detail::npos(), ImportProgressListener::OnImportProgress(), ImportProgressListener::OnImportResult(), Tags::SetTag(), ImportProgressListener::Stopped, ImportProgressListener::Success, TAG_YEAR, audacity::ToWXString(), wxT(), and XO().

Here is the call graph for this function:

◆ IsOpen()

bool OpusImportFileHandle::IsOpen ( ) const

Definition at line 412 of file ImportOpus.cpp.

413{
414 return mOpusFile != nullptr;
415}

References mOpusFile.

◆ LogOpusError()

void OpusImportFileHandle::LogOpusError ( const char *  method,
int  error 
)
private

Definition at line 378 of file ImportOpus.cpp.

379{
380 if (error == 0)
381 return;
382
383 if (error == OP_ENOTFORMAT)
384 wxLogDebug("%s: Not Opus format", GetOpusErrorString(error).Translation());
385 else
386 wxLogError("%s: %s", method, GetOpusErrorString(error).Translation());
387}
static TranslatableString GetOpusErrorString(int error)
Definition: ImportOpus.cpp:347

References GetOpusErrorString().

Referenced by OpusImportFileHandle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ NotifyImportFailed() [1/2]

void OpusImportFileHandle::NotifyImportFailed ( ImportProgressListener progressListener,
const TranslatableString error 
)
private

Definition at line 395 of file ImportOpus.cpp.

397{
399 XO("Failed to decode Opus file: %s").Format(error));
400
401 if (IsCancelled())
402 progressListener.OnImportResult(
404 else if (!IsStopped())
405 progressListener.OnImportResult(
407 else
408 progressListener.OnImportResult(
410}
Abstract base class used in importing a file.
static void ShowMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Import Project"))
Definition: ImportUtils.cpp:43

References ImportProgressListener::Cancelled, ImportProgressListener::Error, ImportFileHandleEx::IsCancelled(), ImportFileHandleEx::IsStopped(), ImportProgressListener::OnImportResult(), ImportUtils::ShowMessageBox(), ImportProgressListener::Stopped, and XO().

Here is the call graph for this function:

◆ NotifyImportFailed() [2/2]

void OpusImportFileHandle::NotifyImportFailed ( ImportProgressListener progressListener,
int  error 
)
private

Definition at line 389 of file ImportOpus.cpp.

391{
392 NotifyImportFailed(progressListener, GetOpusErrorString(error));
393}

References GetOpusErrorString(), and NotifyImportFailed().

Referenced by Import(), and NotifyImportFailed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpusCloseCallback()

int OpusImportFileHandle::OpusCloseCallback ( void *  stream)
staticprivate

Definition at line 337 of file ImportOpus.cpp.

338{
339 auto stream = static_cast<OpusImportFileHandle*>(pstream);
340
341 if (stream->mFile.IsOpened())
342 return stream->mFile.Close() ? 0 : EOF;
343
344 return 0;
345}

References mFile.

Referenced by OpusImportFileHandle().

Here is the caller graph for this function:

◆ OpusReadCallback()

int OpusImportFileHandle::OpusReadCallback ( void *  stream,
unsigned char *  ptr,
int  nbytes 
)
staticprivate

Definition at line 302 of file ImportOpus.cpp.

304{
305 auto stream = static_cast<OpusImportFileHandle*>(pstream);
306
307 if (!stream->mFile.IsOpened())
308 return EOF;
309
310 // OpusFile never reads more than 2^31 bytes at a time,
311 // so we can safely cast ssize_t to int.
312 return int(stream->mFile.Read(ptr, nbytes));
313}

Referenced by OpusImportFileHandle().

Here is the caller graph for this function:

◆ OpusSeekCallback()

int OpusImportFileHandle::OpusSeekCallback ( void *  stream,
opus_int64  offset,
int  whence 
)
staticprivate

Definition at line 315 of file ImportOpus.cpp.

317{
318 auto stream = static_cast<OpusImportFileHandle*>(pstream);
319
320 if (!stream->mFile.IsOpened())
321 return -1;
322
323 wxSeekMode wxWhence = whence == SEEK_SET ? wxFromStart :
324 whence == SEEK_CUR ? wxFromCurrent :
325 whence == SEEK_END ? wxFromEnd : wxFromStart;
326
327 return stream->mFile.Seek(offset, wxWhence) != wxInvalidOffset ? 0 : -1;
328}

References mFile.

Referenced by OpusImportFileHandle().

Here is the caller graph for this function:

◆ OpusTellCallback()

opus_int64 OpusImportFileHandle::OpusTellCallback ( void *  stream)
staticprivate

Definition at line 330 of file ImportOpus.cpp.

331{
332 auto stream = static_cast<OpusImportFileHandle*>(pstream);
333
334 return static_cast<opus_int64>(stream->mFile.Tell());
335}

Referenced by OpusImportFileHandle().

Here is the caller graph for this function:

◆ SetStreamUsage()

void OpusImportFileHandle::SetStreamUsage ( wxInt32  StreamID,
bool  Use 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 298 of file ImportOpus.cpp.

299{
300}

Member Data Documentation

◆ mCallbacks

OpusFileCallbacks OpusImportFileHandle::mCallbacks
private

Definition at line 81 of file ImportOpus.cpp.

◆ mFile

wxFile OpusImportFileHandle::mFile
private

Definition at line 79 of file ImportOpus.cpp.

Referenced by OpusCloseCallback(), OpusImportFileHandle(), and OpusSeekCallback().

◆ mFormat

const sampleFormat OpusImportFileHandle::mFormat { floatSample }
private

Definition at line 93 of file ImportOpus.cpp.

Referenced by Import().

◆ mNumChannels

int OpusImportFileHandle::mNumChannels {}
private

Definition at line 83 of file ImportOpus.cpp.

Referenced by Import(), and OpusImportFileHandle().

◆ mNumSamples

int64_t OpusImportFileHandle::mNumSamples {}
private

Definition at line 84 of file ImportOpus.cpp.

Referenced by Import(), and OpusImportFileHandle().

◆ mOpusFile

OggOpusFile* OpusImportFileHandle::mOpusFile {}
private

Definition at line 82 of file ImportOpus.cpp.

Referenced by Import(), IsOpen(), OpusImportFileHandle(), and ~OpusImportFileHandle().

◆ mSampleRate

const double OpusImportFileHandle::mSampleRate { 48000.0 }
private

Definition at line 89 of file ImportOpus.cpp.

Referenced by Import().


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