traverso-commit
[Top][All Lists]
Advanced

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

[Traverso-commit] traverso/src/core ResampleAudioReader.cpp Resam...


From: Ben Levitt
Subject: [Traverso-commit] traverso/src/core ResampleAudioReader.cpp Resam...
Date: Mon, 23 Jul 2007 16:23:39 +0000

CVSROOT:        /sources/traverso
Module name:    traverso
Changes by:     Ben Levitt <benjie>     07/07/23 16:23:39

Modified files:
        src/core       : ResampleAudioReader.cpp ResampleAudioReader.h 

Log message:
        Fix Resampler to not miss any samples mid-clip. (Used to miss 0 or 1 on 
each read.)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.cpp?cvsroot=traverso&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.h?cvsroot=traverso&r1=1.9&r2=1.10

Patches:
Index: ResampleAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- ResampleAudioReader.cpp     20 Jul 2007 23:04:21 -0000      1.12
+++ ResampleAudioReader.cpp     23 Jul 2007 16:23:39 -0000      1.13
@@ -24,6 +24,8 @@
 #include "Utils.h"
 #include "AudioDevice.h"
 
+#define OVERFLOW_SIZE 1024
+
 // Always put me below _all_ includes, this is needed
 // in case we run with memory leak detection enabled!
 #include "Debugger.h"
@@ -40,6 +42,7 @@
        }
        
        m_fileBuffers.resize(get_num_channels());
+       m_filePointers.resize(get_num_channels());
        m_fileBufferLength = 0;
        
        init(converter_type);
@@ -76,10 +79,17 @@
                        m_reader = 0;
                        return;
                }
+               m_srcStates.append(src_new(converter_type, 1, &error));
+               if (!m_srcStates[c]) {
+                       PERROR("ResampleAudioReader: couldn't create 
libSampleRate SRC_STATE");
+                       delete m_reader;
+                       m_reader = 0;
+                       return;
+               }
        }
        
        reset();
-       seek(0);
+       seek_private(0);
 }
 
 
@@ -91,6 +101,8 @@
        }
        
        m_srcData.end_of_input = 0;
+       m_overflowUsed = 0;
+       m_eof = 0;
 }
 
 
@@ -153,48 +165,60 @@
 // otherwise get data from childreader and use libsamplerate to convert
 nframes_t ResampleAudioReader::read_private(audio_sample_t** buffer, nframes_t 
frameCount)
 {
-       nframes_t sourceFramesRead;
-       nframes_t framesRead;
        Q_ASSERT(m_reader);
        
-       /////////////////////////////////
-       // Ben says: FIXME: Add an overflow buffer, and grab more samples at a 
time, saving the extra to the overflow.
-       // This may improve performance? And should fix micro-view waveform 
painting errors.
-       /////////////////////////////////
-       
        // pass through if not changing sampleRate.
        if (audiodevice().get_sample_rate() == (uint)m_reader->get_rate()) {
-               sourceFramesRead = m_reader->read(buffer, frameCount);
-               return sourceFramesRead;
+               return m_reader->read(buffer, frameCount);
        }
        
+       nframes_t bufferUsed;
+       nframes_t framesRead;
+       
        nframes_t fileCnt = song_to_file_frame(frameCount);
        
        if (frameCount && !fileCnt) {
                fileCnt = 1;
        }
        
-       // make sure that the reusable m_fileBuffers are big enough for this 
read
-       if ((uint)m_fileBufferLength < fileCnt) {
+       bufferUsed = m_overflowUsed;
+       
+       if (!m_eof) { // FIXME: add and use Reader::eof()
+               // make sure that the reusable m_fileBuffers are big enough for 
this read + OVERFLOW_SIZE
+               if ((uint)m_fileBufferLength < fileCnt + OVERFLOW_SIZE) {
                for (int c = 0; c < get_num_channels(); c++) {
-                       if (m_fileBuffers.size()) {
+                               if (m_fileBufferLength) {
                                delete m_fileBuffers[c];
                        }
-                       m_fileBuffers[c] = new audio_sample_t[fileCnt];
+                               m_fileBuffers[c] = new audio_sample_t[fileCnt + 
OVERFLOW_SIZE];
+                       }
+                       m_fileBufferLength = fileCnt + OVERFLOW_SIZE;
+               }
+               
+               for (int c = 0; c < get_num_channels(); c++) {
+                       m_filePointers[c] = m_fileBuffers[c] + m_overflowUsed;
                }
-               m_fileBufferLength = fileCnt;
+               
+               bufferUsed += m_reader->read(m_filePointers.data(), fileCnt + 
OVERFLOW_SIZE - m_overflowUsed);
+               //printf("Resampler: Read %lu of %lu (%lu)\n", bufferUsed, 
fileCnt + OVERFLOW_SIZE - m_overflowUsed, m_reader->get_length());
        }
        
-       sourceFramesRead = m_reader->read(m_fileBuffers.data(), fileCnt);
+       if (bufferUsed < fileCnt) {
+               m_srcData.end_of_input = 1;
+               m_eof = 1;
+       }
        
-       //printf("Resampler: sampleCount %lu, fileCnt %lu, returned %lu\n", 
sampleCount/get_num_channels(), fileCnt/get_num_channels(), 
samplesRead/get_num_channels());
+       nframes_t framesToConvert = frameCount;
+       if (frameCount > get_length() - m_readPos) {
+               framesToConvert = get_length() - m_readPos;
+       }
        
        for (int c = 0; c < get_num_channels(); c++) {
                // Set up sample rate converter struct for s.r.c. processing
                m_srcData.data_in = m_fileBuffers[c];
-               m_srcData.input_frames = sourceFramesRead;
+               m_srcData.input_frames = bufferUsed;
                m_srcData.data_out = buffer[c];
-               m_srcData.output_frames = frameCount;
+               m_srcData.output_frames = framesToConvert;
                m_srcData.src_ratio = (double) audiodevice().get_sample_rate() 
/ m_reader->get_rate();
                src_set_ratio(m_srcStates[c], m_srcData.src_ratio);
                
@@ -203,16 +227,23 @@
                        return 0;
                }
                framesRead = m_srcData.output_frames_gen;
-               printf("%lu -- ", framesRead);
        }
