annotate data/fileio/MP3FileReader.h @ 1305:9f9f55a8af92 mp3-gapless

Add gapless flag to MP3FileReader, and implement trimming the delay samples from the start (padding is not yet trimmed from end)
author Chris Cannam
date Tue, 29 Nov 2016 11:35:56 +0000
parents fa574c909c3d
children aa1b1fc2d018
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7 This file copyright 2006 Chris Cannam.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #ifndef _MP3_FILE_READER_H_
Chris@148 17 #define _MP3_FILE_READER_H_
Chris@148 18
Chris@148 19 #ifdef HAVE_MAD
Chris@148 20
Chris@148 21 #include "CodedAudioFileReader.h"
Chris@148 22
Chris@263 23 #include "base/Thread.h"
Chris@148 24 #include <mad.h>
Chris@148 25
Chris@157 26 #include <set>
Chris@157 27
Chris@392 28 class ProgressReporter;
Chris@148 29
Chris@148 30 class MP3FileReader : public CodedAudioFileReader
Chris@148 31 {
Chris@392 32 Q_OBJECT
Chris@392 33
Chris@148 34 public:
Chris@1305 35 /**
Chris@1305 36 * How the MP3FileReader should handle leading and trailing gaps.
Chris@1305 37 * See http://lame.sourceforge.net/tech-FAQ.txt for a technical
Chris@1305 38 * explanation of the numbers here.
Chris@1305 39 */
Chris@1305 40 enum GaplessMode {
Chris@1305 41 /**
Chris@1305 42 * Trim unwanted samples from the start and end of the decoded
Chris@1305 43 * audio. From the start, trim a number of samples equal to
Chris@1305 44 * the decoder delay (a fixed 529 samples) plus any encoder
Chris@1305 45 * delay that may be specified in Xing/LAME metadata. From the
Chris@1305 46 * end, trim any padding specified in Xing/LAME metadata, less
Chris@1305 47 * the fixed decoder delay. This usually results in "gapless"
Chris@1305 48 * audio, i.e. with no spurious zero padding at either end.
Chris@1305 49 */
Chris@1305 50 Gapless,
Chris@1305 51
Chris@1305 52 /**
Chris@1305 53 * Do not trim any samples. Also do not suppress any frames
Chris@1305 54 * from being passed to the mp3 decoder, even Xing/LAME
Chris@1305 55 * metadata frames. This will result in the audio being padded
Chris@1305 56 * with zeros at either end: at the start, typically
Chris@1305 57 * 529+576+1152 = 2257 samples for LAME-encoded mp3s; at the
Chris@1305 58 * end an unknown number depending on the fill ratio of the
Chris@1305 59 * final coded frame, but typically less than 1152-529 = 623.
Chris@1305 60 *
Chris@1305 61 * This mode produces the same output as produced by older
Chris@1305 62 * versions of this code before the gapless option was added,
Chris@1305 63 * and is present mostly for backward compatibility.
Chris@1305 64 */
Chris@1305 65 Gappy
Chris@1305 66 };
Chris@1305 67
Chris@317 68 MP3FileReader(FileSource source,
Chris@297 69 DecodeMode decodeMode,
Chris@297 70 CacheMode cacheMode,
Chris@1305 71 GaplessMode gaplessMode,
Chris@1040 72 sv_samplerate_t targetRate = 0,
Chris@920 73 bool normalised = false,
Chris@392 74 ProgressReporter *reporter = 0);
Chris@148 75 virtual ~MP3FileReader();
Chris@148 76
Chris@290 77 virtual QString getError() const { return m_error; }
Chris@290 78
Chris@345 79 virtual QString getLocation() const { return m_source.getLocation(); }
Chris@290 80 virtual QString getTitle() const { return m_title; }
Chris@334 81 virtual QString getMaker() const { return m_maker; }
Chris@632 82 virtual TagMap getTags() const { return m_tags; }
Chris@271 83
Chris@290 84 static void getSupportedExtensions(std::set<QString> &extensions);
Chris@316 85 static bool supportsExtension(QString ext);
Chris@316 86 static bool supportsContentType(QString type);
Chris@317 87 static bool supports(FileSource &source);
Chris@316 88
Chris@265 89 virtual int getDecodeCompletion() const { return m_completion; }
Chris@265 90
Chris@263 91 virtual bool isUpdating() const {
Chris@263 92 return m_decodeThread && m_decodeThread->isRunning();
Chris@263 93 }
Chris@263 94
Chris@392 95 public slots:
Chris@392 96 void cancelled();
Chris@392 97
Chris@148 98 protected:
Chris@317 99 FileSource m_source;
Chris@290 100 QString m_path;
Chris@290 101 QString m_error;
Chris@290 102 QString m_title;
Chris@333 103 QString m_maker;
Chris@632 104 TagMap m_tags;
Chris@1305 105 GaplessMode m_gaplessMode;
Chris@1038 106 sv_frame_t m_fileSize;
Chris@148 107 double m_bitrateNum;
Chris@929 108 int m_bitrateDenom;
Chris@1288 109 int m_mp3FrameCount;
Chris@265 110 int m_completion;
Chris@263 111 bool m_done;
Chris@263 112
Chris@1290 113 unsigned char *m_fileBuffer;
Chris@1290 114 size_t m_fileBufferSize;
Chris@1290 115
Chris@1290 116 float **m_sampleBuffer;
Chris@1290 117 size_t m_sampleBufferSize;
Chris@148 118
Chris@392 119 ProgressReporter *m_reporter;
Chris@148 120 bool m_cancelled;
Chris@148 121
Chris@1284 122 bool m_decodeErrorShown;
Chris@1284 123
Chris@1290 124 struct DecoderData {
Chris@148 125 unsigned char const *start;
Chris@1288 126 sv_frame_t length;
Chris@148 127 MP3FileReader *reader;
Chris@148 128 };
Chris@148 129
Chris@1038 130 bool decode(void *mm, sv_frame_t sz);
Chris@1288 131 enum mad_flow filter(struct mad_stream const *, struct mad_frame *);
Chris@148 132 enum mad_flow accept(struct mad_header const *, struct mad_pcm *);
Chris@148 133
Chris@1288 134 static enum mad_flow input_callback(void *, struct mad_stream *);
Chris@1288 135 static enum mad_flow output_callback(void *, struct mad_header const *,
Chris@1288 136 struct mad_pcm *);
Chris@1288 137 static enum mad_flow filter_callback(void *, struct mad_stream const *,
Chris@1288 138 struct mad_frame *);
Chris@1288 139 static enum mad_flow error_callback(void *, struct mad_stream *,
Chris@1288 140 struct mad_frame *);
Chris@263 141
Chris@263 142 class DecodeThread : public Thread
Chris@263 143 {
Chris@263 144 public:
Chris@263 145 DecodeThread(MP3FileReader *reader) : m_reader(reader) { }
Chris@263 146 virtual void run();
Chris@263 147
Chris@263 148 protected:
Chris@263 149 MP3FileReader *m_reader;
Chris@263 150 };
Chris@263 151
Chris@263 152 DecodeThread *m_decodeThread;
Chris@271 153
Chris@271 154 void loadTags();
Chris@333 155 QString loadTag(void *vtag, const char *name);
Chris@148 156 };
Chris@148 157
Chris@148 158 #endif
Chris@148 159
Chris@148 160 #endif