Audacity  2.2.2
ImportMP3.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ImportMP3.cpp
6 
7  Joshua Haberman
8  Leland Lucius
9 
10 *//****************************************************************//****************************************************************//*******************************************************************/
28 
29 #include "../Audacity.h"
30 #include "ImportMP3.h"
31 
32 // For compilers that support precompilation, includes "wx/wx.h".
33 #include <wx/wxprec.h>
34 
35 #ifndef WX_PRECOMP
36 #include <wx/window.h>
37 #endif
38 
39 #include <wx/defs.h>
40 #include <wx/intl.h>
41 
42 #include "../AudacityException.h"
43 #include "../Prefs.h"
44 #include "Import.h"
45 #include "ImportPlugin.h"
46 #include "../Internat.h"
47 #include "../Tags.h"
48 #include "../prefs/QualityPrefs.h"
49 
50 #define DESC _("MP3 files")
51 
52 static const wxChar *exts[] =
53 {
54  wxT("mp3"),
55  wxT("mp2"),
56  wxT("mpa")
57 };
58 
59 #ifndef USE_LIBMAD
60 
61 void GetMP3ImportPlugin(ImportPluginList &importPluginList,
62  UnusableImportPluginList &unusableImportPluginList)
63 {
64  unusableImportPluginList.push_back(
65  std::make_unique<UnusableImportPlugin>
66  (DESC, wxArrayString(WXSIZEOF(exts), exts))
67  );
68 }
69 
70 #else /* USE_LIBMAD */
71 
72 #include <wx/textctrl.h>
73 #include <wx/file.h>
74 #include <wx/thread.h>
75 #include <wx/progdlg.h>
76 #include <wx/string.h>
77 #include <wx/timer.h>
78 #include <wx/intl.h>
79 
80 extern "C" {
81 #include "mad.h"
82 
83 #ifdef USE_LIBID3TAG
84 #include <id3tag.h>
85 #endif
86 }
87 
88 #include "../WaveTrack.h"
89 
90 #define INPUT_BUFFER_SIZE 65535
91 #define PROGRESS_SCALING_FACTOR 100000
92 
93 /* this is a private structure we can use for whatever we like, and it will get
94  * passed to each of the callback routines, allowing us to keep track of
95  * things. */
96 struct private_data {
97  wxFile *file; /* the file containing the mp3 data we're feeding the encoder */
98  ArrayOf<unsigned char> inputBuffer{ static_cast<unsigned int>(INPUT_BUFFER_SIZE) };
99  int inputBufferFill; /* amount of data in inputBuffer */
100  TrackFactory *trackFactory;
101  TrackHolders channels;
102  ProgressDialog *progress;
103  unsigned numChannels;
104  ProgressResult updateResult;
105  bool id3checked;
106  bool eof; /* having supplied both underlying file and guard pad data */
107 };
108 
109 class MP3ImportPlugin final : public ImportPlugin
110 {
111 public:
112  MP3ImportPlugin():
113  ImportPlugin(wxArrayString(WXSIZEOF(exts), exts))
114  {
115  }
116 
117  ~MP3ImportPlugin() { }
118 
119  wxString GetPluginStringID() override { return wxT("libmad"); }
120  wxString GetPluginFormatDescription() override;
121  std::unique_ptr<ImportFileHandle> Open(const wxString &Filename) override;
122 };
123 
124 class MP3ImportFileHandle final : public ImportFileHandle
125 {
126 public:
127  MP3ImportFileHandle(std::unique_ptr<wxFile> &&file, wxString filename):
128  ImportFileHandle(filename),
129  mFile(std::move(file))
130  {
131  }
132 
134 
135  wxString GetFileDescription() override;
136  ByteCount GetFileUncompressedBytes() override;
137  ProgressResult Import(TrackFactory *trackFactory, TrackHolders &outTracks,
138  Tags *tags) override;
139 
140  wxInt32 GetStreamCount() override { return 1; }
141 
142  const wxArrayString &GetStreamInfo() override
143  {
144  static wxArrayString empty;
145  return empty;
146  }
147 
148  void SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
149  {}
150 
151 private:
152  void ImportID3(Tags *tags);
153 
154  std::unique_ptr<wxFile> mFile;
155  void *mUserData;
156  mad_decoder mDecoder;
157 };
158 
159 void GetMP3ImportPlugin(ImportPluginList &importPluginList,
160  UnusableImportPluginList & WXUNUSED(unusableImportPluginList))
161 {
162  importPluginList.push_back( std::make_unique<MP3ImportPlugin>() );
163 }
164 
165 /* The MAD callbacks */
166 enum mad_flow input_cb(void *_data, struct mad_stream *stream);
167 enum mad_flow output_cb(void *_data,
168  struct mad_header const *header,
169  struct mad_pcm *pcm);
170 enum mad_flow error_cb(void *_data, struct mad_stream *stream,
171  struct mad_frame *frame);
172 
173 /* convert libmad's fixed point representation to 16 bit signed integers. This
174  * code is taken verbatim from minimad.c. */
175 
176 inline float scale(mad_fixed_t sample)
177 {
178  return (float) (sample / (float) (1L << MAD_F_FRACBITS));
179 }
180 
181 
182 wxString MP3ImportPlugin::GetPluginFormatDescription()
183 {
184  return DESC;
185 }
186 
187 std::unique_ptr<ImportFileHandle> MP3ImportPlugin::Open(const wxString &Filename)
188 {
189  auto file = std::make_unique<wxFile>(Filename);
190 
191  if (!file->IsOpened())
192  return nullptr;
193 
194  /* There's no way to tell if this is a valid mp3 file before actually
195  * decoding, so we return a valid FileHandle. */
196 
197  return std::make_unique<MP3ImportFileHandle>(std::move(file), Filename);
198 }
199 
200 wxString MP3ImportFileHandle::GetFileDescription()
201 {
202  return DESC;
203 }
204 
205 auto MP3ImportFileHandle::GetFileUncompressedBytes() -> ByteCount
206 {
207  // TODO
208  return 0;
209 }
210 
211 ProgressResult MP3ImportFileHandle::Import(TrackFactory *trackFactory, TrackHolders &outTracks,
212  Tags *tags)
213 {
214  outTracks.clear();
215 
216  CreateProgress();
217 
218  /* Prepare decoder data, initialize decoder */
219 
220  private_data privateData;
221  privateData.file = mFile.get();
222  privateData.inputBufferFill = 0;
223  privateData.progress = mProgress.get();
224  privateData.updateResult= ProgressResult::Success;
225  privateData.id3checked = false;
226  privateData.numChannels = 0;
227  privateData.trackFactory= trackFactory;
228  privateData.eof = false;
229 
230  mad_decoder_init(&mDecoder, &privateData, input_cb, 0, 0, output_cb, error_cb, 0);
231 
232  /* and send the decoder on its way! */
233 
234  bool res = (mad_decoder_run(&mDecoder, MAD_DECODER_MODE_SYNC) == 0) &&
235  (privateData.numChannels > 0) &&
236  !(privateData.updateResult == ProgressResult::Cancelled) &&
237  !(privateData.updateResult == ProgressResult::Failed);
238 
239  mad_decoder_finish(&mDecoder);
240 
241  if (!res) {
242  /* failure */
243  /* wxPrintf("failure\n"); */
244  return (privateData.updateResult);
245  }
246 
247  /* success */
248  /* wxPrintf("success\n"); */
249 
250  /* copy the WaveTrack pointers into the Track pointer list that
251  * we are expected to fill */
252  for(const auto &channel : privateData.channels) {
253  channel->Flush();
254  }
255  outTracks.swap(privateData.channels);
256 
257  /* Read in any metadata */
258  ImportID3(tags);
259 
260  return privateData.updateResult;
261 }
262 
263 MP3ImportFileHandle::~MP3ImportFileHandle()
264 {
265 }
266 
267 void MP3ImportFileHandle::ImportID3(Tags *tags)
268 {
269 #ifdef USE_LIBID3TAG
270  wxFile f; // will be closed when it goes out of scope
271  struct id3_file *fp = NULL;
272  auto cleanup = finally([&]{
273  if (fp)
274  id3_file_close(fp);
275  });
276 
277  if (f.Open(mFilename)) {
278  // Use id3_file_fdopen() instead of id3_file_open since wxWidgets can open a
279  // file with a Unicode name and id3_file_open() can't (under Windows).
280  fp = id3_file_fdopen(f.fd(), ID3_FILE_MODE_READONLY);
281  }
282 
283  if (!fp) {
284  return;
285  }
286 
287  // The file descriptor is now owned by "fp", so we must tell "f" to forget
288  // about it.
289  f.Detach();
290 
291  struct id3_tag *tp = id3_file_tag(fp);
292  if (!tp)
293  return;
294 
295  tags->Clear();
296 
297  // Loop through all frames
298  bool have_year = false;
299  for (int i = 0; i < (int) tp->nframes; i++) {
300  struct id3_frame *frame = tp->frames[i];
301 
302  // wxPrintf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
303  // wxPrintf("Desc: %s\n", frame->description);
304  // wxPrintf("Num fields: %d\n", frame->nfields);
305 
306  // for (int j = 0; j < (int) frame->nfields; j++) {
307  // wxPrintf("field %d type %d\n", j, frame->fields[j].type );
308  // if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
309  // wxPrintf("num strings %d\n", frame->fields[j].stringlist.nstrings);
310  // }
311  // }
312 
313  wxString n, v;
314 
315  // Determine the tag name
316  if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
317  n = TAG_TITLE;
318  }
319  else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
320  n = TAG_ARTIST;
321  }
322  else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
323  n = TAG_ALBUM;
324  }
325  else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
326  n = TAG_TRACK;
327  }
328  else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
329  // LLL: When libid3tag encounters the "TYER" tag, it converts it to a
330  // "ZOBS" (obsolete) tag and adds a "TDRC" tag at the end of the
331  // list of tags using the first 4 characters of the "TYER" tag.
332  // Since we write both the "TDRC" and "TYER" tags, the "TDRC" tag
333  // will always be encountered first in the list. We want use it
334  // since the converted "TYER" tag may have been truncated.
335  if (have_year) {
336  continue;
337  }
338  n = TAG_YEAR;
339  have_year = true;
340  }
341  else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
342  n = TAG_COMMENTS;
343  }
344  else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
345  n = TAG_GENRE;
346  }
347  else {
348  // Use frame description as default tag name. The descriptions
349  // may include several "meanings" separated by "/" characters, so
350  // we just use the first meaning
351  n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
352  }
353 
354  const id3_ucs4_t *ustr = NULL;
355 
356  if (n == TAG_COMMENTS) {
357  ustr = id3_field_getfullstring(&frame->fields[3]);
358  }
359  else if (frame->nfields == 3) {
360  ustr = id3_field_getstring(&frame->fields[1]);
361  if (ustr) {
362  // Is this duplication really needed?
363  MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
364  n = UTF8CTOWX(str.get());
365  }
366 
367  ustr = id3_field_getstring(&frame->fields[2]);
368  }
369  else if (frame->nfields >= 2) {
370  ustr = id3_field_getstrings(&frame->fields[1], 0);
371  }
372 
373  if (ustr) {
374  // Is this duplication really needed?
375  MallocString<> str{ (char *)id3_ucs4_utf8duplicate(ustr) };
376  v = UTF8CTOWX(str.get());
377  }
378 
379  if (!n.IsEmpty() && !v.IsEmpty()) {
380  tags->SetTag(n, v);
381  }
382  }
383 
384  // Convert v1 genre to name
385  if (tags->HasTag(TAG_GENRE)) {
386  long g = -1;
387  if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
388  tags->SetTag(TAG_GENRE, tags->GetGenre(g));
389  }
390  }
391 #endif // ifdef USE_LIBID3TAG
392 }
393 
394 //
395 // MAD Callbacks
396 //
397 
398 /* The input callback is called when the decoder wants more data. */
399 
400 enum mad_flow input_cb(void *_data, struct mad_stream *stream)
401 {
402  struct private_data *data = (struct private_data *)_data;
403 
404  data->updateResult = data->progress->Update((wxULongLong_t)data->file->Tell(),
405  (wxULongLong_t)data->file->Length() != 0 ?
406  (wxULongLong_t)data->file->Length() : 1);
407  if(data->updateResult != ProgressResult::Success)
408  return MAD_FLOW_STOP;
409 
410  if (data->eof) {
411  /* different from data->File->Eof(), this means the underlying
412  file has reached eof *and* we have subsequently supplied the
413  final padding zeros */
414  return MAD_FLOW_STOP;
415  }
416 
417 #ifdef USE_LIBID3TAG
418  if (!data->id3checked) {
419  data->file->Read(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
420  int len = id3_tag_query(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
421  if (len > 0) {
422  data->file->Seek(len, wxFromStart);
423  }
424  else {
425  data->file->Seek(0);
426  }
427 
428  data->id3checked = true;
429  }
430 #endif
431 
432  /* "Each time you refill your buffer, you need to preserve the data in
433  * your existing buffer from stream.next_frame to the end.
434  *
435  * This usually amounts to calling memmove() on this unconsumed portion
436  * of the buffer and appending NEW data after it, before calling
437  * mad_stream_buffer()"
438  * -- Rob Leslie, on the mad-dev mailing list */
439 
440  int unconsumedBytes;
441  if(stream->next_frame ) {
442  /* we must use inputBufferFill instead of INPUT_BUFFER_SIZE here
443  because the final buffer of the file may be only partially
444  filled, and we would otherwise be providing too much input
445  after eof */
446  unconsumedBytes = data->inputBuffer.get() + data->inputBufferFill
447  - stream->next_frame;
448  if (unconsumedBytes > 0)
449  memmove(data->inputBuffer.get(), stream->next_frame, unconsumedBytes);
450  }
451  else
452  unconsumedBytes = 0;
453 
454  if (data->file->Eof() &&
455  (unconsumedBytes + MAD_BUFFER_GUARD < INPUT_BUFFER_SIZE)) {
456 
457  /* supply the requisite MAD_BUFFER_GUARD zero bytes to ensure
458  the final frame gets decoded properly, then finish */
459 
460  memset(data->inputBuffer.get() + unconsumedBytes, 0, MAD_BUFFER_GUARD);
461  mad_stream_buffer
462  (stream, data->inputBuffer.get(), MAD_BUFFER_GUARD + unconsumedBytes);
463 
464  data->eof = true; /* so on next call, we will tell mad to stop */
465 
466  return MAD_FLOW_CONTINUE;
467  }
468 
469  off_t read = data->file->Read(data->inputBuffer.get() + unconsumedBytes,
470  INPUT_BUFFER_SIZE - unconsumedBytes);
471 
472  mad_stream_buffer(stream, data->inputBuffer.get(), read + unconsumedBytes);
473 
474  data->inputBufferFill = int(read + unconsumedBytes);
475 
476  return MAD_FLOW_CONTINUE;
477 }
478 
479 /* The output callback is called every time the decoder has finished decoding
480  * a frame, allowing us to use the decoded data */
481 
482 enum mad_flow output_cb(void *_data,
483  struct mad_header const * WXUNUSED(header),
484  struct mad_pcm *pcm)
485 {
486  // Don't C++ exceptions propagate through mad
487  return GuardedCall< mad_flow > ( [&] {
488  int samplerate;
489  struct private_data *data = (struct private_data *)_data;
490 
491  samplerate= pcm->samplerate;
492  auto channels = pcm->channels;
493  const auto samples = pcm->length;
494 
495  /* If this is the first run, we need to create the WaveTracks that
496  * will hold the data. We do this now because now is the first
497  * moment when we know how many channels there are. */
498 
499  if(data->channels.empty()) {
500  data->channels.resize(channels);
501 
503 
504  for(auto &channel: data->channels) {
505  channel = data->trackFactory->NewWaveTrack(format, samplerate);
506  channel->SetChannel(Track::MonoChannel);
507  }
508 
509  /* special case: 2 channels is understood to be stereo */
510  if(channels == 2) {
511  data->channels.begin()->get()->SetChannel(Track::LeftChannel);
512  data->channels.rbegin()->get()->SetChannel(Track::RightChannel);
513  data->channels.begin()->get()->SetLinked(true);
514  }
515  data->numChannels = channels;
516  }
517  else {
518  // This is not the first run, protect us from libmad glitching
519  // on the number of channels
520  channels = data->numChannels;
521  }
522 
523  /* TODO: get rid of this by adding fixed-point support to SampleFormat.
524  * For now, we allocate temporary float buffers to convert the fixed
525  * point samples into something we can feed to the WaveTrack. Allocating
526  * big blocks of data like this isn't a great idea, but it's temporary.
527  */
528  FloatBuffers channelBuffers{ channels, samples };
529  for(size_t smpl = 0; smpl < samples; smpl++)
530  for(int chn = 0; chn < channels; chn++)
531  channelBuffers[chn][smpl] = scale(pcm->samples[chn][smpl]);
532 
533  for(int chn = 0; chn < channels; chn++)
534  data->channels[chn]->Append((samplePtr)channelBuffers[chn].get(),
535  floatSample,
536  samples);
537 
538  return MAD_FLOW_CONTINUE;
539  }, MakeSimpleGuard(MAD_FLOW_BREAK) );
540 }
541 
542 enum mad_flow error_cb(void * WXUNUSED(_data), struct mad_stream * WXUNUSED(stream),
543  struct mad_frame * WXUNUSED(frame))
544 {
545 /* enum mad_flow {
546  MAD_FLOW_CONTINUE = 0x0000,
547  MAD_FLOW_STOP = 0x0010,
548  MAD_FLOW_BREAK = 0x0011,
549  MAD_FLOW_IGNORE = 0x0020
550  }; */
551  /*
552  wxPrintf("decoding error 0x%04x (%s)\n",
553  stream->error, mad_stream_errorstr(stream));
554  */
555 
556  return MAD_FLOW_CONTINUE;
557 
558  /* return MAD_FLOW_BREAK; */
559 }
560 
561 
562 #endif /* defined(USE_LIBMAD) */
void SetTag(const wxString &name, const wxString &value)
Definition: Tags.cpp:449
ProgressResult
#define TAG_TRACK
Definition: Tags.h:63
An ImportFileHandle for data.
Definition: ImportPlugin.h:119
ProgressDialog Class.
struct in the MPEG library, used for MP3 compression by MP3Exporter
#define UTF8CTOWX(X)
Definition: Internat.h:179
#define TAG_TITLE
Definition: Tags.h:60
#define TAG_ARTIST
Definition: Tags.h:61
wxString GetGenre(int value)
Definition: Tags.cpp:391
SimpleGuard< R > MakeSimpleGuard(R value)
struct in the MPEG library, used for MP3 compression by MP3Exporter
std::unique_ptr< Character[], freer > MallocString
Definition: MemoryX.h:417
Used to create a WaveTrack, or a LabelTrack.. Implementation of the functions of this class are dispe...
Definition: Track.h:862
int format
Definition: ExportPCM.cpp:56
struct in the MPEG library, used for MP3 compression by MP3Exporter
void Clear()
Definition: Tags.cpp:300
char * samplePtr
Definition: Types.h:203
The interface that all file import "plugins" (if you want to call them that) must implement...
struct in the MPEG library, used for MP3 compression by MP3Exporter
struct in the MPEG library, used for MP3 compression by MP3Exporter
ID3 Tags (for MP3)
Definition: Tags.h:70
wxString GetTag(const wxString &name) const
Definition: Tags.cpp:424
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Definition: ImportPlugin.h:73
void GetMP3ImportPlugin(ImportPluginList &importPluginList, UnusableImportPluginList &unusableImportPluginList)
Definition: ImportMP3.cpp:61
static const wxChar * exts[]
Definition: ImportMP3.cpp:52
An ImportPlugin for MP3 data.
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:86
#define TAG_COMMENTS
Definition: Tags.h:66
#define TAG_GENRE
Definition: Tags.h:65
An UnusableImportPlugin list.
An ImportPlugin list.
#define DESC
Definition: ImportMP3.cpp:50
static sampleFormat SampleFormatChoice()
std::vector< std::unique_ptr< WaveTrack >> TrackHolders
Definition: ImportRaw.h:24
#define TAG_ALBUM
Definition: Tags.h:62
An ImportFileHandle for MP3 data.
#define TAG_YEAR
Definition: Tags.h:64
bool HasTag(const wxString &name) const
Definition: Tags.cpp:415