Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/soundsourceflac.cpp

Go to the documentation of this file.
00001 
00007 /***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include <cstring> // memcpy
00017 #include <QtDebug>
00018 #include <taglib/flacfile.h>
00019 
00020 #include "soundsourceflac.h"
00021 
00022 SoundSourceFLAC::SoundSourceFLAC(QString filename)
00023     : Mixxx::SoundSource(filename)
00024     , m_file(filename)
00025     , m_decoder(NULL)
00026     , m_samples(0)
00027     , m_bps(0)
00028     , m_minBlocksize(0)
00029     , m_maxBlocksize(0)
00030     , m_minFramesize(0)
00031     , m_maxFramesize(0)
00032     , m_flacBuffer(NULL)
00033     , m_flacBufferLength(0)
00034     , m_leftoverBuffer(NULL)
00035     , m_leftoverBufferLength(0) {
00036 }
00037 
00038 SoundSourceFLAC::~SoundSourceFLAC() {
00039     if (m_flacBuffer != NULL) {
00040         delete [] m_flacBuffer;
00041         m_flacBuffer = NULL;
00042     }
00043     if (m_leftoverBuffer != NULL) {
00044         delete [] m_leftoverBuffer;
00045         m_leftoverBuffer = NULL;
00046     }
00047     if (m_decoder) {
00048         FLAC__stream_decoder_finish(m_decoder);
00049         FLAC__stream_decoder_delete(m_decoder); // frees memory
00050         m_decoder = NULL;
00051     }
00052 }
00053 
00054 // soundsource overrides
00055 int SoundSourceFLAC::open() {
00056     m_file.open(QIODevice::ReadOnly);
00057     m_decoder = FLAC__stream_decoder_new();
00058     if (m_decoder == NULL) {
00059         qWarning() << "SSFLAC: decoder allocation failed!";
00060         return ERR;
00061     }
00062     FLAC__StreamDecoderInitStatus initStatus(
00063         FLAC__stream_decoder_init_stream(
00064             m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb,
00065             FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb,
00066             (void*) this)
00067     );
00068     if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
00069         qWarning() << "SSFLAC: decoder init failed!";
00070         goto decoderError;
00071     }
00072     if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) {
00073         qWarning() << "SSFLAC: process to end of meta failed!";
00074         qWarning() << "SSFLAC: decoder state: " << FLAC__stream_decoder_get_state(m_decoder);
00075         goto decoderError;
00076     } // now number of samples etc. should be populated
00077     if (m_flacBuffer == NULL) {
00078         // we want 2 samples per frame, see ::flacWrite code -- bkgood
00079         m_flacBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/];
00080     }
00081     if (m_leftoverBuffer == NULL) {
00082         m_leftoverBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/];
00083     }
00084 //    qDebug() << "SSFLAC: Total samples: " << m_samples;
00085 //    qDebug() << "SSFLAC: Sampling rate: " << m_iSampleRate << " Hz";
00086 //    qDebug() << "SSFLAC: Channels: " << m_iChannels;
00087 //    qDebug() << "SSFLAC: BPS: " << m_bps;
00088     return OK;
00089 decoderError:
00090     FLAC__stream_decoder_finish(m_decoder);
00091     FLAC__stream_decoder_delete(m_decoder);
00092     m_decoder = NULL;
00093     return ERR;
00094 }
00095 
00096 long SoundSourceFLAC::seek(long filepos) {
00097     if (!m_decoder) return 0;
00098     // important division here, filepos is in audio samples (i.e. shorts)
00099     // but libflac expects a number in time samples. I _think_ this should
00100     // be hard-coded at two because *2 is the assumption the caller makes
00101     // -- bkgood
00102     FLAC__stream_decoder_seek_absolute(m_decoder, filepos / 2);
00103     m_leftoverBufferLength = 0; // clear internal buffer since we moved
00104     return filepos;
00105 }
00106 
00107 unsigned int SoundSourceFLAC::read(unsigned long size, const SAMPLE *destination) {
00108     if (!m_decoder) return 0;
00109     SAMPLE *destBuffer(const_cast<SAMPLE*>(destination));
00110     unsigned int samplesWritten = 0;
00111     unsigned int i = 0;
00112     while (samplesWritten < size) {
00113         // if our buffer from libflac is empty (either because we explicitly cleared
00114         // it or because we've simply used all the samples), ask for a new buffer
00115         if (m_flacBufferLength == 0) {
00116             i = 0;
00117             if (!FLAC__stream_decoder_process_single(m_decoder)) {
00118                 qWarning() << "SSFLAC: decoder_process_single returned false";
00119                 break;
00120             } else if (m_flacBufferLength == 0) {
00121                 // EOF
00122                 break;
00123             }
00124         }
00125         destBuffer[samplesWritten++] = m_flacBuffer[i++];
00126         --m_flacBufferLength;
00127     }
00128     if (m_flacBufferLength != 0) {
00129         memcpy(m_leftoverBuffer, &m_flacBuffer[i],
00130                 m_flacBufferLength * sizeof(m_flacBuffer[0])); // safe because leftoverBuffer
00131                                                                // is as long as flacbuffer
00132         memcpy(m_flacBuffer, m_leftoverBuffer,
00133                 m_flacBufferLength * sizeof(m_leftoverBuffer[0]));
00134         // this whole if block could go away if this just used a ring buffer but I'd
00135         // rather do that after I've gotten off the inital happiness of getting this right,
00136         // if I see SIGSEGV one more time I'll pop -- bkgood
00137     }
00138     return samplesWritten;
00139 }
00140 
00141 inline unsigned long SoundSourceFLAC::length() {
00142     return m_samples * m_iChannels;
00143 }
00144 
00145 int SoundSourceFLAC::parseHeader() {
00146     setType("flac");
00147 #ifdef __WINDOWS__
00148     /* From Tobias: A Utf-8 string did not work on my Windows XP (German edition)
00149      * If you try this conversion, f.isValid() will return false in many cases
00150      * and processTaglibFile() will fail
00151      *
00152      * The method toLocal8Bit() returns the local 8-bit representation of the string as a QByteArray.
00153      * The returned byte array is undefined if the string contains characters not supported
00154      * by the local 8-bit encoding.
00155      */
00156     QByteArray qBAFilename = m_qFilename.toLocal8Bit();
00157 #else
00158     QByteArray qBAFilename = m_qFilename.toUtf8();
00159 #endif
00160     TagLib::FLAC::File f(qBAFilename.constData());
00161     bool result = processTaglibFile(f);
00162     TagLib::ID3v2::Tag *id3v2(f.ID3v2Tag());
00163     TagLib::Ogg::XiphComment *xiph(f.xiphComment());
00164     if (id3v2) {
00165         processID3v2Tag(id3v2);
00166     }
00167     if (xiph) {
00168         processXiphComment(xiph);
00169     }
00170     return result ? OK : ERR;
00171 }
00172 
00177 inline int SoundSourceFLAC::getShift() const {
00178     return 16 - m_bps;
00179 }
00180 
00184 inline FLAC__int16 SoundSourceFLAC::shift(FLAC__int32 sample) const {
00185     // this is how libsndfile does this operation and is wonderfully
00186     // straightforward. Just shift the sample left or right so that
00187     // it fits in a 16-bit short. -- bkgood
00188     int shift(getShift());
00189     if (shift == 0) {
00190         return sample;
00191     } else if (shift < 0) {
00192         return sample >> abs(shift);
00193     } else {
00194         return sample << shift;
00195     }
00196 };
00197 
00198 // static
00199 QList<QString> SoundSourceFLAC::supportedFileExtensions() {
00200     QList<QString> list;
00201     list.push_back("flac");
00202     return list;
00203 }
00204 
00205 
00206 // flac callback methods
00207 FLAC__StreamDecoderReadStatus SoundSourceFLAC::flacRead(FLAC__byte buffer[], size_t *bytes) {
00208     *bytes = m_file.read((char*) buffer, *bytes);
00209     if (*bytes > 0) {
00210         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
00211     } else if (*bytes == 0) {
00212         return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
00213     } else {
00214         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
00215     }
00216 }
00217 
00218 FLAC__StreamDecoderSeekStatus SoundSourceFLAC::flacSeek(FLAC__uint64 offset) {
00219     if (m_file.seek(offset)) {
00220         return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
00221     } else {
00222         return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
00223     }
00224 }
00225 
00226 FLAC__StreamDecoderTellStatus SoundSourceFLAC::flacTell(FLAC__uint64 *offset) {
00227     if (m_file.isSequential()) {
00228         return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
00229     }
00230     *offset = m_file.pos();
00231     return FLAC__STREAM_DECODER_TELL_STATUS_OK;
00232 }
00233 
00234 FLAC__StreamDecoderLengthStatus SoundSourceFLAC::flacLength(FLAC__uint64 *length) {
00235     if (m_file.isSequential()) {
00236         return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
00237     }
00238     *length = m_file.size();
00239     return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
00240 }
00241 
00242 FLAC__bool SoundSourceFLAC::flacEOF() {
00243     if (m_file.isSequential()) {
00244         return false;
00245     }
00246     return m_file.atEnd();
00247 }
00248 
00249 FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite(const FLAC__Frame *frame,
00250         const FLAC__int32 *const buffer[]) {
00251     unsigned int i(0);
00252     m_flacBufferLength = 0;
00253     if (frame->header.channels > 1) {
00254         // stereo (or greater)
00255         for (i = 0; i < frame->header.blocksize; ++i) {
00256             m_flacBuffer[m_flacBufferLength++] = shift(buffer[0][i]); // left channel
00257             m_flacBuffer[m_flacBufferLength++] = shift(buffer[1][i]); // right channel
00258         }
00259     } else {
00260         // mono
00261         for (i = 0; i < frame->header.blocksize; ++i) {
00262             m_flacBuffer[m_flacBufferLength++] = shift(buffer[0][i]); // left channel
00263             m_flacBuffer[m_flacBufferLength++] = shift(buffer[0][i]); // mono channel
00264         }
00265     }
00266     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; // can't anticipate any errors here
00267 }
00268 
00269 void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata *metadata) {
00270     switch (metadata->type) {
00271     case FLAC__METADATA_TYPE_STREAMINFO:
00272         m_samples = metadata->data.stream_info.total_samples;
00273         m_iChannels = metadata->data.stream_info.channels;
00274         m_iSampleRate = metadata->data.stream_info.sample_rate;
00275         m_bps = metadata->data.stream_info.bits_per_sample;
00276         m_minBlocksize = metadata->data.stream_info.min_blocksize;
00277         m_maxBlocksize = metadata->data.stream_info.max_blocksize;
00278         m_minFramesize = metadata->data.stream_info.min_framesize;
00279         m_maxFramesize = metadata->data.stream_info.max_framesize;
00280 //        qDebug() << "FLAC file " << m_qFilename;
00281 //        qDebug() << m_iChannels << " @ " << m_iSampleRate << " Hz, " << m_samples
00282 //            << " total, " << m_bps << " bps";
00283 //        qDebug() << "Blocksize in [" << m_minBlocksize << ", " << m_maxBlocksize
00284 //            << "], Framesize in [" << m_minFramesize << ", " << m_maxFramesize << "]";
00285         break;
00286     default:
00287         break;
00288     }
00289 }
00290 
00291 void SoundSourceFLAC::flacError(FLAC__StreamDecoderErrorStatus status) {
00292     QString error;
00293     // not much can be done at this point -- luckly the decoder seems to be
00294     // pretty forgiving -- bkgood
00295     switch (status) {
00296     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
00297         error = "STREAM_DECODER_ERROR_STATUS_LOST_SYNC";
00298         break;
00299     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
00300         error = "STREAM_DECODER_ERROR_STATUS_BAD_HEADER";
00301         break;
00302     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
00303         error = "STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH";
00304         break;
00305     case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
00306         error = "STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM";
00307         break;
00308     }
00309     qWarning() << "SSFLAC got error" << error << "from libFLAC for file"
00310         << m_file.fileName();
00311     // not much else to do here... whatever function that initiated whatever
00312     // decoder method resulted in this error will return an error, and the caller
00313     // will bail. libFLAC docs say to not close the decoder here -- bkgood
00314 }
00315 
00316 // begin callbacks (have to be regular functions because normal libFLAC isn't C++-aware)
00317 
00318 FLAC__StreamDecoderReadStatus FLAC_read_cb(const FLAC__StreamDecoder*, FLAC__byte buffer[],
00319         size_t *bytes, void *client_data) {
00320     return ((SoundSourceFLAC*) client_data)->flacRead(buffer, bytes);
00321 }
00322 
00323 FLAC__StreamDecoderSeekStatus FLAC_seek_cb(const FLAC__StreamDecoder*,
00324         FLAC__uint64 absolute_byte_offset, void *client_data) {
00325     return ((SoundSourceFLAC*) client_data)->flacSeek(absolute_byte_offset);
00326 }
00327 
00328 FLAC__StreamDecoderTellStatus FLAC_tell_cb(const FLAC__StreamDecoder*,
00329         FLAC__uint64 *absolute_byte_offset, void *client_data) {
00330     return ((SoundSourceFLAC*) client_data)->flacTell(absolute_byte_offset);
00331 }
00332 
00333 FLAC__StreamDecoderLengthStatus FLAC_length_cb(const FLAC__StreamDecoder*,
00334         FLAC__uint64 *stream_length, void *client_data) {
00335     return ((SoundSourceFLAC*) client_data)->flacLength(stream_length);
00336 }
00337 
00338 FLAC__bool FLAC_eof_cb(const FLAC__StreamDecoder*, void *client_data) {
00339     return ((SoundSourceFLAC*) client_data)->flacEOF();
00340 }
00341 
00342 FLAC__StreamDecoderWriteStatus FLAC_write_cb(const FLAC__StreamDecoder*, const FLAC__Frame *frame,
00343         const FLAC__int32 *const buffer[], void *client_data) {
00344     return ((SoundSourceFLAC*) client_data)->flacWrite(frame, buffer);
00345 }
00346 
00347 void FLAC_metadata_cb(const FLAC__StreamDecoder*, const FLAC__StreamMetadata *metadata, void *client_data) {
00348     ((SoundSourceFLAC*) client_data)->flacMetadata(metadata);
00349 }
00350 
00351 void FLAC_error_cb(const FLAC__StreamDecoder*, FLAC__StreamDecoderErrorStatus status, void *client_data) {
00352     ((SoundSourceFLAC*) client_data)->flacError(status);
00353 }
00354 // end callbacks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines