Audacity  2.3.1
Classes | Macros | Functions | Variables
ImportMP3.cpp File Reference
#include "../Audacity.h"
#include "ImportMP3.h"
#include <wx/wxprec.h>
#include <wx/window.h>
#include <wx/defs.h>
#include <wx/intl.h>
#include "../AudacityException.h"
#include "../Prefs.h"
#include "Import.h"
#include "ImportPlugin.h"
#include "../Internat.h"
#include "../Tags.h"
#include "../prefs/QualityPrefs.h"
#include <wx/textctrl.h>
#include <wx/file.h>
#include <wx/thread.h>
#include <wx/progdlg.h>
#include <wx/string.h>
#include <wx/timer.h>
#include "../WaveTrack.h"
#include "mad.h"

Go to the source code of this file.

Classes

struct  private_data
 
class  MP3ImportPlugin
 An ImportPlugin for MP3 data. More...
 
class  MP3ImportFileHandle
 An ImportFileHandle for MP3 data. More...
 

Macros

#define DESC   _("MP3 files")
 
#define INPUT_BUFFER_SIZE   65535
 
#define PROGRESS_SCALING_FACTOR   100000
 

Functions

void GetMP3ImportPlugin (ImportPluginList &importPluginList, UnusableImportPluginList &WXUNUSED(unusableImportPluginList))
 
enum mad_flow input_cb (void *_data, struct mad_stream *stream)
 
enum mad_flow output_cb (void *_data, struct mad_header const *header, struct mad_pcm *pcm)
 
enum mad_flow error_cb (void *_data, struct mad_stream *stream, struct mad_frame *frame)
 
float scale (mad_fixed_t sample)
 
enum mad_flow output_cb (void *_data, struct mad_header const *WXUNUSED(header), struct mad_pcm *pcm)
 
enum mad_flow error_cb (void *WXUNUSED(_data), struct mad_stream *WXUNUSED(stream), struct mad_frame *WXUNUSED(frame))
 

Variables

static const wxChar * exts []
 

Macro Definition Documentation

#define DESC   _("MP3 files")
#define INPUT_BUFFER_SIZE   65535

Definition at line 94 of file ImportMP3.cpp.

Referenced by input_cb().

#define PROGRESS_SCALING_FACTOR   100000

Definition at line 95 of file ImportMP3.cpp.

Function Documentation

enum mad_flow error_cb ( void *  _data,
struct mad_stream stream,
struct mad_frame frame 
)
enum mad_flow error_cb ( void *  WXUNUSED_data,
struct mad_stream WXUNUSEDstream,
struct mad_frame WXUNUSEDframe 
)

Definition at line 540 of file ImportMP3.cpp.

542 {
543 /* enum mad_flow {
544  MAD_FLOW_CONTINUE = 0x0000,
545  MAD_FLOW_STOP = 0x0010,
546  MAD_FLOW_BREAK = 0x0011,
547  MAD_FLOW_IGNORE = 0x0020
548  }; */
549  /*
550  wxPrintf("decoding error 0x%04x (%s)\n",
551  stream->error, mad_stream_errorstr(stream));
552  */
553 
554  return MAD_FLOW_CONTINUE;
555 
556  /* return MAD_FLOW_BREAK; */
557 }
void GetMP3ImportPlugin ( ImportPluginList importPluginList,
UnusableImportPluginList WXUNUSEDunusableImportPluginList 
)

Definition at line 163 of file ImportMP3.cpp.

Referenced by Importer::Initialize().

165 {
166  importPluginList.push_back( std::make_unique<MP3ImportPlugin>() );
167 }
enum mad_flow input_cb ( void *  _data,
struct mad_stream stream 
)

Definition at line 406 of file ImportMP3.cpp.

References private_data::eof, private_data::file, private_data::id3checked, INPUT_BUFFER_SIZE, private_data::inputBufferFill, private_data::progress, Success, ProgressDialog::Update(), and private_data::updateResult.

Referenced by MP3ImportFileHandle::Import().

407 {
408  struct private_data *data = (struct private_data *)_data;
409 
410  data->updateResult = data->progress->Update((wxULongLong_t)data->file->Tell(),
411  (wxULongLong_t)data->file->Length() != 0 ?
412  (wxULongLong_t)data->file->Length() : 1);
414  return MAD_FLOW_STOP;
415 
416  if (data->eof) {
417  /* different from data->File->Eof(), this means the underlying
418  file has reached eof *and* we have subsequently supplied the
419  final padding zeros */
420  return MAD_FLOW_STOP;
421  }
422 
423 #ifdef USE_LIBID3TAG
424  if (!data->id3checked) {
425  data->file->Read(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
426  int len = id3_tag_query(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
427  if (len > 0) {
428  data->file->Seek(len, wxFromStart);
429  }
430  else {
431  data->file->Seek(0);
432  }
433 
434  data->id3checked = true;
435  }
436 #endif
437 
438  /* "Each time you refill your buffer, you need to preserve the data in
439  * your existing buffer from stream.next_frame to the end.
440  *
441  * This usually amounts to calling memmove() on this unconsumed portion
442  * of the buffer and appending NEW data after it, before calling
443  * mad_stream_buffer()"
444  * -- Rob Leslie, on the mad-dev mailing list */
445 
446  int unconsumedBytes;
447  if(stream->next_frame ) {
448  /* we must use inputBufferFill instead of INPUT_BUFFER_SIZE here
449  because the final buffer of the file may be only partially
450  filled, and we would otherwise be providing too much input
451  after eof */
452  unconsumedBytes = data->inputBuffer.get() + data->inputBufferFill
453  - stream->next_frame;
454  if (unconsumedBytes > 0)
455  memmove(data->inputBuffer.get(), stream->next_frame, unconsumedBytes);
456  }
457  else
458  unconsumedBytes = 0;
459 
460  if (data->file->Eof() &&
461  (unconsumedBytes + MAD_BUFFER_GUARD < INPUT_BUFFER_SIZE)) {
462 
463  /* supply the requisite MAD_BUFFER_GUARD zero bytes to ensure
464  the final frame gets decoded properly, then finish */
465 
466  memset(data->inputBuffer.get() + unconsumedBytes, 0, MAD_BUFFER_GUARD);
467  mad_stream_buffer
468  (stream, data->inputBuffer.get(), MAD_BUFFER_GUARD + unconsumedBytes);
469 
470  data->eof = true; /* so on next call, we will tell mad to stop */
471 
472  return MAD_FLOW_CONTINUE;
473  }
474 
475  off_t read = data->file->Read(data->inputBuffer.get() + unconsumedBytes,
476  INPUT_BUFFER_SIZE - unconsumedBytes);
477 
478  mad_stream_buffer(stream, data->inputBuffer.get(), read + unconsumedBytes);
479 
480  data->inputBufferFill = int(read + unconsumedBytes);
481 
482  return MAD_FLOW_CONTINUE;
483 }
#define INPUT_BUFFER_SIZE
Definition: ImportMP3.cpp:94
ProgressDialog * progress
Definition: ImportMP3.cpp:106
ProgressResult updateResult
Definition: ImportMP3.cpp:108
ProgressResult Update(int value, const wxString &message=wxEmptyString)
wxFile * file
Definition: ImportMP3.cpp:101
int inputBufferFill
Definition: ImportMP3.cpp:103
enum mad_flow output_cb ( void *  _data,
struct mad_header const *  header,
struct mad_pcm pcm 
)
enum mad_flow output_cb ( void *  _data,
struct mad_header const *  WXUNUSEDheader,
struct mad_pcm pcm 
)

Definition at line 488 of file ImportMP3.cpp.

References private_data::channels, floatSample, format, MakeSimpleGuard(), TrackFactory::NewWaveTrack(), private_data::numChannels, QualityPrefs::SampleFormatChoice(), scale(), and private_data::trackFactory.

491 {
492  // Don't C++ exceptions propagate through mad
493  return GuardedCall< mad_flow > ( [&] {
494  int samplerate;
495  struct private_data *data = (struct private_data *)_data;
496 
497  samplerate= pcm->samplerate;
498  auto channels = pcm->channels;
499  const auto samples = pcm->length;
500 
501  /* If this is the first run, we need to create the WaveTracks that
502  * will hold the data. We do this now because now is the first
503  * moment when we know how many channels there are. */
504 
505  if(data->channels.empty()) {
506  data->channels.resize(channels);
507 
509 
510  for(auto &channel: data->channels)
511  channel = data->trackFactory->NewWaveTrack(format, samplerate);
512 
513  data->numChannels = channels;
514  }
515  else {
516  // This is not the first run, protect us from libmad glitching
517  // on the number of channels
518  channels = data->numChannels;
519  }
520 
521  /* TODO: get rid of this by adding fixed-point support to SampleFormat.
522  * For now, we allocate temporary float buffers to convert the fixed
523  * point samples into something we can feed to the WaveTrack. Allocating
524  * big blocks of data like this isn't a great idea, but it's temporary.
525  */
526  FloatBuffers channelBuffers{ channels, samples };
527  for(size_t smpl = 0; smpl < samples; smpl++)
528  for(int chn = 0; chn < channels; chn++)
529  channelBuffers[chn][smpl] = scale(pcm->samples[chn][smpl]);
530 
531  for(int chn = 0; chn < channels; chn++)
532  data->channels[chn]->Append((samplePtr)channelBuffers[chn].get(),
533  floatSample,
534  samples);
535 
536  return MAD_FLOW_CONTINUE;
537  }, MakeSimpleGuard(MAD_FLOW_BREAK) );
538 }
NewChannelGroup channels
Definition: ImportMP3.cpp:105
float scale(mad_fixed_t sample)
Definition: ImportMP3.cpp:180
SimpleGuard< R > MakeSimpleGuard(R value)
int format
Definition: ExportPCM.cpp:56
char * samplePtr
Definition: Types.h:203
std::unique_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:78
TrackFactory * trackFactory
Definition: ImportMP3.cpp:104
static sampleFormat SampleFormatChoice()
unsigned numChannels
Definition: ImportMP3.cpp:107
float scale ( mad_fixed_t  sample)
inline

Variable Documentation

const wxChar* exts[]
static
Initial value:
=
{
wxT("mp3"),
wxT("mp2"),
wxT("mpa")
}

Definition at line 52 of file ImportMP3.cpp.