Audacity 3.2.0
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle Class Referencefinal
Inheritance diagram for anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle:
[legend]
Collaboration diagram for anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle:
[legend]

Public Member Functions

 MP3ImportFileHandle (const FilePath &filename)
 
 ~MP3ImportFileHandle ()
 
TranslatableString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
ProgressResult Import (WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
 
bool SetupOutputFormat ()
 
void ReadTags (Tags *tags)
 
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 Member Functions

bool Open ()
 

Static Private Member Functions

static ptrdiff_t ReadCallback (void *handle, void *buffer, size_t size)
 
static off_t SeekCallback (void *handle, off_t offset, int whence)
 

Private Attributes

wxFile mFile
 
wxFileOffset mFileLen { 0 }
 
WaveTrackFactorymTrackFactory { nullptr }
 
NewChannelGroup mChannels
 
unsigned mNumChannels { 0 }
 
ProgressResult mUpdateResult { ProgressResult::Success }
 
mpg123_handle * mHandle { nullptr }
 
bool mFloat64Output {}
 
friend MP3ImportPlugin
 

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 126 of file ImportMP3_MPG123.cpp.

Constructor & Destructor Documentation

◆ MP3ImportFileHandle()

MP3ImportFileHandle::MP3ImportFileHandle ( const FilePath filename)

Definition at line 188 of file ImportMP3_MPG123.cpp.

189 : ImportFileHandle(filename)
190{
191 int errorCode = MPG123_OK;
192 mHandle = mpg123_new(nullptr, &errorCode);
193
194 if (errorCode != MPG123_OK)
195 {
196 wxLogError(
197 "Failed to create MPG123 handle: %s",
198 mpg123_plain_strerror(errorCode));
199
200 mHandle = nullptr;
201
202 return;
203 }
204
205 errorCode = mpg123_replace_reader_handle(
207
208 if (errorCode != MPG123_OK)
209 {
210 wxLogError(
211 "Failed to set reader on the MPG123 handle: %s",
212 mpg123_plain_strerror(errorCode));
213
214 mpg123_delete(mHandle);
215 mHandle = nullptr;
216 }
217
218 // We force mpg123 to decode into floats
219 mpg123_param(mHandle, MPG123_FLAGS, MPG123_FORCE_FLOAT, 0.0);
220
221 if (errorCode != MPG123_OK)
222 {
223 wxLogError(
224 "Failed to set options on the MPG123 handle",
225 mpg123_plain_strerror(errorCode));
226
227 mpg123_delete(mHandle);
228 mHandle = nullptr;
229 }
230}
ImportFileHandle(const FilePath &filename)
static ptrdiff_t ReadCallback(void *handle, void *buffer, size_t size)
static off_t SeekCallback(void *handle, off_t offset, int whence)

References mHandle, ReadCallback(), and SeekCallback().

Here is the call graph for this function:

◆ ~MP3ImportFileHandle()

MP3ImportFileHandle::~MP3ImportFileHandle ( )

Definition at line 232 of file ImportMP3_MPG123.cpp.

233{
234 // nullptr is a valid input for the mpg123_delete
235 mpg123_delete(mHandle);
236}

References mHandle.

Member Function Documentation

◆ GetFileDescription()

TranslatableString MP3ImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 238 of file ImportMP3_MPG123.cpp.

239{
240 return DESC;
241}
#define DESC

References DESC.

◆ GetFileUncompressedBytes()

auto MP3ImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 243 of file ImportMP3_MPG123.cpp.

244{
245 // We have to parse the file first using mpg123_scan,
246 // we do not want to do that before the import starts.
247 return 0;
248}

◆ GetStreamCount()

wxInt32 MP3ImportFileHandle::GetStreamCount ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 250 of file ImportMP3_MPG123.cpp.

251{
252 return 1;
253}

◆ GetStreamInfo()

const TranslatableStrings & MP3ImportFileHandle::GetStreamInfo ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 255 of file ImportMP3_MPG123.cpp.

256{
257 static TranslatableStrings empty;
258 return empty;
259}
std::vector< TranslatableString > TranslatableStrings

◆ Import()

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

Implements ImportFileHandle.

Definition at line 265 of file ImportMP3_MPG123.cpp.

268{
269 auto finalAction = finally([handle = mHandle]() { mpg123_close(handle); });
270
271 outTracks.clear();
272 mTrackFactory = trackFactory;
273
275
276 long long framesCount = mpg123_framelength(mHandle);
277
278 mUpdateResult = mProgress->Update(0ll, framesCount);
279
282
283 if (!SetupOutputFormat())
284 return ProgressResult::Failed;
285
286 off_t frameIndex { 0 };
287 unsigned char* data { nullptr };
288 size_t dataSize { 0 };
289
290 std::vector<float> conversionBuffer;
291
292 int ret = MPG123_OK;
293
294 while ((ret = mpg123_decode_frame(mHandle, &frameIndex, &data, &dataSize)) ==
295 MPG123_OK)
296 {
297 mUpdateResult = mProgress->Update(
298 static_cast<long long>(frameIndex), framesCount);
299
302
303 constSamplePtr samples = reinterpret_cast<constSamplePtr>(data);
304 const size_t samplesCount = dataSize / sizeof(float) / mNumChannels;
305
306 // libmpg123 picks up the format based on some "internal" precision.
307 // This case is not expected to happen
308 if (mFloat64Output)
309 {
310 conversionBuffer.resize(samplesCount * mNumChannels);
311
312 for (size_t sampleIndex = 0; sampleIndex < conversionBuffer.size();
313 ++sampleIndex)
314 {
315 conversionBuffer[sampleIndex] = static_cast<float>(
316 reinterpret_cast<const double*>(data)[sampleIndex]);
317 }
318
319 samples = reinterpret_cast<constSamplePtr>(conversionBuffer.data());
320 }
321 // Just copy the interleaved data to the channels
322 for (unsigned channel = 0; channel < mNumChannels; ++channel)
323 {
324 mChannels[channel]->Append(
325 samples + sizeof(float) * channel, floatSample, samplesCount,
327 }
328 }
329
330 if (ret != MPG123_DONE)
331 {
332 wxLogError(
333 "Failed to decode MP3 file: %s", mpg123_plain_strerror(ret));
334
335 return ProgressResult::Failed;
336 }
337
338 // Flush and trim the channels
339 for (const auto &channel : mChannels)
340 channel->Flush();
341
342 // Copy the WaveTrack pointers into the Track pointer list that
343 // we are expected to fill
344 outTracks.push_back(std::move(mChannels));
345
346 ReadTags(tags);
347
348 return mUpdateResult;
349}
constexpr sampleFormat floatSample
Definition: SampleFormat.h:43
const char * constSamplePtr
Definition: SampleFormat.h:56
std::unique_ptr< ProgressDialog > mProgress
Definition: ImportPlugin.h:164

References RefreshCode::Cancelled, ImportFileHandle::CreateProgress(), floatSample, mChannels, mFloat64Output, mHandle, mNumChannels, ImportFileHandle::mProgress, mTrackFactory, mUpdateResult, ReadTags(), and SetupOutputFormat().

Here is the call graph for this function:

◆ Open()

bool MP3ImportFileHandle::Open ( )
private

Definition at line 451 of file ImportMP3_MPG123.cpp.

452{
453 if (mHandle == nullptr)
454 return false;
455
456 // Open the file
457 if (!mFile.Open(mFilename))
458 {
459 return false;
460 }
461
462 // Get the length of the file
463 mFileLen = mFile.Seek(0, wxFromEnd);
464
465 if (mFileLen == wxInvalidOffset || mFile.Error())
466 {
467 mFile.Close();
468 return false;
469 }
470
471 if (mFile.Seek(0, wxFromStart) == wxInvalidOffset || mFile.Error())
472 {
473 mFile.Close();
474 return false;
475 }
476
477 // Check if file is an MP3
478 auto errorCode = mpg123_open_handle(mHandle, this);
479
480 if (errorCode != MPG123_OK)
481 return false;
482
483 // Scan the file
484 errorCode = mpg123_scan(mHandle);
485
486 if (errorCode != MPG123_OK)
487 return false;
488
489 // Read the output format
490 errorCode = mpg123_decode_frame(mHandle, nullptr, nullptr, nullptr);
491
492 // First decode should read the format
493 if (errorCode != MPG123_NEW_FORMAT)
494 return false;
495
496 return true;
497}
FilePath mFilename
Definition: ImportPlugin.h:163

References mFile, mFileLen, ImportFileHandle::mFilename, and mHandle.

◆ ReadCallback()

ptrdiff_t MP3ImportFileHandle::ReadCallback ( void *  handle,
void *  buffer,
size_t  size 
)
staticprivate

Definition at line 499 of file ImportMP3_MPG123.cpp.

501{
502 return static_cast<MP3ImportFileHandle*>(handle)->mFile.Read(buffer, size);
503}
An ImportFileHandle for MP3 data.

References mFile, and size.

Referenced by MP3ImportFileHandle().

Here is the caller graph for this function:

◆ ReadTags()

void MP3ImportFileHandle::ReadTags ( Tags tags)

Definition at line 376 of file ImportMP3_MPG123.cpp.

377{
378 mpg123_id3v1* v1;
379 mpg123_id3v2* v2;
380 int meta;
381
382 meta = mpg123_meta_check(mHandle);
383
384 if (meta & MPG123_ID3 && mpg123_id3(mHandle, &v1, &v2) == MPG123_OK)
385 {
386 if (v2 != nullptr && v2->title != nullptr && v2->title->fill > 0)
387 tags->SetTag(TAG_TITLE, audacity::ToWXString(v2->title->p));
388 else if (v1 != nullptr && v1->title[0] != '\0')
389 tags->SetTag(TAG_TITLE, audacity::ToWXString(v1->title));
390
391 if (v2 != nullptr && v2->artist != nullptr && v2->artist->fill > 0)
392 tags->SetTag(TAG_ARTIST, audacity::ToWXString(v2->artist->p));
393 else if (v1 != nullptr && v1->artist[0] != '\0')
394 tags->SetTag(TAG_ARTIST, audacity::ToWXString(v1->artist));
395
396 if (v2 != nullptr && v2->album != nullptr && v2->album->fill > 0)
397 tags->SetTag(TAG_ALBUM, audacity::ToWXString(v2->album->p));
398 else if (v1 != nullptr && v1->album[0] != '\0')
399 tags->SetTag(TAG_ALBUM, audacity::ToWXString(v1->album));
400
401 if (v2 != nullptr && v2->year != nullptr && v2->year->fill > 0)
402 tags->SetTag(TAG_YEAR, audacity::ToWXString(v2->year->p));
403 else if (v1 != nullptr && v1->year[0] != '\0')
404 tags->SetTag(TAG_YEAR, audacity::ToWXString(std::string(v1->year, 4)));
405
406 if (v2 != nullptr && v2->genre != nullptr && v2->genre->fill > 0)
407 tags->SetTag(TAG_GENRE, GetId3v2Genre(*tags, v2->genre->p));
408 else if (v1 != nullptr)
409 tags->SetTag(TAG_GENRE, tags->GetGenre(v1->genre));
410
411 if (v2 != nullptr && v2->comment != nullptr && v2->comment->fill > 0)
412 tags->SetTag(TAG_COMMENTS, audacity::ToWXString(v2->comment->p));
413 else if (v1 != nullptr && v1->comment[0] != '\0')
414 tags->SetTag(TAG_COMMENTS, audacity::ToWXString(v1->comment));
415
416 if (v2 != nullptr)
417 {
418 for (size_t i = 0; i < v2->comments; ++i)
419 {
420 if (v2->comment_list[i].text.fill == 0)
421 continue;
422
423 tags->SetTag(
424 audacity::ToWXString(std::string(v2->comment_list[i].id, 4)),
425 audacity::ToWXString(v2->comment_list[i].text.p));
426 }
427
428 for (size_t i = 0; i < v2->extras; ++i)
429 {
430 if (v2->extra[i].text.fill == 0)
431 continue;
432
433 tags->SetTag(
434 audacity::ToWXString(std::string(v2->extra[i].id, 4)),
435 audacity::ToWXString(v2->extra[i].text.p));
436 }
437
438 // libmpg123 does not parse TRCK tag, we have to do it ourselves
439 for (size_t i = 0; i < v2->texts; ++i)
440 {
441 if (memcmp(v2->text[i].id, "TRCK", 4) == 0)
442 {
443 tags->SetTag(
444 TAG_TRACK, audacity::ToWXString(v2->text[i].text.p));
445 }
446 }
447 }
448 }
449}
#define TAG_TRACK
Definition: Tags.h:61
#define TAG_COMMENTS
Definition: Tags.h:64
#define TAG_GENRE
Definition: Tags.h:63
#define TAG_ALBUM
Definition: Tags.h:60
#define TAG_YEAR
Definition: Tags.h:62
#define TAG_TITLE
Definition: Tags.h:58
#define TAG_ARTIST
Definition: Tags.h:59
wxString GetGenre(int value)
Definition: Tags.cpp:383
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:441
wxString GetId3v2Genre(Tags &tags, const char *genre)
wxString ToWXString(const std::string &str)

References Tags::GetGenre(), anonymous_namespace{ImportMP3_MPG123.cpp}::GetId3v2Genre(), mHandle, Tags::SetTag(), TAG_ALBUM, TAG_ARTIST, TAG_COMMENTS, TAG_GENRE, TAG_TITLE, TAG_TRACK, TAG_YEAR, and audacity::ToWXString().

Referenced by Import().

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

◆ SeekCallback()

off_t MP3ImportFileHandle::SeekCallback ( void *  handle,
off_t  offset,
int  whence 
)
staticprivate

Definition at line 523 of file ImportMP3_MPG123.cpp.

525{
526 return static_cast<MP3ImportFileHandle*>(handle)->mFile.Seek(
527 offset, GetWXSeekMode(whence));
528}

References anonymous_namespace{ImportMP3_MPG123.cpp}::GetWXSeekMode(), and mFile.

Referenced by MP3ImportFileHandle().

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

◆ SetStreamUsage()

void anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::SetStreamUsage ( wxInt32  StreamID,
bool  Use 
)
overridevirtual

Implements ImportFileHandle.

◆ SetupOutputFormat()

bool MP3ImportFileHandle::SetupOutputFormat ( )

Definition at line 351 of file ImportMP3_MPG123.cpp.

352{
353 long rate;
354 int channels;
355 int encoding = MPG123_ENC_FLOAT_32;
356 mpg123_getformat(mHandle, &rate, &channels, &encoding);
357
358 mNumChannels = channels == MPG123_MONO ? 1 : 2;
359 mChannels.resize(mNumChannels);
360
361 if (encoding != MPG123_ENC_FLOAT_32 && encoding != MPG123_ENC_FLOAT_64)
362 {
363 wxLogError("MPG123 returned unexpected encoding");
364
365 return false;
366 }
367
368 mFloat64Output = encoding == MPG123_ENC_FLOAT_64;
369
370 for (unsigned i = 0; i < mNumChannels; ++i)
371 mChannels[i] = NewWaveTrack(*mTrackFactory, floatSample, rate);
372
373 return true;
374}
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.

References floatSample, mChannels, mFloat64Output, mHandle, mNumChannels, mTrackFactory, and ImportFileHandle::NewWaveTrack().

Referenced by Import().

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

Member Data Documentation

◆ mChannels

NewChannelGroup anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mChannels
private

Definition at line 155 of file ImportMP3_MPG123.cpp.

Referenced by Import(), and SetupOutputFormat().

◆ mFile

wxFile anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mFile
private

Definition at line 151 of file ImportMP3_MPG123.cpp.

Referenced by Open(), ReadCallback(), and SeekCallback().

◆ mFileLen

wxFileOffset anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mFileLen { 0 }
private

Definition at line 152 of file ImportMP3_MPG123.cpp.

Referenced by Open().

◆ mFloat64Output

bool anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mFloat64Output {}
private

Definition at line 162 of file ImportMP3_MPG123.cpp.

Referenced by Import(), and SetupOutputFormat().

◆ mHandle

mpg123_handle* anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mHandle { nullptr }
private

◆ mNumChannels

unsigned anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mNumChannels { 0 }
private

Definition at line 156 of file ImportMP3_MPG123.cpp.

Referenced by Import(), and SetupOutputFormat().

◆ MP3ImportPlugin

friend anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::MP3ImportPlugin
private

Definition at line 164 of file ImportMP3_MPG123.cpp.

◆ mTrackFactory

WaveTrackFactory* anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mTrackFactory { nullptr }
private

Definition at line 154 of file ImportMP3_MPG123.cpp.

Referenced by Import(), and SetupOutputFormat().

◆ mUpdateResult

ProgressResult anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::mUpdateResult { ProgressResult::Success }
private

Definition at line 158 of file ImportMP3_MPG123.cpp.

Referenced by Import().


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