traverso-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Traverso-commit] traverso/src/core MadAudioReader.cpp


From: Ben Levitt
Subject: [Traverso-commit] traverso/src/core MadAudioReader.cpp
Date: Mon, 09 Jul 2007 03:38:03 +0000

CVSROOT:        /sources/traverso
Module name:    traverso
Changes by:     Ben Levitt <benjie>     07/07/09 03:38:03

Modified files:
        src/core       : MadAudioReader.cpp 

Log message:
        fix frame-exact seeking in mp3 files, some whitespace fixes that should 
have been in a separate commit

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MadAudioReader.cpp?cvsroot=traverso&r1=1.1&r2=1.2

Patches:
Index: MadAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/MadAudioReader.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- MadAudioReader.cpp  8 Jul 2007 23:16:56 -0000       1.1
+++ MadAudioReader.cpp  9 Jul 2007 03:38:03 -0000       1.2
@@ -41,7 +41,7 @@
        K3bMad();
        ~K3bMad();
        
-       bool open( const QString& filename );
+       bool open(const QString& filename);
        
        /**
         * @return true if the mad stream contains data
@@ -250,7 +250,7 @@
                
                // skip the id3 tag
                if (!m_inputFile.seek(offset)) {
-                       PERROR("Couldn't seek to %u in %s", offset, 
m_inputFile.fileName());
+                       PERROR("Couldn't seek to %u in %s", offset, 
QS_C(m_inputFile.fileName()));
                        return false;
                }
        }
@@ -529,27 +529,31 @@
        // It always takes waves for mp3 files so we introduce this hack to
        // filter out wave files. :(
        //
-       QFile f( filename );
-       if( !f.open( QIODevice::ReadOnly ) )
+       QFile f(filename);
+       if (!f.open( QIODevice::ReadOnly)) {
                return false;
+       }
+       
        char buffer[12];
-       if( f.read( buffer, 12 ) != 12 )
+       if (f.read(buffer, 12) != 12) {
                return false;
-       if( !qstrncmp( buffer, "RIFF", 4 ) && !qstrncmp( buffer + 8, "WAVE", 4 
) )
+       }
+       if (!qstrncmp(buffer, "RIFF", 4) && !qstrncmp(buffer + 8, "WAVE", 4)) {
                return false;
+       }
        f.close();
        
        
        K3bMad handle;
-       if( !handle.open( filename ) )
+       if (!handle.open(filename)) {
                return false;
-       
+       }
        handle.skipTag();
-       if( !handle.seekFirstHeader() )
+       if (!handle.seekFirstHeader()) {
                return false;
-       
-       if( handle.findNextHeader() ) {
-               int c = MAD_NCHANNELS( &handle.madFrame->header );
+       }
+       if (handle.findNextHeader()) {
+               int c = MAD_NCHANNELS(&handle.madFrame->header);
                int layer = handle.madFrame->header.layer;
                unsigned int s = handle.madFrame->header.samplerate;
                
@@ -559,18 +563,18 @@
                // for example wave files.
                //
                int cnt = 1;
-               while( handle.findNextHeader() ) {
+               while (handle.findNextHeader()) {
                        // compare the found headers
-                       if( MAD_NCHANNELS( &handle.madFrame->header ) == c &&
+                       if (MAD_NCHANNELS(&handle.madFrame->header) == c &&
                        handle.madFrame->header.layer == layer &&
-                       handle.madFrame->header.samplerate == s ) {
+                           handle.madFrame->header.samplerate == s) {
                                // only support layer III for now since 
otherwise some wave files
                                // are taken for layer I
-                               if( ++cnt >= 5 ) {
+                               if (++cnt >= 5) {
                                        //stdout << "(MadDecoder) valid mpeg 1 
layer " << layer 
                                        //<< " file with " << c << " channels 
and a samplerate of "
                                        //<< s << endl;
-                                       return ( layer == MAD_LAYER_III );
+                                       return (layer == MAD_LAYER_III);
                                }
                        }
                        else
@@ -642,11 +646,12 @@
        double posSecs = static_cast<double>(start) / get_rate();
        
        // seekPosition to seek after frame i
-       unsigned int frame = static_cast<unsigned int>( posSecs / mp3FrameSecs 
);
+       unsigned int frame = static_cast<unsigned int>(posSecs / mp3FrameSecs);
+       nframes_t frameOffset = (nframes_t)(start - (frame * mp3FrameSecs * 
get_rate() + 0.5)) * get_num_channels();
        
        // Rob said: 29 frames is the theoretically max frame reservoir limit 
(whatever that means...)
        // it seems that mad needs at most 29 frames to get ready
-       unsigned int frameReservoirProtect = ( frame > 29 ? 29 : frame );
+       unsigned int frameReservoirProtect = (frame > 29 ? 29 : frame);
        
        frame -= frameReservoirProtect;
        
@@ -655,13 +660,14 @@
        
        // decode some frames ignoring MAD_ERROR_BADDATAPTR errors
        unsigned int i = 1;
-       while( i <= frameReservoirProtect ) {
+       while (i <= frameReservoirProtect) {
                d->handle->fillStreamBuffer();
-               if( mad_frame_decode( d->handle->madFrame, d->handle->madStream 
) ) {
-                       if( MAD_RECOVERABLE( d->handle->madStream->error ) ) {
-                               if( d->handle->madStream->error == 
MAD_ERROR_BUFLEN )
+               if (mad_frame_decode( d->handle->madFrame, 
d->handle->madStream)) {
+                       if (MAD_RECOVERABLE( d->handle->madStream->error)) {
+                               if (d->handle->madStream->error == 
MAD_ERROR_BUFLEN) {
                                        continue;
-                               else if( d->handle->madStream->error != 
MAD_ERROR_BADDATAPTR ) {
+                               }
+                               else if (d->handle->madStream->error != 
MAD_ERROR_BADDATAPTR) {
                                        //kdDebug() << "(K3bMadDecoder) 
Seeking: recoverable mad error ("
                                        //<< 
mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                                        continue;
@@ -671,16 +677,32 @@
                                        //<< 
mad_stream_errorstr(d->handle->madStream) << ")" << endl;
                                }
                        }
-                       else
+                       else {
                        return false;
                }
+               }
        
-               if( i == frameReservoirProtect )  // synth only the last frame 
(Rob said so ;)
+               if (i == frameReservoirProtect) {  // synth only the last frame 
(Rob said so ;)
                        mad_synth_frame( d->handle->madSynth, 
d->handle->madFrame );
+               }
        
                ++i;
        }
        
+       d->overflowStart = 0;
+       d->overflowSize = 0;
+       
+       // Seek to exact traverso frame, within this mp3 frame
+       if (frameOffset > 0) {
+               //printf("seekOffset: %lu (start: %lu)\n", frameOffset, start);
+               d->outputBuffer = 0; // Zeros so that we write to overflow
+               d->outputBufferEnd = 0;
+               d->outputPointer = d->outputBufferEnd + 1;
+               createPcmSamples(d->handle->madSynth);
+               d->overflowStart = frameOffset;
+               d->overflowSize -= frameOffset;
+       }
+       
        m_nextFrame = start;
        
        return true;
@@ -693,14 +715,17 @@
        
        d->bOutputFinished = false;
        
-       if( !d->handle->open( m_fileName ) )
+       if (!d->handle->open(m_fileName)) {
                return false;
+       }
        
-       if( !d->handle->skipTag() )
+       if (!d->handle->skipTag()) {
                return false;
+       }
        
-       if( !d->handle->seekFirstHeader() )
+       if (!d->handle->seekFirstHeader()) {
                return false;
+       }
        
        return true;
 }
@@ -733,12 +758,12 @@
                
                // save the number of bytes to be read to decode i-1 frames at 
position i
                // in other words: when seeking to seekPos the next decoded 
frame will be i
-               d->seekPositions.append( seekPos );
+               d->seekPositions.append(seekPos);
        }
        
-       if( !d->handle->inputError() && !error ) {
-               frames =  get_rate() * (d->handle->madTimer->seconds + 
-                       
(float)d->handle->madTimer->fraction/(float)MAD_TIMER_RESOLUTION);
+       if (!d->handle->inputError() && !error) {
+               frames =  get_rate() * (d->handle->madTimer->seconds + 
(unsigned long)(
+                       
(float)d->handle->madTimer->fraction/(float)MAD_TIMER_RESOLUTION));
                //kdDebug() << "(K3bMadDecoder) length of track " << seconds << 
endl;
        }
 
@@ -814,24 +839,29 @@
                int padLength = (remainingSamplesRequested > 
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
                memset(d->outputPointer, 0, padLength);
                samplesWritten += padLength;
+               //printf("remainingSamplesRequested: %d, 
remainingSamplesInFile: %d (using: %d)\n", remainingSamplesRequested, 
remainingSamplesInFile, padLength);
        }       
        
-       //printf("at: %lu (total: %lu), request: %d (returned: %d)\n", 
m_nextFrame, m_frames, sampleCount/get_num_channels(), 
(samplesWritten)/get_num_channels());
+       //if (samplesWritten) printf("at: %lu (total: %lu), request: %d 
(returned: %d)\n", m_nextFrame, m_frames, sampleCount/get_num_channels(), 
samplesWritten/get_num_channels());
+       
+       // Truncate so we don't return too many samples
+       if (samplesWritten > remainingSamplesInFile) {
+               samplesWritten = remainingSamplesInFile;
+       }
        
        m_nextFrame += samplesWritten / get_num_channels();
        return samplesWritten;
 }
 
 
-bool MadAudioReader::createPcmSamples( mad_synth* synth )
+bool MadAudioReader::createPcmSamples(mad_synth* synth)
 {
        unsigned short nsamples = synth->pcm.length;
        bool overflow = false;
        
        // now create the output
        for (int i = 0; i < nsamples; i++) {
-               if (d->outputPointer >= d->outputBufferEnd) {
-                       //printf("start overflowing\n");
+               if (overflow == false && d->outputPointer > d->outputBufferEnd) 
{
                        d->outputPointer = d->overflowBuffer;
                        overflow = true;
                }
@@ -851,6 +881,7 @@
                d->overflowSize = d->outputPointer - d->overflowBuffer;
                d->overflowStart = 0;
                d->outputPointer = d->outputBufferEnd;
+               //printf("overflowing %lu samples\n", d->overflowSize);
        }
        
        return true;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]