-       printf("(frames read per channel)\n");
        
-       // Pad end of file with 0s if necessary
-       int remainingFramesRequested = frameCount - framesRead;
-       int remainingFramesInFile = get_length() - m_readPos - 
m_srcData.output_frames_gen;
+       m_overflowUsed = bufferUsed - m_srcData.input_frames_used;
+       
+       if (m_overflowUsed < 0) {
+               m_overflowUsed = 0;
+       }
        
-       if (framesRead == 0 && remainingFramesRequested > 0 && 
remainingFramesInFile > 0) {
-               int padLength = (remainingFramesRequested > 
remainingFramesInFile) ? remainingFramesInFile : remainingFramesRequested;
+       if (m_srcData.input_frames_used < bufferUsed) {
+               for (int c = 0; c < get_num_channels(); c++) {
+                       memmove(m_fileBuffers[c], m_fileBuffers[c] + 
m_srcData.input_frames_used, m_overflowUsed * sizeof(audio_sample_t));
+               }
+       }
+       
+       // Pad end of file with 0s if necessary
+       if (framesRead == 0 && m_readPos < get_length()) {
+               int padLength = m_readPos;
                for (int c = 0; c < get_num_channels(); c++) {
                        memset(buffer[c] + framesRead, 0, padLength * 
sizeof(audio_sample_t));
                }
@@ -221,10 +252,12 @@
        }       
        
        // Truncate so we don't return too many samples
-       if (framesRead > (uint)remainingFramesInFile) {
-               printf("Resampler: truncating: %d\n", framesRead - 
remainingFramesInFile);
-               framesRead = remainingFramesInFile;
-       }
+       /*if (m_readPos + framesRead > get_length()) {
+               printf("Resampler: truncating: %d\n", framesRead - 
(get_length() - m_readPos));
+               framesRead = get_length() - m_readPos;
+       }*/
+       
+       //printf("framesRead: %lu of %lu (overflow: %lu) (at: %lu of %lu)\n", 
framesRead, frameCount, m_overflowUsed, m_readPos + framesRead, get_length());
        
        return framesRead;
 }

Index: ResampleAudioReader.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- ResampleAudioReader.h       20 Jul 2007 23:04:21 -0000      1.9
+++ ResampleAudioReader.h       23 Jul 2007 16:23:39 -0000      1.10
@@ -53,7 +53,10 @@
        QVector<SRC_STATE*>     m_srcStates;
        SRC_DATA                m_srcData;
        QVector<audio_sample_t*> m_fileBuffers;
+       QVector<audio_sample_t*> m_filePointers;
        long                    m_fileBufferLength;
+       long                    m_overflowUsed;
+       bool                    m_eof;
 };
 
 #endif




reply via email to

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