Audacity  3.0.3
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 
30 
31 #include <wx/defs.h>
32 
33 #include "Import.h"
34 #include "BasicUI.h"
35 #include "ImportPlugin.h"
36 #include "Project.h"
37 
38 #define DESC XO("MP3 files")
39 
40 static const auto exts =
41 {
42  wxT("mp3"),
43  wxT("mp2"),
44  wxT("mpa")
45 };
46 
47 #ifndef USE_LIBMAD
48 
50 {
51  std::make_unique<UnusableImportPlugin>(DESC, FileExtensions(exts.begin(), exts.end()))
52 };
53 
54 #else
55 
56 #if defined(__WXMSW__)
57 #include <malloc.h>
58 #else
59 #include <stdlib.h>
60 #endif
61 
62 #include <wx/file.h>
63 #include <wx/string.h>
64 
65 #include "Prefs.h"
66 #include "../Tags.h"
67 #include "../WaveTrack.h"
68 #include "../widgets/AudacityMessageBox.h"
69 #include "../widgets/ProgressDialog.h"
70 
71 // PRL: include these last,
72 // and correct some preprocessor namespace pollution from wxWidgets that
73 // caused a warning about duplicate definition
74 #undef SIZEOF_LONG
75 extern "C"
76 {
77 #include "mad.h"
78 
79 #ifdef USE_LIBID3TAG
80 #include <id3tag.h>
81 #endif
82 }
83 
84 // Specifies the number of bytes in the input buffer. This also controls
85 // how many bytes will be scanned when searching for the first MP3 frame.
86 #define INPUT_BUFFER_SIZE 65535
87 
88 // This is the number of decoded samples libmad adds at the beginning
89 // (This is an "observed" value.)
90 #define MAD_DELAY 529
91 
92 class MP3ImportPlugin final : public ImportPlugin
93 {
94 public:
97 
98  wxString GetPluginStringID() override;
100  std::unique_ptr<ImportFileHandle> Open(const FilePath &Filename, AudacityProject*) override;
101 };
102 
103 using NewChannelGroup = std::vector< std::shared_ptr<WaveTrack> >;
104 
106 {
107 public:
108  MP3ImportFileHandle(const FilePath &filename);
110 
113  ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override;
114  wxInt32 GetStreamCount() override;
115  const TranslatableStrings &GetStreamInfo() override;
116  void SetStreamUsage(wxInt32 StreamID, bool Use) override;
117 
118 private:
119  bool Open();
120  void CheckTags();
121  void CheckAPETags(bool atEnd);
122  void CheckID3V1Tags();
123  void CheckID3V2Tags(bool atEnd);
124  void CheckLyrics();
125  bool CheckMP3();
126  bool FillBuffer();
127  void LoadID3(Tags *tags);
128 
129  // The MAD callbacks
130 
131  static mad_flow input_cb(void *that,
132  struct mad_stream *stream);
133  mad_flow InputCB(struct mad_stream *stream);
134 
135  static mad_flow filter_cb(void *that,
136  struct mad_stream const *stream,
137  struct mad_frame *frame);
138  mad_flow FilterCB(struct mad_stream const *stream, struct mad_frame *frame);
139 
140  static mad_flow output_cb(void *that,
141  struct mad_header const *header,
142  struct mad_pcm *pcm);
143  mad_flow OutputCB(struct mad_header const *header, struct mad_pcm *pcm);
144 
145  static mad_flow error_cb(void *that,
146  struct mad_stream *stream,
147  struct mad_frame *frame);
148  mad_flow ErrorCB(struct mad_stream *stream, struct mad_frame *frame);
149 
150 private:
152 
153  wxFile mFile;
154  wxFileOffset mFilePos;
155  wxFileOffset mFileLen;
156 
157  unsigned char mInputBuffer[INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD];
159 
162  unsigned mNumChannels;
163 
165 
166  int mDelay;
167  int mPadding;
168 
169  bool mHaveID3;
170 
172 };
173 
174 // ============================================================================
175 // MP3ImportPlugin
176 // ============================================================================
177 
179 : ImportPlugin(FileExtensions(exts.begin(), exts.end()))
180 {
181 }
182 
184 {
185 }
186 
188 {
189  return wxT("libmad");
190 }
191 
193 {
194  return DESC;
195 }
196 
197 std::unique_ptr<ImportFileHandle> MP3ImportPlugin::Open(
198  const FilePath &Filename, AudacityProject *)
199 {
200  auto handle = std::make_unique<MP3ImportFileHandle>(Filename);
201 
202  if (!handle->Open())
203  {
204  return nullptr;
205  }
206 
207  return handle;
208 }
209 
211 {
212  "MP3",
213  std::make_unique<MP3ImportPlugin>()
214 };
215 
216 // ============================================================================
217 // MP3ImportFileHandle
218 // ============================================================================
219 
221 : ImportFileHandle(filename)
222 {
223 }
224 
226 {
227 }
228 
230 {
231  return DESC;
232 }
233 
235 {
236  // TODO
237  return 0;
238 }
239 
241 {
242  return 1;
243 }
244 
246 {
247  static TranslatableStrings empty;
248  return empty;
249 }
250 
251 void MP3ImportFileHandle::SetStreamUsage(wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use))
252 {
253 }
254 
256  TrackHolders &outTracks,
257  Tags *tags)
258 {
259  outTracks.clear();
260 
261  CreateProgress();
262 
263  mTrackFactory = trackFactory;
265  mNumChannels = 0;
266 
267  // Set delay and padding to best possible in case the LAME tag is not present
268  mDelay = MAD_DELAY;
269  mPadding = 0;
270 
271  // Initialize decoder
272  mad_decoder_init(&mDecoder, this, input_cb, 0, filter_cb, output_cb, error_cb, 0);
273 
274  // Send the decoder on its way!
275  auto res = mad_decoder_run(&mDecoder, MAD_DECODER_MODE_SYNC);
276 
277  // Terminate decoder
278  mad_decoder_finish(&mDecoder);
279 
280  // Decoding failed, so pass it on
281  if (res != 0)
282  {
283  return ProgressResult::Failed;
284  }
285 
286  // The user canceled the decoding, so bail without saving tracks or tags
288  {
289  return mUpdateResult;
290  }
291 
292  // Flush and trim the channels
293  for (const auto &channel : mChannels)
294  {
295  channel->Flush();
296 
297  // Trim any padding
298  if (mPadding)
299  {
300  double et = channel->GetEndTime();
301  double t1 = et - channel->LongSamplesToTime(mPadding);
302  channel->Clear(t1, et);
303  }
304 
305  // And delay
306  if (mDelay)
307  {
308  double st = channel->GetStartTime();
309  double t0 = st + channel->LongSamplesToTime(mDelay);
310  channel->Clear(st, t0);
311  }
312  }
313 
314  // Copy the WaveTrack pointers into the Track pointer list that
315  // we are expected to fill
316  outTracks.push_back(std::move(mChannels));
317 
318  // Load ID3 tags from the file
319  LoadID3(tags);
320 
321  return mUpdateResult;
322 }
323 
325 {
326  mInputBufferLen = 0;
327  mFilePos = 0;
328  mHaveID3 = false;
329 
330  // Open the file
331  if (!mFile.Open(mFilename))
332  {
333  return false;
334  }
335 
336  // Get the length of the file
337  mFileLen = mFile.Seek(0, wxFromEnd);
338  if (mFileLen == wxInvalidOffset || mFile.Error())
339  {
340  mFile.Close();
341  return false;
342  }
343 
344  if (mFile.Seek(0, wxFromStart) == wxInvalidOffset || mFile.Error())
345  {
346  mFile.Close();
347  return false;
348  }
349 
350  // Check for ID3 tags
351  CheckTags();
352 
353  // Scan for the first MP3 frame
354  if (!CheckMP3())
355  {
356  mFile.Close();
357  return false;
358  }
359 
360  return true;
361 }
362 
364 {
365  // We do this twice to allow them to be in any order
366  for (int i = 0; i < 2; ++i)
367  {
368  CheckAPETags(false);
369  CheckID3V2Tags(false);
370  }
371 
372  // We do this twice to allow them to be in any order. Even though ID3v1 is
373  // supposed to at the end, some apps put the v2 tags after the v1 tags.
374  for (int i = 0; i < 2; ++i)
375  {
376  CheckAPETags(true);
377  CheckID3V1Tags();
378  CheckLyrics();
379  CheckID3V2Tags(true);
380  }
381 
382  return;
383 }
384 
386 {
387  int offset = atEnd ? mFileLen - 32 : mFilePos;
388 
389  // Ensure file is positioned to start of (possible) tags
390  if (mFile.Seek(offset, wxFromStart) == wxInvalidOffset || mFile.Error())
391  {
392  return;
393  }
394 
395  // An APE tag header is 32 bytes
396  if (mFile.Read(mInputBuffer, 32) != 32 || mFile.Error())
397  {
398  return;
399  }
400 
401  // Do we have an APE preamble?
402  if (memcmp(mInputBuffer, "APETAGEX", 8) != 0)
403  {
404  return;
405  }
406 
407  // Get the (little endian) length
408  wxFileOffset len = (mInputBuffer[12] & 0xff) |
409  ((mInputBuffer[13] & 0xff) << 8) |
410  ((mInputBuffer[14] & 0xff) << 16) |
411  ((mInputBuffer[15] & 0xff) << 24);
412 
413  // Get needed flags
414  bool hasHeader = mInputBuffer[23] & 0x80;
415 
416  // Skip the tags
417  if (!atEnd)
418  {
419  mFilePos += (32 + len);
420  }
421  else
422  {
423  mFileLen -= ((hasHeader ? 32 : 0) + len);
424  }
425 }
426 
428 {
429  // Ensure file is positioned to start of (possible) tags
430  if (mFile.Seek(mFileLen - 128, wxFromStart) == wxInvalidOffset || mFile.Error())
431  {
432  return;
433  }
434 
435  // An ID3v1 tag header is 3 bytes
436  if (mFile.Read(mInputBuffer, 3) != 3 || mFile.Error())
437  {
438  return;
439  }
440 
441  // Do we have ID3v1 tags?
442  if (memcmp(mInputBuffer, "TAG", 3) != 0)
443  {
444  return;
445  }
446 
447  // Adjust file length
448  mFileLen -= 128;
449 
450  // Remember that we have tags
451  mHaveID3 = true;
452 }
453 
455 {
456  int offset = mFileLen - 9;
457 
458  // Ensure file is positioned to start of (possible) lyrics
459  if (mFile.Seek(offset, wxFromStart) == wxInvalidOffset || mFile.Error())
460  {
461  return;
462  }
463 
464  // An Lyrics3 footeris 9 bytes
465  if (mFile.Read(mInputBuffer, 9) != 9 || mFile.Error())
466  {
467  return;
468  }
469 
470  // Found a v1 Lyrics footer?
471  if (memcmp(mInputBuffer, "LYRICSEND", 9) == 0)
472  {
473  wxFileOffset pos = wxMax(offset - 5100, 0);
474  size_t len = offset - pos;
475 
476  // Ensure file is positioned to start of (possible) lyrics
477  if (mFile.Seek(pos, wxFromStart) == wxInvalidOffset || mFile.Error())
478  {
479  return;
480  }
481 
482  // Read the lyrics
483  if (mFile.Read(mInputBuffer, len) != len || mFile.Error())
484  {
485  return;
486  }
487 
488  // Search forward to find the beginning of the lyrics
489  for (size_t i = 0; i < len; ++i)
490  {
491  if (memcmp(&mInputBuffer[i], "LYRICSBEGIN", 11) == 0)
492  {
493  // Adjust the file length to exclude the lyrics
494  mFileLen = pos + i;
495  break;
496  }
497  }
498  }
499  // Found a v2 Lyrics footer?
500  else if (memcmp(mInputBuffer, "LYRICS200", 9) == 0)
501  {
502  // Ensure file is positioned to start of (possible) lyrics
503  if (mFile.Seek(-15, wxFromCurrent) == wxInvalidOffset || mFile.Error())
504  {
505  return;
506  }
507 
508  // An Lyrics3v2 length is 6 bytes
509  if (mFile.Read(mInputBuffer, 6) != 6 || mFile.Error())
510  {
511  return;
512  }
513 
514  // Adjust the file length to exclude the lyrics
515  mInputBuffer[6] = 0;
516  mFileLen -= (wxAtoi((char *) mInputBuffer) + 15);
517  }
518 }
519 
521 {
522  int offset = atEnd ? mFileLen - 10 : mFilePos;
523 
524  // Ensure file is positioned to start of (possible) tags
525  if (mFile.Seek(offset, wxFromStart) == wxInvalidOffset || mFile.Error())
526  {
527  return;
528  }
529 
530  // An ID3v2 tag header is 10 bytes
531  if (mFile.Read(mInputBuffer, 10) != 10 || mFile.Error())
532  {
533  return;
534  }
535 
536  // Do we have an ID3v2 header or footer?
537  if (memcmp(mInputBuffer, atEnd ? "3DI" : "ID3", 3) != 0)
538  {
539  return;
540  }
541 
542  // Get and decode the length
543  wxFileOffset len = (mInputBuffer[6] & 0x7f);
544  len = (len << 7) | (mInputBuffer[7] & 0x7f);
545  len = (len << 7) | (mInputBuffer[8] & 0x7f);
546  len = (len << 7) | (mInputBuffer[9] & 0x7f);
547 
548  // Skip the tags
549  if (!atEnd)
550  {
551  mFilePos += (10 + len);
552  }
553  else
554  {
555  mFileLen -= (10 + len + 10);
556  }
557 
558  // Remember that we have tags
559  mHaveID3 = true;
560 }
561 
563 {
564  wxFileOffset savedPos = mFilePos;
565 
566  // Ensure file is positioned to start of 1st mp3 frame
567  if (mFile.Seek(mFilePos, wxFromStart) == wxInvalidOffset || mFile.Error())
568  {
569  return false;
570  }
571 
572  // Load as much as will fit into the buffer
573  if (!FillBuffer())
574  {
575  return false;
576  }
577 
578  // Initialize mad stream
579  mad_stream stream;
580  mad_stream_init(&stream);
581  mad_stream_buffer(&stream, mInputBuffer, mInputBufferLen);
582 
583  // And header
584  mad_header header;
585  mad_header_init(&header);
586 
587  // Scan the input buffer for 2 consecutive MP3 frames. When the header
588  // decoder finds a frame, it decodes it and ensures it is followed by
589  // another frame or EOF...thus 2 (or 1) consecutive frame(s) are detected.
590  int consecutive = 1;
591  while (consecutive > 0)
592  {
593  // Decode the header at the current stream position.
594  if (mad_header_decode(&header, &stream))
595  {
596  // End of buffer.
597  if (stream.error != MAD_ERROR_NONE)
598  {
599  break;
600  }
601  }
602 
603  consecutive -= 1;
604  }
605 
606  // Remember how many bytes were processed
607  int used = stream.this_frame - stream.buffer;
608 
609  // Cleanup
610  mad_header_finish(&header);
611  mad_stream_finish(&stream);
612 
613  // Did we find all that we wanted?
614  if (consecutive)
615  {
616  return false;
617  }
618 
619  // Reset file controls
620  mInputBufferLen = 0;
621 
622  // Reposition file to start of mp3 frames to prepare for the Import.
623  mFilePos = savedPos + used;
624  if (mFile.Seek(mFilePos, wxFromStart) == wxInvalidOffset || mFile.Error())
625  {
626  return false;
627  }
628 
629  // Looks like an MP3...
630  return true;
631 }
632 
634 {
635  // We either want enough to fill the input buffer or what's left in the file
636  auto want = wxMin(INPUT_BUFFER_SIZE - mInputBufferLen, mFileLen - mFilePos);
637  if (want > 0)
638  {
639  // We should always get what we ask for
640  auto got = mFile.Read(&mInputBuffer[mInputBufferLen], want);
641  if (got != want || mFile.Error())
642  {
643  return false;
644  }
645 
646  // Adjust input control
647  mInputBufferLen += got;
648  mFilePos += got;
649  }
650 
651  // MAD requires that we add MAD_BUFFER_GUARD extra bytes when we've processed
652  // all of the MP3 frames. Otherwise, we will drop the last frame.
653  if (mFilePos == mFileLen)
654  {
655  memset(&mInputBuffer[mInputBufferLen], 0, MAD_BUFFER_GUARD);
656  mInputBufferLen += MAD_BUFFER_GUARD;
657  }
658 
659  return true;
660 }
661 
663 {
664 #ifdef USE_LIBID3TAG
665  struct id3_file *id3file = NULL;
666  auto cleanup = finally([&]
667  {
668  if (id3file)
669  {
670  id3_file_close(id3file);
671  }
672  });
673 
674  // Use id3_file_fdopen() instead of id3_file_open since wxWidgets can open a
675  // file with a Unicode name and id3_file_open() can't (under Windows).
676  id3file = id3_file_fdopen(mFile.fd(), ID3_FILE_MODE_READONLY);
677  if (!id3file)
678  {
679  return;
680  }
681 
682  // The file descriptor is now owned by "id3file", so we must tell "mFile" to forget
683  // about it.
684  mFile.Detach();
685 
686  // Load the tags
687  struct id3_tag *id3tags = id3_file_tag(id3file);
688  if (!id3tags || id3tags->nframes == 0)
689  {
690  return;
691  }
692 
693  // Convert from libid3tag's ucs4 type to wxString.
694  //
695  // The ucs4 type is unsigned long which can be 8 bytes instead
696  // of the expected 4 bytes for a UTF-32 character, so we have
697  // to convert to unsigned int and then to wxString.
698  wxMBConvUTF32 converter;
699  auto toString = [=](const id3_ucs4_t *in)
700  {
701  // Count the number of characters
702  size_t len = 0;
703  for (const id3_ucs4_t *p = in; *p; p++)
704  {
705  len++;
706  }
707 
708  // Would like to use std::dynarray or runtime-sized array,
709  // but VS doesn't support either.
710  wxUint32 *buf = (wxUint32 *) alloca((len + 1) * sizeof(wxUint32));
711 
712  // Copy and convert to unsigned int
713  wxUint32 *out;
714  for (out = buf; *in; in++, out++)
715  {
716  *out = (wxUint32) (*in);
717  }
718  *out = 0;
719 
720  // Finally convert to and return wxString
721  return wxString((char *) buf, converter);
722  };
723 
724  tags->Clear();
725 
726  // Extract tags from ID3 frames and add to our tags
727  bool have_year = false;
728  for (unsigned int i = 0; i < id3tags->nframes; ++i)
729  {
730  struct id3_frame *frame = id3tags->frames[i];
731 
732 #if 0
733  wxLogDebug("ID: %08x '%4s'", (int) *(int *)frame->id, frame->id);
734  wxLogDebug("Desc: %s", frame->description);
735  wxLogDebug("Num fields: %d", frame->nfields);
736 
737  for (unsigned int j = 0; j < frame->nfields; ++j)
738  {
739  wxLogDebug("field %d type %d", j, frame->fields[j].type);
740  if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST)
741  {
742  wxLogDebug("num strings %d", frame->fields[j].stringlist.nstrings);
743  }
744  }
745 #endif
746 
747  wxString n;
748  wxString v;
749 
750  // Determine the tag name
751  if (strcmp(frame->id, ID3_FRAME_TITLE) == 0)
752  {
753  n = TAG_TITLE;
754  }
755  else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0)
756  {
757  n = TAG_ARTIST;
758  }
759  else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0)
760  {
761  n = TAG_ALBUM;
762  }
763  else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0)
764  {
765  n = TAG_TRACK;
766  }
767  else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0)
768  {
769  // LLL: When libid3tag encounters the "TYER" tag, it converts it to a
770  // "ZOBS" (obsolete) tag and adds a "TDRC" tag at the end of the
771  // list of tags using the first 4 characters of the "TYER" tag.
772  // Since we write both the "TDRC" and "TYER" tags, the "TDRC" tag
773  // will always be encountered first in the list. We want to use
774  // it since the converted "TYER" tag may have been truncated.
775  if (have_year)
776  {
777  continue;
778  }
779  n = TAG_YEAR;
780  have_year = true;
781  }
782  else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0)
783  {
784  n = TAG_COMMENTS;
785  }
786  else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0)
787  {
788  n = TAG_GENRE;
789  }
790  else
791  {
792  // Use frame description as default tag name. The descriptions
793  // may include several "meanings" separated by "/" characters, so
794  // we just use the first meaning
795  n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
796  }
797 
798  // Now get the tag value
799  const id3_ucs4_t *ustr = NULL;
800 
801  if (n == TAG_COMMENTS)
802  {
803  ustr = id3_field_getfullstring(&frame->fields[3]);
804  }
805  else if (frame->nfields == 3)
806  {
807  ustr = id3_field_getstring(&frame->fields[1]);
808  if (ustr)
809  {
810  n = toString(ustr);
811  }
812 
813  ustr = id3_field_getstring(&frame->fields[2]);
814  }
815  else if (frame->nfields >= 2)
816  {
817  ustr = id3_field_getstrings(&frame->fields[1], 0);
818  }
819 
820  // Convert the value
821  if (ustr)
822  {
823  v = toString(ustr);
824  }
825 
826  // And add it to the list of tags
827  if (!n.empty() && !v.empty())
828  {
829  tags->SetTag(n, v);
830  }
831  }
832 
833  // Convert v1 genre to name
834  if (tags->HasTag(TAG_GENRE))
835  {
836  long g = -1;
837  if (tags->GetTag(TAG_GENRE).ToLong(&g))
838  {
839  tags->SetTag(TAG_GENRE, tags->GetGenre(g));
840  }
841  }
842 #else
843  (void) tags;
844 #endif
845 }
846 
847 //
848 // MAD Callbacks
849 //
850 
851 // The input callback is called when the decoder wants more data
852 mad_flow MP3ImportFileHandle::input_cb(void *that,
853  struct mad_stream *stream)
854 {
855  auto cb = [&]()
856  {
857  return ((MP3ImportFileHandle *) that)->InputCB(stream);
858  };
859 
860  return GuardedCall<mad_flow>(cb, MakeSimpleGuard(MAD_FLOW_BREAK));
861 }
862 
863 mad_flow MP3ImportFileHandle::InputCB(struct mad_stream *stream)
864 {
865  // Update the progress
866  mUpdateResult = mProgress->Update((wxLongLong_t) mFilePos, (wxLongLong_t) mFileLen);
868  {
869  return MAD_FLOW_STOP;
870  }
871 
872  // Stop if we've consumed all of the MP3 data
873  if (mFilePos == mFileLen)
874  {
875  return MAD_FLOW_STOP;
876  }
877 
878  // "Each time you refill your buffer, you need to preserve the data in
879  // your existing buffer from stream.next_frame to the end.
880  //
881  // This usually amounts to calling memmove() on this unconsumed portion
882  // of the buffer and appending NEW data after it, before calling
883  // mad_stream_buffer()
884  // -- Rob Leslie, on the mad-dev mailing list
885  if (stream->next_frame)
886  {
887  mInputBufferLen -= (stream->next_frame - mInputBuffer);
888  memmove(mInputBuffer, stream->next_frame, mInputBufferLen);
889  }
890 
891  // Refill the buffer
892  if (!FillBuffer())
893  {
894  return MAD_FLOW_BREAK;
895  }
896 
897  // And give it back to MAD
898  mad_stream_buffer(stream, mInputBuffer, mInputBufferLen);
899 
900  return MAD_FLOW_CONTINUE;
901 }
902 
903 // The filter callback lets us examine each frame and decide if it should be
904 // kept or tossed. We use this to detect the Xing or LAME tags.
905 mad_flow MP3ImportFileHandle::filter_cb(void *that,
906  struct mad_stream const *stream,
907  struct mad_frame *frame)
908 {
909  auto cb = [&]()
910  {
911  return ((MP3ImportFileHandle *) that)->FilterCB(stream, frame);
912  };
913 
914  return GuardedCall<mad_flow>(cb, MakeSimpleGuard(MAD_FLOW_BREAK));
915 }
916 
917 mad_flow MP3ImportFileHandle::FilterCB(struct mad_stream const *stream,
918  struct mad_frame *frame)
919 {
920  // We only want to jinspect the first frame, so disable future calls
921  mDecoder.filter_func = nullptr;
922 
923  // Is it a VBRI info frame?
924  if (memcmp(&stream->this_frame[4 + 32], "VBRI", 4) == 0)
925  {
926  mDelay = (stream->this_frame[4 + 32 + 6] & 0xff) << 8 |
927  (stream->this_frame[4 + 32 + 7] & 0xff);
928 
929  return MAD_FLOW_CONTINUE;
930  }
931 
932  // Look for Xing/Info information
933 
934  // Get the ancillary data ptr and length. If the frame has CRC protection, we make
935  // a small adjustment to get around an apparent bug in libmad.
936  auto ptr = stream->anc_ptr.byte - (frame->header.flags & MAD_FLAG_PROTECTION ? 2 : 0);
937  int len = stream->anc_bitlen / 8;
938 
939  // Ensure it's something we can understand
940  if (len < 4 || (memcmp(ptr, "Xing", 4) != 0 && memcmp(ptr, "Info", 4) != 0))
941  {
942  return MAD_FLOW_CONTINUE;
943  }
944 
945  // Skip the tag
946  ptr += 4;
947  len -= 4;
948 
949  enum flagBits
950  {
951  hasFrames = 0x0001,
952  hasBytes = 0x0002,
953  hasToc = 0x0004,
954  hasScale = 0x0008
955  };
956 
957  // Extract the flags
958  unsigned int flags = (((((ptr[0] << 8) + ptr[1]) << 8) + ptr[2]) << 8) + ptr[3];
959  ptr += 4;
960  len -= 4;
961 
962  // Skip the number of frames
963  if (len >= 4 && flags & hasFrames)
964  {
965  ptr += 4;
966  len -= 4;
967  }
968 
969  // Skip the number of bytes
970  if (len >= 4 && flags & hasBytes)
971  {
972  ptr += 4;
973  len -= 4;
974  }
975 
976  // Skip the TOC
977  if (len >= 100 && flags & hasToc)
978  {
979  ptr += 100;
980  len -= 100;
981  }
982 
983  // Skip the VBR Scale
984  if (len >= 4 && flags & hasScale)
985  {
986  ptr += 4;
987  len -= 4;
988  }
989 
990  // Bail if LAME wasn't the encoder or we don't have enough ancillary data left
991  if (len < 24 || memcmp(ptr, "LAME", 4) != 0)
992  {
993  return MAD_FLOW_IGNORE;
994  }
995 
996  // Skip down to the delay and padding
997  ptr += 21;
998  len -= 21;
999 
1000  // Extract the delay and padding and adjust for decoder delay
1001  mDelay = (ptr[0] << 4) + (ptr[1] >> 4) + MAD_DELAY;
1002  mPadding = ((ptr[1] & 0x0f) << 8) + ptr[2] - MAD_DELAY;
1003  if (mPadding < 0)
1004  {
1005  mPadding = 0;
1006  }
1007 
1008  return MAD_FLOW_IGNORE;
1009 }
1010 
1011 // The output callback is called every time the decoder has finished decoding
1012  // a frame, allowing us to use the decoded data
1014  struct mad_header const *header,
1015  struct mad_pcm *pcm)
1016 {
1017  auto cb = [&]()
1018  {
1019  return ((MP3ImportFileHandle *) that)->OutputCB(header, pcm);
1020  };
1021 
1022  return GuardedCall<mad_flow>(cb, MakeSimpleGuard(MAD_FLOW_BREAK));
1023 }
1024 
1025 enum mad_flow MP3ImportFileHandle::OutputCB(struct mad_header const * WXUNUSED(header),
1026  struct mad_pcm *pcm)
1027 {
1028  // If this is the first run, we need to create the WaveTracks that
1029  // will hold the data. We do this now because now is the first
1030  // moment when we know how many channels there are.
1031  if (mChannels.empty())
1032  {
1033  mNumChannels = pcm->channels;
1034 
1035  mChannels.resize(mNumChannels);
1036 
1037  for (auto &channel: mChannels)
1038  {
1039  // Mad library header explains the 32 bit fixed point format with
1040  // 28 fractional bits. Effective sample format must therefore be
1041  // more than 24, and this is our only choice now.
1042  channel = NewWaveTrack(*mTrackFactory, floatSample, pcm->samplerate);
1043  }
1044  }
1045 
1046  // Get the number of samples in each channel
1047  auto samples = pcm->length;
1048 
1049  // Convert libmad samples to float and append to WaveTracks
1050  for (int chn = 0; chn < mNumChannels; ++chn)
1051  {
1052  // Number of samples will never be more than 1152
1053  float sampleBuf[1152];
1054  wxASSERT(samples <= 1152);
1055 
1056  // Copy over the samples
1057  for (int sample = 0; sample < samples; ++sample)
1058  {
1059  // Convert libmad's fixed point representation to float
1060  sampleBuf[sample] = ((float) pcm->samples[chn][sample] / (1L << MAD_F_FRACBITS));
1061  }
1062 
1063  // And append to the channel
1064  mChannels[chn]->Append((samplePtr) sampleBuf, floatSample, samples);
1065  }
1066 
1067  return MAD_FLOW_CONTINUE;
1068 }
1069 
1070 // The error callback is used when MAD encounters an error and needs to know
1071 // how it should proceed
1072 mad_flow MP3ImportFileHandle::error_cb(void *that,
1073  struct mad_stream *stream,
1074  struct mad_frame *frame)
1075 {
1076  auto cb = [&]()
1077  {
1078  return ((MP3ImportFileHandle *) that)->ErrorCB(stream, frame);
1079  };
1080 
1081  return GuardedCall<mad_flow>(cb, MakeSimpleGuard(MAD_FLOW_BREAK));
1082 }
1083 
1084 enum mad_flow MP3ImportFileHandle::ErrorCB(struct mad_stream *stream,
1085  struct mad_frame *frame)
1086 {
1087  // You always get a LOSTSYNC error at EOF, so just ignore it
1088  if (stream->error == MAD_ERROR_LOSTSYNC && mFilePos == mFileLen)
1089  {
1090  return MAD_FLOW_CONTINUE;
1091  }
1092 
1093  // This can happen when parsing the first frame. We can use the number of channels
1094  // to test for this since it hasn't been determined yet.
1095  if (stream->error == MAD_ERROR_BADDATAPTR && mNumChannels == 0)
1096  {
1097  return MAD_FLOW_CONTINUE;
1098  }
1099 
1100  // Let the user know about the error
1101  using namespace BasicUI;
1102  ShowErrorDialog( {},
1103  DefaultCaption(),
1104  XO("Import failed\n\nThis is likely caused by a malformed MP3.\n\n"),
1105  "Opening_malformed_MP3_files");
1106  return MAD_FLOW_BREAK;
1107 }
1108 
1109 #endif
MP3ImportPlugin::~MP3ImportPlugin
~MP3ImportPlugin()
Definition: ImportMP3.cpp:183
MP3ImportFileHandle::SetStreamUsage
void SetStreamUsage(wxInt32 StreamID, bool Use) override
Definition: ImportMP3.cpp:251
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
MP3ImportPlugin::GetPluginStringID
wxString GetPluginStringID() override
Definition: ImportMP3.cpp:187
MP3ImportPlugin::GetPluginFormatDescription
TranslatableString GetPluginFormatDescription() override
Definition: ImportMP3.cpp:192
MP3ImportPlugin
An ImportPlugin for MP3 data.
Definition: ImportMP3.cpp:93
TrackHolders
std::vector< std::vector< std::shared_ptr< WaveTrack > > > TrackHolders
Definition: Import.h:39
BasicUI::ProgressResult::Success
@ Success
MP3ImportFileHandle::mTrackFactory
WaveTrackFactory * mTrackFactory
Definition: ImportMP3.cpp:160
MP3ImportFileHandle::mDelay
int mDelay
Definition: ImportMP3.cpp:166
MP3ImportFileHandle
An ImportFileHandle for MP3 data.
Definition: ImportMP3.cpp:106
MP3ImportFileHandle::mInputBuffer
unsigned char mInputBuffer[INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD]
Definition: ImportMP3.cpp:157
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
ImportPlugin
Base class for FlacImportPlugin, LOFImportPlugin, MP3ImportPlugin, OggImportPlugin and PCMImportPlugi...
Definition: ImportPlugin.h:67
BasicUI::ShowErrorDialog
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:233
Project.h
Import.h
MP3ImportFileHandle::mChannels
NewChannelGroup mChannels
Definition: ImportMP3.cpp:161
Tags::HasTag
bool HasTag(const wxString &name) const
Definition: Tags.cpp:452
Tags
ID3 Tags (for MP3)
Definition: Tags.h:74
exts
static const auto exts
Definition: ImportMP3.cpp:40
TAG_TRACK
#define TAG_TRACK
Definition: Tags.h:63
MP3ImportFileHandle::Open
bool Open()
Definition: ImportMP3.cpp:324
BasicUI::ProgressResult
ProgressResult
Definition: BasicUI.h:145
mad_pcm
struct in the MPEG library, used for MP3 compression by MP3Exporter
MakeSimpleGuard
SimpleGuard< R > MakeSimpleGuard(R value)
Convert a value to a handler function returning that value, suitable for GuardedCall<R>
Definition: AudacityException.h:167
INPUT_BUFFER_SIZE
#define INPUT_BUFFER_SIZE
Definition: ImportMP3.cpp:86
MP3ImportFileHandle::CheckMP3
bool CheckMP3()
Definition: ImportMP3.cpp:562
RefreshCode::Cancelled
@ Cancelled
Definition: RefreshCode.h:23
XO
#define XO(s)
Definition: Internat.h:31
mad_stream
struct in the MPEG library, used for MP3 compression by MP3Exporter
MP3ImportFileHandle::CheckTags
void CheckTags()
Definition: ImportMP3.cpp:363
MP3ImportFileHandle::CheckLyrics
void CheckLyrics()
Definition: ImportMP3.cpp:454
MP3ImportFileHandle::mHaveID3
bool mHaveID3
Definition: ImportMP3.cpp:169
MP3ImportFileHandle::FillBuffer
bool FillBuffer()
Definition: ImportMP3.cpp:633
Tags::GetTag
wxString GetTag(const wxString &name) const
Definition: Tags.cpp:461
ImportFileHandle::mProgress
std::unique_ptr< ProgressDialog > mProgress
Definition: ImportPlugin.h:159
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
MP3ImportFileHandle::mFilePos
wxFileOffset mFilePos
Definition: ImportMP3.cpp:154
MP3ImportFileHandle::GetFileDescription
TranslatableString GetFileDescription() override
Definition: ImportMP3.cpp:229
floatSample
@ floatSample
Definition: SampleFormat.h:34
Tags::GetGenre
wxString GetGenre(int value)
Definition: Tags.cpp:428
ImportFileHandle::CreateProgress
void CreateProgress()
Definition: ImportPlugin.cpp:45
ImportFileHandle::NewWaveTrack
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.
Definition: ImportPlugin.cpp:69
FilePath
wxString FilePath
Definition: Project.h:20
Tags::SetTag
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:486
MP3ImportFileHandle::Import
ProgressResult Import(WaveTrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
Definition: ImportMP3.cpp:255
MP3ImportFileHandle::filter_cb
static mad_flow filter_cb(void *that, struct mad_stream const *stream, struct mad_frame *frame)
Definition: ImportMP3.cpp:905
MP3ImportFileHandle::CheckID3V1Tags
void CheckID3V1Tags()
Definition: ImportMP3.cpp:427
MP3ImportFileHandle::mInputBufferLen
int mInputBufferLen
Definition: ImportMP3.cpp:158
mad_header
struct in the MPEG library, used for MP3 compression by MP3Exporter
MP3ImportFileHandle::ErrorCB
mad_flow ErrorCB(struct mad_stream *stream, struct mad_frame *frame)
Definition: ImportMP3.cpp:1084
MP3ImportFileHandle::CheckAPETags
void CheckAPETags(bool atEnd)
Definition: ImportMP3.cpp:385
UTF8CTOWX
#define UTF8CTOWX(X)
Definition: Internat.h:159
MP3ImportPlugin::MP3ImportPlugin
MP3ImportPlugin()
Definition: ImportMP3.cpp:178
Tags::Clear
void Clear()
Definition: Tags.cpp:337
TAG_GENRE
#define TAG_GENRE
Definition: Tags.h:65
mad_frame
struct in the MPEG library, used for MP3 compression by MP3Exporter
MP3ImportFileHandle::MP3ImportPlugin
friend MP3ImportPlugin
Definition: ImportMP3.cpp:171
registered
static Importer::RegisteredImportPlugin registered
Definition: ImportMP3.cpp:211
ImportFileHandle::mFilename
FilePath mFilename
Definition: ImportPlugin.h:158
TAG_YEAR
#define TAG_YEAR
Definition: Tags.h:64
MP3ImportFileHandle::output_cb
static mad_flow output_cb(void *that, struct mad_header const *header, struct mad_pcm *pcm)
Definition: ImportMP3.cpp:1013
ImportFileHandle
An ImportFileHandle for data.
Definition: ImportPlugin.h:107
MP3ImportFileHandle::~MP3ImportFileHandle
~MP3ImportFileHandle()
Definition: ImportMP3.cpp:225
MP3ImportFileHandle::mFileLen
wxFileOffset mFileLen
Definition: ImportMP3.cpp:155
MP3ImportFileHandle::LoadID3
void LoadID3(Tags *tags)
Definition: ImportMP3.cpp:662
FileExtensions
wxArrayStringEx FileExtensions
Definition: Identifier.h:225
MP3ImportFileHandle::InputCB
mad_flow InputCB(struct mad_stream *stream)
Definition: ImportMP3.cpp:863
MP3ImportFileHandle::mPadding
int mPadding
Definition: ImportMP3.cpp:167
WaveTrackFactory
Used to create or clone a WaveTrack, with appropriate context from the project that will own the trac...
Definition: WaveTrack.h:713
MP3ImportFileHandle::GetFileUncompressedBytes
ByteCount GetFileUncompressedBytes() override
Definition: ImportMP3.cpp:234
MP3ImportFileHandle::CheckID3V2Tags
void CheckID3V2Tags(bool atEnd)
Definition: ImportMP3.cpp:520
BasicUI.h
Toolkit-neutral facade for basic user interface services.
MP3ImportFileHandle::GetStreamCount
wxInt32 GetStreamCount() override
Definition: ImportMP3.cpp:240
DESC
#define DESC
Definition: ImportMP3.cpp:38
samplePtr
char * samplePtr
Definition: SampleFormat.h:49
MP3ImportFileHandle::input_cb
static mad_flow input_cb(void *that, struct mad_stream *stream)
Definition: ImportMP3.cpp:852
MP3ImportFileHandle::mFile
wxFile mFile
Definition: ImportMP3.cpp:153
BasicUI
Definition: Export.h:39
MP3ImportFileHandle::mDecoder
mad_decoder mDecoder
Definition: ImportMP3.cpp:151
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
ImportPlugin.h
The interface that all file import "plugins" (if you want to call them that) must implement....
Importer::RegisteredImportPlugin
Definition: Import.h:85
mad_decoder
struct in the MPEG library, used for MP3 compression by MP3Exporter
MP3ImportPlugin::Open
std::unique_ptr< ImportFileHandle > Open(const FilePath &Filename, AudacityProject *) override
Definition: ImportMP3.cpp:197
MP3ImportFileHandle::OutputCB
mad_flow OutputCB(struct mad_header const *header, struct mad_pcm *pcm)
Definition: ImportMP3.cpp:1025
TAG_COMMENTS
#define TAG_COMMENTS
Definition: Tags.h:66
TAG_ARTIST
#define TAG_ARTIST
Definition: Tags.h:61
BasicUI::DefaultCaption
TranslatableString DefaultCaption()
"Message", suitably translated
Definition: BasicUI.cpp:70
MP3ImportFileHandle::MP3ImportFileHandle
MP3ImportFileHandle(const FilePath &filename)
Definition: ImportMP3.cpp:220
MP3ImportFileHandle::mUpdateResult
ProgressResult mUpdateResult
Definition: ImportMP3.cpp:164
Prefs.h
MP3ImportFileHandle::FilterCB
mad_flow FilterCB(struct mad_stream const *stream, struct mad_frame *frame)
Definition: ImportMP3.cpp:917
NewChannelGroup
std::vector< std::shared_ptr< WaveTrack > > NewChannelGroup
Definition: Import.cpp:62
ImportFileHandle::ByteCount
unsigned long long ByteCount
Definition: ImportPlugin.h:127
MP3ImportFileHandle::error_cb
static mad_flow error_cb(void *that, struct mad_stream *stream, struct mad_frame *frame)
Definition: ImportMP3.cpp:1072
MP3ImportFileHandle::mNumChannels
unsigned mNumChannels
Definition: ImportMP3.cpp:162
MAD_DELAY
#define MAD_DELAY
Definition: ImportMP3.cpp:90
TAG_TITLE
#define TAG_TITLE
Definition: Tags.h:60
MP3ImportFileHandle::GetStreamInfo
const TranslatableStrings & GetStreamInfo() override
Definition: ImportMP3.cpp:245
Importer::RegisteredUnusableImportPlugin
Definition: Import.h:94
TAG_ALBUM
#define TAG_ALBUM
Definition: Tags.h:62