traverso-commit
[Top][All Lists]
Advanced

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

[Traverso-commit] traverso/src commands/AudioClipExternalProcessi...


From: Remon Sijrier
Subject: [Traverso-commit] traverso/src commands/AudioClipExternalProcessi...
Date: Wed, 18 Jul 2007 13:13:08 +0000

CVSROOT:        /sources/traverso
Module name:    traverso
Changes by:     Remon Sijrier <r_sijrier>       07/07/18 13:13:08

Modified files:
        src/commands   : AudioClipExternalProcessing.cpp 
        src/core       : AbstractAudioReader.cpp AbstractAudioReader.h 
                         AudioClip.cpp AudioClip.h AudioSource.cpp 
                         AudioSource.h core.pro DiskIO.cpp DiskIO.h 
                         FlacAudioReader.cpp MadAudioReader.cpp Peak.cpp 
                         ReadSource.cpp ReadSource.h 
                         ResampleAudioReader.cpp ResampleAudioReader.h 
                         ResourcesManager.cpp ResourcesManager.h 
                         SFAudioReader.cpp Song.cpp Track.cpp 
                         VorbisAudioReader.cpp 
        src/traverso/songcanvas: AudioClipView.cpp 
Removed files:
        src/core       : MonoReader.cpp MonoReader.h 

Log message:
        * Merged MonoReader and ReadSource into ReadSource
        * Buffered reading reads all channels in one go now, modified Peak, 
Track, AudioClip::process() to take care of it
        * Renamed AbstractAudioReader variable m_nextFrame to m_readPos, seems 
more logical. Updating of this variable is only done now in AUR read_from() 
function, avoids duplication of code in all audioreaders, and it also fixed the 
 always seeking in read_from() with resampled reader.
        * AudioDevice paramater changes now issues a seek, so DiskIO seeks to 
the correct position and as a result ResampleReader buffers are cleared and 
filled with correc data
        * Needs more love and work :D

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/commands/AudioClipExternalProcessing.cpp?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AbstractAudioReader.cpp?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AbstractAudioReader.h?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.cpp?cvsroot=traverso&r1=1.113&r2=1.114
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.h?cvsroot=traverso&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.cpp?cvsroot=traverso&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.h?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/core.pro?cvsroot=traverso&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/DiskIO.cpp?cvsroot=traverso&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/DiskIO.h?cvsroot=traverso&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/FlacAudioReader.cpp?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MadAudioReader.cpp?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Peak.cpp?cvsroot=traverso&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ReadSource.cpp?cvsroot=traverso&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ReadSource.h?cvsroot=traverso&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.cpp?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.h?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResourcesManager.cpp?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResourcesManager.h?cvsroot=traverso&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/SFAudioReader.cpp?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Song.cpp?cvsroot=traverso&r1=1.122&r2=1.123
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Track.cpp?cvsroot=traverso&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/VorbisAudioReader.cpp?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MonoReader.cpp?cvsroot=traverso&r1=1.22&r2=0
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MonoReader.h?cvsroot=traverso&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/songcanvas/AudioClipView.cpp?cvsroot=traverso&r1=1.80&r2=1.81

Patches:
Index: commands/AudioClipExternalProcessing.cpp
===================================================================
RCS file: 
/sources/traverso/traverso/src/commands/AudioClipExternalProcessing.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- commands/AudioClipExternalProcessing.cpp    2 Jul 2007 20:34:21 -0000       
1.20
+++ commands/AudioClipExternalProcessing.cpp    18 Jul 2007 13:13:05 -0000      
1.21
@@ -54,7 +54,8 @@
        void run() {
                uint buffersize = 16384;
                audio_sample_t readbuffer[buffersize];
-               audio_sample_t* mixdown = new audio_sample_t[2 * buffersize];
+               audio_sample_t* mixdown[2];
+               for (int i=0; i<2; ++i) mixdown[i] = new audio_sample_t[2 * 
buffersize];
        
                ExportSpecification* spec = new ExportSpecification();
                spec->start_frame = 0;
@@ -82,12 +83,11 @@
                
                        memset (spec->dataF, 0, sizeof (spec->dataF[0]) * 
nframes * spec->channels);
                
-                       for (int chan=0; chan < 2; ++chan) {
-                       
-                               m_readsource->file_read(chan, mixdown, 
spec->pos, nframes, readbuffer);
+                       m_readsource->file_read(mixdown, spec->pos, nframes, 
readbuffer);
                        
+                       for (int chan=0; chan < 2; ++chan) {
                                for (uint x = 0; x < nframes; ++x) {
-                                       spec->dataF[chan+(x*spec->channels)] = 
mixdown[x];
+                                       spec->dataF[chan+(x*spec->channels)] = 
mixdown[chan][x];
                                }
                        }
                
@@ -101,7 +101,8 @@
                delete writesource;
                delete [] spec->dataF;
                delete spec;
-               delete [] mixdown;
+               for (int i=0; i<2; ++i)
+                       delete [] mixdown[i];
        }
 
 private:
@@ -125,6 +126,7 @@
 
 int AudioClipExternalProcessing::prepare_actions()
 {
+       PENTER;
        ExternalProcessingDialog epdialog(Interface::instance(), this);
        
        epdialog.exec();
@@ -217,15 +219,15 @@
                        
m_filename.remove(".wav").remove(".").append("-").append(m_commandargs.simplified()).append(".wav");
        
        
-       if (rs->get_channel_count() == 2 && rs->get_file_count() == 2) {
+/*     if (rs->get_channel_count() == 2 && rs->get_file_count() == 2) {
                m_merger = new MergeThread(rs, "merged.wav");
                connect(m_merger, SIGNAL(finished()), this, 
SLOT(start_external_processing()));
                m_merger->start();
                statusText->setHtml(tr("Preparing audio data to a format that 
can be used by <b>%1</b>, this can take a while for large 
files!").arg(m_program));
                progressBar->setMaximum(0);
-       } else {        
+       } else {        */
                start_external_processing();
-       }
+//     }
 }
 
 void ExternalProcessingDialog::start_external_processing()

Index: core/AbstractAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AbstractAudioReader.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/AbstractAudioReader.cpp        15 Jul 2007 05:14:47 -0000      1.6
+++ core/AbstractAudioReader.cpp        18 Jul 2007 13:13:05 -0000      1.7
@@ -34,11 +34,11 @@
 #include "Debugger.h"
 
 
-AbstractAudioReader::AbstractAudioReader(QString filename)
+AbstractAudioReader::AbstractAudioReader(const QString& filename)
  : QObject(0)
 {
        m_fileName = filename;
-       m_nextFrame = 0;
+       m_readPos = 0;
 }
 
 
@@ -53,20 +53,28 @@
 {
        QMutexLocker locker( &m_mutex );
        
-       if (m_nextFrame != start) {
+//     printf("read_from:: before_seek from %d, framepos is %d\n", start, 
m_readPos);
+       
+       if (m_readPos != start) {
+//             printf("starting seek\n");
                if (!seek(start)) {
                        return 0;
+               } else {
+                       m_readPos = start;
                }
        }
        
+//     printf("read_from:: after_seek from %d, framepos is %d\n", start, 
m_readPos);
        int samplesRead = read(dst, cnt);
        
+       m_readPos += samplesRead / get_num_channels();
+       
        return samplesRead;
 }
 
 
 // Static method used by other classes to get an AudioReader for the correct 
file type
-AbstractAudioReader* AbstractAudioReader::create_audio_reader(QString filename)
+AbstractAudioReader* AbstractAudioReader::create_audio_reader(const QString& 
filename)
 {
        AbstractAudioReader* newReader;
        
@@ -97,7 +105,7 @@
 
 // Static method used by other classes to get an automatically resampling 
AudioReader that wraps
 // an AudioReader chosen by create_audio_reader().
-AbstractAudioReader* 
AbstractAudioReader::create_resampled_audio_reader(QString filename, int 
converter_type)
+AbstractAudioReader* AbstractAudioReader::create_resampled_audio_reader(const 
QString& filename, int converter_type)
 {
        ResampleAudioReader* newReader;
 

Index: core/AbstractAudioReader.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AbstractAudioReader.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/AbstractAudioReader.h  15 Jul 2007 05:14:47 -0000      1.6
+++ core/AbstractAudioReader.h  18 Jul 2007 13:13:05 -0000      1.7
@@ -31,9 +31,10 @@
 
 class AbstractAudioReader : public QObject
 {
-Q_OBJECT
+       Q_OBJECT
+
 public:
-       AbstractAudioReader(QString filename);
+       AbstractAudioReader(const QString& filename);
        ~AbstractAudioReader();
        
        virtual int get_num_channels() = 0;
@@ -43,14 +44,13 @@
        virtual bool seek(nframes_t start) = 0;
        virtual int read(audio_sample_t* dst, int sampleCount) = 0;
        
-       static AbstractAudioReader* create_audio_reader(QString filename);
-       static AbstractAudioReader* create_resampled_audio_reader(QString 
filename, int converter_type);
-       static bool can_decode(QString filename) { return false; };
+       static AbstractAudioReader* create_audio_reader(const QString& 
filename);
+       static AbstractAudioReader* create_resampled_audio_reader(const 
QString& filename, int converter_type);
 
 protected:
        QString         m_fileName;
        QMutex          m_mutex;
-       nframes_t       m_nextFrame;
+       nframes_t       m_readPos;
 
 };
 

Index: core/AudioClip.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.cpp,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -b -r1.113 -r1.114
--- core/AudioClip.cpp  16 Jul 2007 01:48:10 -0000      1.113
+++ core/AudioClip.cpp  18 Jul 2007 13:13:05 -0000      1.114
@@ -102,6 +102,10 @@
                m_song->get_diskio()->unregister_read_source(m_readSource);
                delete m_readSource;
        }
+       // FIXME crashes with a double free in ResourcesManager desctructor on 
deleting a ReadSource :(
+/*     foreach(Peak* peak, m_peaks) {
+               peak->close();
+       }*/
 }
 
 void AudioClip::init()
@@ -379,12 +383,12 @@
 //
 //  Function called in RealTime AudioThread processing path
 //
-int AudioClip::process(nframes_t nframes, audio_sample_t* buffer, uint channel)
+int AudioClip::process(nframes_t nframes)
 {
        Q_ASSERT(m_song);
        
        if (m_recordingStatus == RECORDING) {
-               process_capture(nframes, channel);
+//             process_capture(nframes, channel);
                return 0;
        }
 
@@ -398,12 +402,13 @@
        
        Q_ASSERT(m_readSource);
        
-       if (channel >= m_readSource->get_channel_count()) {
+/*     if (channel >= m_readSource->get_channel_count()) {
                return 1;
-       }
+       }*/
        
+       AudioBus* bus = m_song->get_render_bus();
        nframes_t mix_pos;
-       audio_sample_t* mixdown;
+       audio_sample_t* mixdown[get_channels()];
 
 
        nframes_t transportFrame = m_song->get_transport_frame();
@@ -413,11 +418,17 @@
                if (transportFrame < trackStartFrame) {
                        uint offset = trackStartFrame - transportFrame;
                        mix_pos = sourceStartFrame;
-                       mixdown = buffer + offset;
+//                     mixdown = buffer + offset;
+                       for (int chan=0; chan<bus->get_channel_count(); ++chan) 
{
+                               mixdown[chan] = bus->get_buffer(chan, nframes) 
+ offset;
+                       }
                        nframes = nframes - offset;
                } else {
                        mix_pos = transportFrame - trackStartFrame + 
sourceStartFrame;
-                       mixdown = buffer;
+//                     mixdown = buffer;
+                       for (int chan=0; chan<bus->get_channel_count(); ++chan) 
{
+                               mixdown[chan] = bus->get_buffer(chan, nframes);
+                       }
                }
                if (trackEndFrame < upperRange) {
                        nframes -= (upperRange - trackEndFrame);
@@ -431,21 +442,27 @@
 
 
        if (m_song->realtime_path()) {
-               read_frames = m_readSource->rb_read(channel, mixdown, mix_pos, 
nframes);
+               read_frames = m_readSource->rb_read(mixdown, mix_pos, nframes);
        } else {
-               read_frames = m_readSource->file_read(channel, mixdown, 
mix_pos, nframes, m_song->readbuffer);
+               read_frames = m_readSource->file_read(mixdown, mix_pos, 
nframes, m_song->readbuffer);
        }
 
        if (read_frames <= 0) {
                return 0;
        }
 
+       for (int chan=0; chan<bus->get_channel_count(); ++chan) {
 
        for (int i=0; i<m_fades.size(); ++i) {
-               m_fades.at(i)->process(mixdown, read_frames);
+                       m_fades.at(i)->process(mixdown[chan], read_frames);
+               }
+               
+               m_fader->process_gain(mixdown[chan], 
(m_song->get_transport_frame() - (trackStartFrame - sourceStartFrame)), 
read_frames);
+               
+               Mixer::apply_gain_to_buffer(bus->get_buffer(chan, nframes), 
nframes, get_gain());
        }
        
-       m_fader->process_gain(mixdown, (m_song->get_transport_frame() - 
(trackStartFrame - sourceStartFrame)), read_frames);
+       
        
        return 1;
 }
@@ -619,8 +636,10 @@
 Peak* AudioClip::get_peak_for_channel( int chan ) const
 {
        PENTER2;
-       Q_ASSERT(m_readSource);
-       return m_readSource->get_peak(chan);
+       if (chan >= m_peaks.size()) {
+               return 0;
+       }
+       return m_peaks.at(chan);
 }
 
 void AudioClip::set_audio_source(ReadSource* rs)
@@ -657,6 +676,16 @@
 
        rs->set_audio_clip(this);
 
+       foreach(Peak* peak, m_peaks) {
+               peak->close();
+       }
+       
+       m_peaks.clear();
+       
+       for (int chan=0; chan<m_readSource->get_channel_count(); ++chan) {
+               m_peaks.append(new Peak(rs, chan));
+       }
+
        emit stateChanged();
 }
 
@@ -894,7 +923,7 @@
        }
 
        for (uint i=0; i<m_readSource->get_channel_count(); ++i) {
-               double amp = 
m_readSource->get_peak(i)->get_max_amplitude(sourceStartFrame, sourceEndFrame);
+               double amp = 
get_peak_for_channel(i)->get_max_amplitude(sourceStartFrame, sourceEndFrame);
                
                if (amp == 0.0f) {
                        printf("AudioClip::normalization: max amplitude == 
0\n");

Index: core/AudioClip.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- core/AudioClip.h    28 Jun 2007 15:03:56 -0000      1.55
+++ core/AudioClip.h    18 Jul 2007 13:13:05 -0000      1.56
@@ -69,7 +69,7 @@
        
        void set_audio_source(ReadSource* source);
        int init_recording(QByteArray bus);
-       int process(nframes_t nframes, audio_sample_t* channelBuffer, uint 
channel);
+       int process(nframes_t nframes);
        
        void set_track_start_frame(nframes_t newTrackFirstFrame);
        void set_name(const QString& name);
@@ -130,6 +130,7 @@
        ReadSource*             m_readSource;
        QList<WriteSource* >    writeSources;
        QList<FadeCurve* >      m_fades;
+       QList<Peak* >           m_peaks;
        AudioBus*               m_captureBus;
        FadeCurve*              fadeIn;
        FadeCurve*              fadeOut;

Index: core/AudioSource.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- core/AudioSource.cpp        27 Jun 2007 13:17:06 -0000      1.25
+++ core/AudioSource.cpp        18 Jul 2007 13:13:05 -0000      1.26
@@ -67,7 +67,6 @@
 {
        QDomElement node = doc.createElement("Source");
        node.setAttribute("channelcount", m_channelCount);
-       node.setAttribute("filecount", m_fileCount);
        node.setAttribute("origsheetid", m_origSongId);
        node.setAttribute("dir", m_dir);
        node.setAttribute("id", m_id);
@@ -87,7 +86,6 @@
        
        QDomElement e = node.toElement();
        m_channelCount = e.attribute("channelcount", "0").toInt();
-       m_fileCount = e.attribute("filecount", "0").toInt();
        m_origSongId = e.attribute("origsheetid", "0").toLongLong();
        set_dir( e.attribute("dir", "" ));
        m_id = e.attribute("id", "").toLongLong();
@@ -99,7 +97,7 @@
        // For older project files, this should properly detect if the 
        // audio source was a recording or not., in fact this should suffice
        // and the flag wasrecording would be unneeded, but oh well....
-       if (m_origSongId != 0 && m_channelCount == 2 && m_fileCount == 2) {
+       if (m_origSongId != 0) {
                m_wasRecording = true;
        }
        

Index: core/AudioSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- core/AudioSource.h  20 Jun 2007 15:27:16 -0000      1.20
+++ core/AudioSource.h  18 Jul 2007 13:13:05 -0000      1.21
@@ -38,7 +38,7 @@
        AudioSource(){};
        ~AudioSource();
        
-       virtual void process_ringbuffer(audio_sample_t* framebuffer, 
audio_sample_t* readbuffer = 0, bool seeking=false);
+       virtual void process_ringbuffer(audio_sample_t** framebuffer, 
audio_sample_t* readbuffer = 0, bool seeking=false);
 
        void set_name(const QString& name);
        void set_dir(const QString& name);
@@ -56,12 +56,10 @@
        qint64 get_orig_song_id() const {return m_origSongId;}
        int get_rate() const;
        uint get_channel_count() const;
-       uint get_file_count() const {return m_fileCount;}
        int get_bit_depth() const;
        
 protected:
-       uint            m_channelCount;
-       uint            m_fileCount;
+       int             m_channelCount;
        qint64          m_origSongId;
        QString         m_dir;
        qint64          m_id;
@@ -77,7 +75,7 @@
 
 inline uint AudioSource::get_channel_count( ) const {return m_channelCount;}
 
-inline void AudioSource::process_ringbuffer(audio_sample_t*, audio_sample_t*, 
bool) {}
+inline void AudioSource::process_ringbuffer(audio_sample_t**, audio_sample_t*, 
bool) {}
 inline qint64 AudioSource::get_id( ) const {return m_id;}
 
 #endif

Index: core/core.pro
===================================================================
RCS file: /sources/traverso/traverso/src/core/core.pro,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- core/core.pro       13 Jul 2007 07:41:03 -0000      1.32
+++ core/core.pro       18 Jul 2007 13:13:05 -0000      1.33
@@ -34,7 +34,6 @@
        InputEngine.cpp \
        Mixer.cpp \
        Peak.cpp \
-       MonoReader.cpp \
        Project.cpp \
        ProjectManager.cpp \
        ReadSource.cpp \
@@ -77,7 +76,6 @@
        InputEngine.h \
        Mixer.h \
        Peak.h \
-       MonoReader.h \
        Project.h \
        ProjectManager.h \
        ReadSource.h \
@@ -114,3 +112,7 @@
 win32{
     INCLUDEPATH += ../../3thparty/include .
 }
+SOURCES -= MonoReader.cpp
+
+HEADERS -= MonoReader.h
+

Index: core/DiskIO.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/DiskIO.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- core/DiskIO.cpp     22 Jun 2007 12:29:27 -0000      1.38
+++ core/DiskIO.cpp     18 Jul 2007 13:13:05 -0000      1.39
@@ -150,7 +150,8 @@
        m_hardDiskOverLoadCounter = 0;
        
        // TODO This is a LARGE buffer, any ideas how to make it smaller ??
-       framebuffer = new audio_sample_t[audiodevice().get_sample_rate() * 
writebuffertime];
+       framebuffer[0] = new audio_sample_t[audiodevice().get_sample_rate() * 
writebuffertime];
+       framebuffer[1] = new audio_sample_t[audiodevice().get_sample_rate() * 
writebuffertime];
        // We assume here that the audiofiles have max 2 channels, and 
readbuffer time is max 3 seconds.
        m_readbuffer = new audio_sample_t[audiodevice().get_sample_rate() * 6];
 
@@ -168,7 +169,8 @@
        PENTERDES;
        stop();
        delete cpuTimeBuffer;
-       delete [] framebuffer;
+       delete [] framebuffer[0];
+       delete [] framebuffer[1];
        delete [] m_readbuffer;
 }
 
@@ -189,7 +191,7 @@
        m_stopWork = 0;
        m_seeking = true;
 
-       foreach(MonoReader* source, m_monoReaders) {
+       foreach(ReadSource* source, m_readSources) {
                source->rb_seek_to_file_position(position);
        }
        
@@ -243,7 +245,7 @@
 int DiskIO::there_are_processable_sources( )
 {
        m_processableSources.clear();
-       QList< MonoReader * > syncSources;
+       QList<ReadSource* > syncSources;
                
        for (int i=6; i >= 0; --i) {
                
@@ -270,9 +272,9 @@
                        }
                }
                
-               for (int j=0; j<m_monoReaders.size(); ++j) {
+               for (int j=0; j<m_readSources.size(); ++j) {
 
-                       MonoReader* source = m_monoReaders.at(j);
+                       ReadSource* source = m_readSources.at(j);
                        BufferStatus* status = source->get_buffer_status();
                        
                        if (status->priority > i && source->is_active() && 
!status->needSync ) {
@@ -350,12 +352,7 @@
        QMutexLocker locker(&mutex);
 
        m_readSources.append(source);
-
-       foreach(MonoReader* prs, source->get_mono_readers()) {
-               prs->prepare_buffer();
-               m_monoReaders.append(prs);
-       }
-               
+       source->prepare_buffer();
 }
 
 /**
@@ -387,10 +384,6 @@
        QMutexLocker locker(&mutex);
        
        m_readSources.removeAll(source);
-
-       foreach(MonoReader* prs, source->get_mono_readers()) {
-               m_monoReaders.removeAll(prs);
-       }
 }
 
 

Index: core/DiskIO.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/DiskIO.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- core/DiskIO.h       22 Jun 2007 12:29:28 -0000      1.17
+++ core/DiskIO.h       18 Jul 2007 13:13:05 -0000      1.18
@@ -29,7 +29,6 @@
 #include "defines.h"
 
 class ReadSource;
-class MonoReader;
 class WriteSource;
 class AudioSource;
 class RingBuffer;
@@ -70,7 +69,6 @@
        Song*                   m_song;
        volatile size_t         m_stopWork;
        QList<ReadSource*>      m_readSources;
-       QList<MonoReader*>      m_monoReaders;
        QList<AudioSource*>     m_processableSources;
        QList<WriteSource*>     m_writeSources;
        DiskIOThread*           m_diskThread;
@@ -83,7 +81,7 @@
        trav_time_t             lastCpuReadTime;
        bool                    m_seeking;
        int                     m_hardDiskOverLoadCounter;
-       audio_sample_t*         framebuffer;
+       audio_sample_t*         framebuffer[2];
        audio_sample_t*         m_readbuffer;
 
        

Index: core/FlacAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/FlacAudioReader.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- core/FlacAudioReader.cpp    17 Jul 2007 00:49:55 -0000      1.4
+++ core/FlacAudioReader.cpp    18 Jul 2007 13:13:05 -0000      1.5
@@ -370,8 +370,6 @@
                return false;
        }
        
-       m_nextFrame = start;
-
        return true;
 }
 
@@ -398,14 +396,14 @@
                                if (!m_flac->process_single()) {
                                        PERROR("process_single() error\n");
                                        m_flac->reset();
-                                       seek(m_nextFrame);
+                                       seek(m_readPos);
                                        return -1;
                                }
                        }
                        else {
-                               PERROR("flac_state() = %d\n", 
m_flac->get_state());
+                               PERROR("flac_state() = %d\n", 
int(m_flac->get_state()));
                                m_flac->reset();
-                               seek(m_nextFrame);
+                               seek(m_readPos);
                                return -1;
                        }
 #else
@@ -418,14 +416,14 @@
                                if (!m_flac->process_single()) {
                                        PERROR("process_single() error\n");
                                        m_flac->reset();
-                                       seek(m_nextFrame);
+                                       seek(m_readPos);
                                        return -1;
                                }
                        }
                        else {
-                               PERROR("flac_state() = %d\n", 
m_flac->get_state());
+                               PERROR("flac_state() = %d\n", 
int(m_flac->get_state()));
                                m_flac->reset();
-                               seek(m_nextFrame);
+                               seek(m_readPos);
                                return -1;
                        }
 #endif
@@ -451,7 +449,7 @@
        
        // Pad end of file with 0s if necessary.  (Shouldn't be necessary...)
        int remainingSamplesRequested = sampleCount - samplesCoppied;
-       int remainingSamplesInFile = get_length() * get_num_channels() - 
(m_nextFrame * get_num_channels() + samplesCoppied);
+       int remainingSamplesInFile = get_length() * get_num_channels() - 
(m_readPos * get_num_channels() + samplesCoppied);
        if (samplesCoppied == 0 && remainingSamplesInFile > 0) {
                int padLength = (remainingSamplesRequested > 
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
                //PERROR("padLength: %d", padLength);
@@ -463,9 +461,7 @@
                samplesCoppied = sampleCount;
        }
        
-       m_nextFrame += samplesCoppied / get_num_channels();
-       
-       //printf("copied %d of %d.  nextFrame: %lu of %lu\n", samplesCoppied, 
sampleCount, m_nextFrame, get_length());
+       //printf("copied %d of %d.  nextFrame: %lu of %lu\n", samplesCoppied, 
sampleCount, m_readPos, get_length());
        
        return samplesCoppied;
 }

Index: core/MadAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/MadAudioReader.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/MadAudioReader.cpp     15 Jul 2007 19:59:35 -0000      1.5
+++ core/MadAudioReader.cpp     18 Jul 2007 13:13:06 -0000      1.6
@@ -697,8 +697,6 @@
                d->overflowSize -= frameOffset;
        }
        
-       m_nextFrame = start;
-       
        return true;
 }
 
@@ -791,7 +789,6 @@
                        memcpy(d->outputBuffer, d->overflowBuffer + 
d->overflowStart, sampleCount * sizeof(audio_sample_t));
                        d->overflowSize -= sampleCount;
                        d->overflowStart += sampleCount;
-                       m_nextFrame += sampleCount / get_num_channels();
                        return sampleCount;
                }
        }
@@ -828,7 +825,7 @@
        // is get_length() reporting incorrectly?
        // are we not outputting the last mp3-frame for some reason?
        int remainingSamplesRequested = sampleCount - samplesWritten;
-       int remainingSamplesInFile = (get_length() - m_nextFrame) * 
get_num_channels() - samplesWritten;
+       int remainingSamplesInFile = (get_length() - m_readPos) * 
get_num_channels() - samplesWritten;
        if (remainingSamplesRequested > 0 && remainingSamplesInFile > 0) {
                int padLength = (remainingSamplesRequested > 
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
                memset(d->outputPointer, 0, padLength * sizeof(audio_sample_t));
@@ -842,9 +839,8 @@
                samplesWritten = remainingSamplesInFile;
        }
        
-       //printf("at: %lu (total: %lu), request: %d (returned: %d)\n", 
m_nextFrame, m_frames, sampleCount/get_num_channels(), 
samplesWritten/get_num_channels());
+       //printf("at: %lu (total: %lu), request: %d (returned: %d)\n", 
m_readPos, m_frames, sampleCount/get_num_channels(), 
samplesWritten/get_num_channels());
        
-       m_nextFrame += samplesWritten / get_num_channels();
        return samplesWritten;
 }
 
@@ -855,9 +851,9 @@
        bool overflow = false;
        int i;
        
-       if ((nframes + ((d->outputPointer - d->outputBuffer)/get_num_channels() 
+ m_nextFrame)) > get_length()) {
-               nframes = get_length() - ((d->outputPointer - 
d->outputBuffer)/get_num_channels() + m_nextFrame);
-               //printf("!!!nframes: %lu, length: %lu, current: %lu\n", 
nframes, get_length(), (d->outputPointer - d->outputBuffer)/get_num_channels() 
+ m_nextFrame);
+       if ((nframes + ((d->outputPointer - d->outputBuffer)/get_num_channels() 
+ m_readPos)) > get_length()) {
+               nframes = get_length() - ((d->outputPointer - 
d->outputBuffer)/get_num_channels() + m_readPos);
+               //printf("!!!nframes: %lu, length: %lu, current: %lu\n", 
nframes, get_length(), (d->outputPointer - d->outputBuffer)/get_num_channels() 
+ m_readPos);
        }
        
        // now create the output

Index: core/Peak.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Peak.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- core/Peak.cpp       16 Jul 2007 01:48:11 -0000      1.36
+++ core/Peak.cpp       18 Jul 2007 13:13:06 -0000      1.37
@@ -56,7 +56,7 @@
        
        ReadSource* rs = qobject_cast<ReadSource*>(source);
        if (rs) {
-               m_source = resources_manager()->get_readsource(rs->get_id(), 
true);
+               m_source = resources_manager()->get_readsource(rs->get_id());
        }
        
        if (source->get_channel_count() > 1) {
@@ -299,27 +299,23 @@
        // Micro view mode
        } else {
                nframes_t toRead = pixelcount * zoomStep[zoomLevel];
-               audio_sample_t buf[toRead];
-               audio_sample_t readbuffer[toRead*2];
-               
-               nframes_t readFrames = 0;
-               nframes_t totalReadFrames = 0;
                
-               do {
-                       readFrames = m_source->file_read(m_channel, buf + 
totalReadFrames, startPos + totalReadFrames, toRead - totalReadFrames, 
readbuffer);
-                       if (readFrames <= 0) {
-                               PERROR("readFrames < 0");
-                               break;
+               // Maybe they can be created on the stack for better 
performance ?
+               audio_sample_t* audiobuf[m_source->get_channel_count()];
+               for (uint chan=0; chan < m_source->get_channel_count(); ++chan) 
{
+                       audiobuf[chan] = new audio_sample_t[toRead];
                        }
-                       totalReadFrames += readFrames;
-               } while (totalReadFrames < toRead);
+               audio_sample_t readbuffer[toRead*2];
+               
+               nframes_t readFrames = m_source->file_read(audiobuf, startPos, 
toRead, readbuffer);
                
-               if ( totalReadFrames != toRead) {
-                       PWARN("Unable to read nframes %d (only %d available)", 
toRead, totalReadFrames);
-                       if (totalReadFrames == 0) {
+               if (readFrames == 0) {
                                return NO_PEAKDATA_FOUND;
                        }
-                       pixelcount = totalReadFrames / zoomStep[zoomLevel];
+               
+               if ( readFrames != toRead) {
+                       PWARN("Unable to read nframes %d (only %d available)", 
toRead, readFrames);
+                       pixelcount = readFrames / zoomStep[zoomLevel];
                }
 
                int count = 0;
@@ -333,7 +329,7 @@
                        for(int i=0; i < zoomStep[zoomLevel]; i++) {
                                if (pos > readFrames)
                                        break;
-                               sample = buf[pos];
+                               sample = audiobuf[m_channel][pos];
                                if (sample > valueMax)
                                        valueMax = sample;
                                if (sample < valueMin)
@@ -356,6 +352,11 @@
                int processtime = (int) (get_microseconds() - starttime);
                printf("Process time: %d useconds\n\n", processtime);
 #endif
+               
+               for (uint chan=0; chan < m_source->get_channel_count(); ++chan) 
{
+                       delete audiobuf[chan];
+               }
+               
                return count;
        }
 
@@ -604,7 +605,10 @@
                }
        }
 
-       audio_sample_t* buf = new audio_sample_t[bufferSize];
+       audio_sample_t* buffer[m_source->get_channel_count()];
+       for (uint chan=0; chan<m_source->get_channel_count(); ++chan) {
+               buffer[chan] = new audio_sample_t[bufferSize];
+       }
        audio_sample_t* readbuffer = new audio_sample_t[bufferSize * 2];
        
        do {
@@ -613,12 +617,12 @@
                        goto out;
                }
                
-               readFrames = m_source->file_read(m_channel, buf, 
totalReadFrames, bufferSize, readbuffer);
+               readFrames = m_source->file_read(buffer, totalReadFrames, 
bufferSize, readbuffer);
                if (readFrames <= 0) {
                        PERROR("readFrames < 0 during peak building");
                        break;
                }
-               process(buf, readFrames);
+               process(buffer[m_channel], readFrames);
                totalReadFrames += readFrames;
                p = (int) ((float)totalReadFrames / 
((float)m_source->get_nframes() / 100.0));
                
@@ -638,7 +642,9 @@
        ret = 1;
        
 out:
-       delete [] buf;
+       for (uint chan=0; chan<m_source->get_channel_count(); ++chan) {
+               delete buffer[chan];
+       }
        delete [] readbuffer;
         
        return ret;
@@ -666,9 +672,9 @@
                int toRead = (int) ((startpos * NORMALIZE_CHUNK_SIZE) - 
startframe);
                
                audio_sample_t buf[toRead];
-               int read = m_source->file_read(m_channel, buf, startframe, 
toRead, readbuffer);
+//             int read = m_source->file_read(m_channel, buf, startframe, 
toRead, readbuffer);
                
-               maxamp = Mixer::compute_peak(buf, read, maxamp);
+//             maxamp = Mixer::compute_peak(buf, read, maxamp);
        }
        
        
@@ -678,7 +684,8 @@
        int endpos = (int) f;
        int toRead = (int) ((f - (endframe / NORMALIZE_CHUNK_SIZE)) * 
NORMALIZE_CHUNK_SIZE);
        audio_sample_t buf[toRead];
-       int read = m_source->file_read(m_channel, buf, endframe - toRead, 
toRead, readbuffer);
+//     int read = m_source->file_read(m_channel, buf, endframe - toRead, 
toRead, readbuffer);
+       int read = 0;//m_source->file_read(m_channel, buf, endframe - toRead, 
toRead, readbuffer);
        maxamp = Mixer::compute_peak(buf, read, maxamp);
        
        // Now that we have covered both boundary situations,

Index: core/ReadSource.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ReadSource.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- core/ReadSource.cpp 15 Jul 2007 05:09:47 -0000      1.39
+++ core/ReadSource.cpp 18 Jul 2007 13:13:06 -0000      1.40
@@ -29,7 +29,10 @@
 #include "AudioClip.h"
 #include "DiskIO.h"
 #include "Utils.h"
+#include "Song.h"
+#include "AudioDevice.h"
 #include <QFile>
+#include "Config.h"
 
 // Always put me below _all_ includes, this is needed
 // in case we run with memory leak detection enabled!
@@ -44,10 +47,9 @@
 // This constructor is called for existing (recorded/imported) audio sources
 ReadSource::ReadSource(const QDomNode node)
        : AudioSource(node)
-       , m_refcount(0)
-       , m_error(0)
-       , m_clip(0)
 {
+       private_init();
+       
        Project* project = pm().get_project();
        
        // Check if the audiofile exists in our project audiosources dir
@@ -60,41 +62,35 @@
        }
        
        m_silent = (m_channelCount == 0);
-       m_forPeaks = false;
 }      
 
 // constructor for file import
 ReadSource::ReadSource(const QString& dir, const QString& name)
        : AudioSource(dir, name)
-       , m_refcount(0)
-       , m_error(0)
-       , m_clip(0)
 {
-       AbstractAudioReader* reader = 
AbstractAudioReader::create_audio_reader(m_fileName);
+       private_init();
 
-       m_channelCount = 0;
+       AbstractAudioReader* reader = 
AbstractAudioReader::create_audio_reader(m_fileName);
        
        if (reader) {
                m_channelCount = reader->get_num_channels();
                delete reader;
+       } else {
+               m_channelCount = 0;
        }
 
-       m_fileCount = 1;
        m_silent = false;
-       m_forPeaks = false;
 }
 
 
 // Constructor for recorded audio.
 ReadSource::ReadSource(const QString& dir, const QString& name, int 
channelCount)
        : AudioSource(dir, name)
-       , m_refcount(0)
-       , m_error(0)
-       , m_clip(0)
 {
-       m_channelCount = m_fileCount = channelCount;
+       private_init();
+       
+       m_channelCount = channelCount;
        m_silent = false;
-       m_forPeaks = false;
        m_name = name  + "-" + QString::number(m_id);
        m_fileName = m_dir + m_name;
        m_length = 0;
@@ -107,28 +103,35 @@
 // Constructor for silent clips
 ReadSource::ReadSource()
        : AudioSource("", tr("Silence"))
-       , m_refcount(0)
-       , m_error(0)
-       , m_clip(0)
 {
+       private_init();
+       
        m_channelCount = 0;
-       m_fileCount = 0;
        m_silent = true;
 }
 
 
+void ReadSource::private_init()
+{
+       m_refcount = 0;
+       m_error = 0;
+       m_clip = 0;
+       m_audioReader = 0;
+}
+
+
 ReadSource::~ReadSource()
 {
        PENTERDES;
-       foreach(MonoReader* source, m_sources) {
-               delete source;
+       for(int i=0; i<m_buffers.size(); ++i) {
+               delete m_buffers.at(i);
        }
-}
 
+       if (m_audioReader) {
+               delete m_audioReader;
+       }
 
-void ReadSource::set_is_for_peaks(bool forPeaks)
-{
-       m_forPeaks = forPeaks;
+       delete m_bufferstatus;
 }
 
 
@@ -156,80 +159,99 @@
        }
        
        
-       QString fileName = m_dir + m_name;
+       m_rbFileReadPos = 0;
+       m_rbRelativeFileReadPos = 0;
+       m_rbReady = 0;
+       m_needSync = 0;
+       m_syncInProgress = 0;
+       m_bufferUnderRunDetected = m_wasActivated = 0;
        
-       if (m_wasRecording) {
-               if (m_channelCount == 1 && m_fileCount == 1) {
-                       if ( (m_error = add_mono_reader(1, 0, fileName + "-ch" 
+ QByteArray::number(0) + ".wav")) < 0) {
-                               return m_error;
-                       }
-               } else if (m_channelCount == 2 && m_fileCount == 2) {
-                       if (((m_error = add_mono_reader(1, 0, fileName + "-ch" 
+ QByteArray::number(0) + ".wav") < 0)) || 
-                                 ((m_error = add_mono_reader(1, 1, fileName + 
"-ch" + QByteArray::number(1) + ".wav")) < 0)) {
-                               return m_error;
+       bool useResampling = config().get_property("Conversion", 
"DynamicResampling", false).toBool();
+       
+       if (useResampling) {
+               int converter_type;
+               converter_type = config().get_property("Conversion", 
"RTResamplingConverterType", 2).toInt();
+               // There should be another config option for ConverterType to 
use for export (higher quality)
+               //converter_type = config().get_property("Conversion", 
"ExportResamplingConverterType", 0).toInt();
+               m_audioReader = 
AbstractAudioReader::create_resampled_audio_reader(m_fileName, converter_type);
                        }
-               } else {
-                       PERROR("WasRecording section: Unsupported combination 
of channelcount/filecount (%d/%d)", m_channelCount, m_fileCount);
-                       return (m_error = CHANNELCOUNT_FILECOUNT_MISMATCH);
+       else {
+               m_audioReader = 
AbstractAudioReader::create_audio_reader(m_fileName);
                }
-       } else {
        
-               if (m_channelCount == 1 && m_fileCount == 1) {
-                       if ((m_error = add_mono_reader(1, 0, fileName)) < 0) {
-                               return m_error;
-                       }
-               } else if (m_channelCount == 2 && m_fileCount == 1) {
-                       if (((m_error = add_mono_reader(2, 0, fileName)) < 0) 
|| ((m_error = add_mono_reader(2, 1, fileName)) < 0)) {
-                               return m_error;
+       if (m_audioReader == 0) {
+               return COULD_NOT_OPEN_FILE;
                        }
-               } else {
-                       PERROR("Unsupported combination of 
channelcount/filecount (%d/%d)", m_channelCount, m_fileCount);
-                       return (m_error = CHANNELCOUNT_FILECOUNT_MISMATCH);
+       
+       if (m_channelCount > m_audioReader->get_num_channels()) {
+               PERROR("ReadAudioSource: file only contains %d channels; %d is 
invalid as a channel number", m_audioReader->get_num_channels(), 
m_channelCount);
+               delete m_audioReader;
+               m_audioReader = 0;
+               return INVALID_CHANNEL_COUNT;
                }
+
+       if (m_audioReader->get_num_channels() == 0) {
+               PERROR("ReadAudioSource: not a valid channel count: %d", 
m_audioReader->get_num_channels());
+               delete m_audioReader;
+               m_audioReader = 0;
+               return ZERO_CHANNELS;
        }
        
+       m_length = m_audioReader->get_length();
+       m_rate = m_audioReader->get_rate();
+       
+       m_bufferstatus = new BufferStatus;
        
        return 1;
 }
 
-int ReadSource::add_mono_reader(int sourceChannelCount, int channelNumber, 
const QString& fileName)
-{
-       int result = 1;
-       
-       MonoReader* source = new MonoReader(this, sourceChannelCount, 
channelNumber, fileName);
        
-       if ( (result = source->init(m_forPeaks)) > 0) {
-               m_sources.append(source);
-       } else {
-               PERROR("Failed to initialize a MonoReader (%s)", 
QS_C(fileName));
-               delete source;
+int ReadSource::file_read(audio_sample_t** dst, nframes_t start, nframes_t 
cnt, audio_sample_t* readbuffer) const
+{
+#if defined (profile)
+       trav_time_t starttime = get_microseconds();
+#endif
+       if (m_audioReader->get_num_channels() == 1) {
+               int result = m_audioReader->read_from(dst[0], start, cnt);
+#if defined (profile)
+               int processtime = (int) (get_microseconds() - starttime);
+               if (processtime > 40000)
+                       printf("Process time for %s: %d useconds\n\n", 
QS_C(m_fileName), processtime);
+#endif
                return result;
        }
        
-       return result;
-}
+       float *ptr;
+       uint real_cnt = cnt * m_audioReader->get_num_channels();
 
-int ReadSource::file_read (int channel, audio_sample_t* dst, nframes_t start, 
nframes_t cnt, audio_sample_t* readbuffer) const
-{
-       Q_ASSERT(channel < m_sources.size());
-       return m_sources.at(channel)->file_read(dst, start, cnt, readbuffer);
-}
+       // The readbuffer 'assumes' that there is max 2 channels...
+       Q_ASSERT(m_audioReader->get_num_channels() <= 2);
 
+       int nread = m_audioReader->read_from(readbuffer, start, real_cnt);
+#if defined (profile)
+       int processtime = (int) (get_microseconds() - starttime);
+       if (processtime > 40000)
+               printf("Process time for %s: %d useconds\n\n", 
QS_C(m_fileName), processtime);
+#endif
+       ptr = readbuffer;
+       nread /= m_audioReader->get_num_channels();
 
-int ReadSource::rb_read(int channel, audio_sample_t* dst, nframes_t start, 
nframes_t cnt)
-{
-       Q_ASSERT(channel < m_sources.size());
-       return m_sources.at(channel)->rb_read(dst, start, cnt);
-
-}
+       /* stride through the interleaved data */
+       // FIXME: deinterlace in AudioReader Classes instead of here
 
+       for (int32_t n = 0; n < nread; ++n) {
+               dst[0][n] = *ptr;
+               ptr += m_audioReader->get_num_channels();
+       }
 
-void ReadSource::set_active(bool active)
-{
-       PENTER2;
-       foreach(MonoReader* source, m_sources) {
-               source->set_active(active);
+       ptr = readbuffer+1;
+       for (int32_t n = 0; n < nread; ++n) {
+               dst[1][n] = *ptr;
+               ptr += m_audioReader->get_num_channels();
        }
+
+
+       return nread;
 }
 
 
@@ -243,22 +265,11 @@
        return source;
 }
 
-
 void ReadSource::set_audio_clip( AudioClip * clip )
 {
        PENTER;
        Q_ASSERT(clip);
        m_clip = clip;
-       foreach(MonoReader* source, m_sources) {
-               source->set_audio_clip(clip);
-       }
-}
-
-
-Peak * ReadSource::get_peak( int channel )
-{
-       Q_ASSERT(channel < m_sources.size());
-       return m_sources.at(channel)->get_peak();
 }
 
 nframes_t ReadSource::get_nframes( ) const
@@ -294,4 +305,250 @@
        return 1;
 }
 
+
+
+
+int ReadSource::rb_read(audio_sample_t** dst, nframes_t start, nframes_t count)
+{
+
+       if ( ! m_rbReady ) {
+//             printf("ringbuffer not ready\n");
+               return 0;
+       }
+
+       if (start != m_rbRelativeFileReadPos) {
+               int available = m_buffers.at(0)->read_space();
+//             printf("start %d, m_rbFileReadPos %d\n", start, 
m_rbRelativeFileReadPos);
+               if ( (start > m_rbRelativeFileReadPos) && 
(m_rbRelativeFileReadPos + available) > (start + count)) {
+                       int advance = start - m_rbRelativeFileReadPos;
+                       if (available < advance) {
+                               printf("available < advance !!!!!!!\n");
+                       }
+                       for (int i=m_buffers.size()-1; i>=0; --i) {
+                               m_buffers.at(i)->increment_read_ptr(advance);
+                       }
+                       m_rbRelativeFileReadPos += advance;
+               } else {
+                       start_resync(start + (m_clip->get_track_start_frame() + 
m_clip->get_source_start_frame()));
+                       return 0;
+               }
+       }
+
+       nframes_t readcount = 0;
+       
+       for (int chan=0; chan<m_channelCount; ++chan) {
+               
+               readcount = m_buffers.at(chan)->read(dst[chan], count);
+
+               if (readcount != count) {
+               // Hmm, not sure what to do in this case....
+               }
+               
+       }
+
+       m_rbRelativeFileReadPos += readcount;
+       
+       return readcount;
+}
+
+
+int ReadSource::rb_file_read(audio_sample_t** dst, nframes_t cnt, 
audio_sample_t* readbuffer )
+{
+       int readFrames = file_read(dst, m_rbFileReadPos, cnt, readbuffer);
+       m_rbFileReadPos += readFrames;
+
+       return readFrames;
+}
+
+
+void ReadSource::rb_seek_to_file_position( nframes_t position )
+{
+       Q_ASSERT(m_clip);
+       
+//     printf("rb_seek_to_file_position:: seeking to %d\n", position);
+       
+       // calculate position relative to the file!
+       long fileposition = position - (m_clip->get_track_start_frame() + 
m_clip->get_source_start_frame());
+       
+       if ((long)m_rbFileReadPos == fileposition) {
+//             printf("ringbuffer allready at position %d\n", position);
+               return;
+       }
+
+       // check if the clip's start position is within the range
+       // if not, fill the buffer from the earliest point this clip
+       // will come into play.
+       if (fileposition < 0) {
+//             printf("not seeking to %ld, but too %d\n\n", 
fileposition,m_clip->get_source_start_frame()); 
+               // Song's start from 0, this makes a period start from
+               // 0 - 1023 for example, the nframes is 1024!
+               // Setting a songs new position is on 1024, and NOT 
+               // 1023.. Hmm, something isn't correct here, but at least 
substract 1
+               // to make this thing work!
+               fileposition = m_clip->get_source_start_frame() - 1;
+       }
+       
+//     printf("rb_seek_to_file_position:: seeking to relative pos: %d\n", 
fileposition);
+       for (int i=0; i<m_buffers.size(); ++i) {
+               m_buffers.at(i)->reset();
+       }
+       m_rbFileReadPos = fileposition;
+       m_rbRelativeFileReadPos = fileposition;
+}
+
+void ReadSource::process_ringbuffer(audio_sample_t** framebuffer, 
audio_sample_t* readbuffer, bool seeking)
+{
+       // Do nothing if we passed the lenght of the AudioFile.
+       if (m_rbFileReadPos >= m_length) {
+//             printf("returning, m_rbFileReadPos > m_length! (%d >  %d)\n", 
m_rbFileReadPos, m_source->m_length);
+               if (m_syncInProgress) {
+                       finish_resync();
+               }
+               return;
+       }
+       
+       // Calculate the number of samples we can write into the buffer
+       int writeSpace = m_buffers.at(0)->write_space();
+
+       // The amount of chunks which can be 'read'
+       int chunkCount = (int)(writeSpace / m_chunkSize);
+       
+       int toRead = m_chunkSize;
+       
+       if (seeking) {
+               toRead = writeSpace;
+//             printf("doing a full seek buffer fill\n");
+       } else if (m_syncInProgress) {
+               // Currently, we fill the buffer completely.
+               // For some reason, filling it with 1/4 at a time
+               // doesn't fill it consitently, and thus giving audible 
artifacts.
+               /*              toRead = m_chunkSize * 2;*/
+               toRead = writeSpace;
+       } else if (chunkCount == 0) {
+               // If we are nearing the end of the source file it could be 
possible
+               // we only need to read the last samples which is smaller in 
size then 
+               // chunksize. If so, set toRead to m_source->m_length - 
rbFileReasPos
+               if ( (int) (m_length - m_rbFileReadPos) <= m_chunkSize) {
+                       toRead = m_length - m_rbFileReadPos;
+               } else {
+                       printf("MonoReader:: chunkCount == 0, but not at end of 
file, this shouldn't happen!!\n");
+                       return;
+               }
+       }
+       
+       // Read in the samples from source
+       nframes_t toWrite = rb_file_read(framebuffer, toRead, readbuffer);
+
+       // and write it to the ringbuffer
+       for (int i=m_buffers.size()-1; i>=0; --i) {
+               m_buffers.at(i)->write(framebuffer[i], toWrite);
+       }
+}
+
+
+void ReadSource::recover_from_buffer_underrun(nframes_t position)
+{
+//     printf("buffer underrun detected!\n");
+       m_bufferUnderRunDetected = 1;
+       start_resync(position);
+}
+
+void ReadSource::start_resync( nframes_t position )
+{
+//     printf("starting resync!\n");
+       m_syncPos = position;
+       m_rbReady = 0;
+       m_needSync = 1;
+}
+
+void ReadSource::finish_resync()
+{
+//     printf("sync finished\n");
+       m_needSync = 0;
+       m_bufferUnderRunDetected = 0;
+       m_rbReady = 1;
+       m_syncInProgress = 0;
+}
+
+void ReadSource::sync(audio_sample_t** framebuffer, audio_sample_t* readbuffer)
+{
+       PENTER2;
+       if (!m_needSync) {
+               return;
+       }
+       
+       if (!m_syncInProgress) {
+               rb_seek_to_file_position(m_syncPos);
+               m_syncInProgress = 1;
+       }
+       
+       // Currently, we fill the buffer completely.
+       // For some reason, filling it with 1/4 at a time
+       // doesn't fill it consitently, and thus giving audible artifacts.
+       process_ringbuffer(framebuffer, readbuffer);
+       
+       if (m_buffers.at(0)->write_space() == 0) {
+               finish_resync();
+       }
+       
+//         PWARN("Resyncing ringbuffer finished");
+}
+
+
+
+void ReadSource::prepare_buffer( )
+{
+       PENTER;
+       
+       Q_ASSERT(m_clip);
+
+       float size = config().get_property("Hardware", "readbuffersize", 
1.0).toDouble();
+
+       m_bufferSize = (int) (size * audiodevice().get_sample_rate());
+
+       m_chunkSize = m_bufferSize / DiskIO::bufferdividefactor;
+
+       for (int i=0; i<m_channelCount; ++i) {
+               m_buffers.append(new RingBufferNPT<float>(m_bufferSize));
+       }
+
+       start_resync(m_clip->get_song()->get_working_frame());
+}
+
+BufferStatus* ReadSource::get_buffer_status()
+{
+       int freespace = m_buffers.at(0)->write_space();
+
+       if (m_rbFileReadPos >= m_length) {
+               m_bufferstatus->fillStatus =  100;
+               freespace = 0;
+       } else {
+               m_bufferstatus->fillStatus = (int) (((float)freespace / 
m_bufferSize) * 100);
+       }
+       
+       m_bufferstatus->bufferUnderRun = m_bufferUnderRunDetected;
+       m_bufferstatus->needSync = m_needSync;
+
+       m_bufferstatus->priority = (int) (freespace / m_chunkSize);
+       
+       return m_bufferstatus;
+}
+
+void ReadSource::set_active(bool active)
+{
+       if (m_active == active)
+               return;
+
+       if (active) {
+               m_active = 1;
+//             m_wasActivated = 1;
+//             printf("setting private readsource %s to active\n", 
QS_C(m_fileName));
+       } else {
+//             printf("setting private readsource %s to IN-active\n", 
QS_C(m_fileName));
+               m_active = 0;
+       }
+}
+
+
 //eof
+

Index: core/ReadSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ReadSource.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- core/ReadSource.h   15 Jul 2007 05:09:47 -0000      1.29
+++ core/ReadSource.h   18 Jul 2007 13:13:06 -0000      1.30
@@ -23,10 +23,12 @@
 #define READSOURCE_H
 
 #include "AudioSource.h"
+#include "RingBufferNPT.h"
+#include "defines.h"
 
+class AbstractAudioReader;
 class AudioClip;
-class Peak;
-class MonoReader;
+struct BufferStatus;
 
 class ReadSource : public AudioSource
 {
@@ -47,37 +49,64 @@
        
        ReadSource* deep_copy();
 
-       int rb_read(int channel, audio_sample_t* dst, nframes_t start, 
nframes_t cnt);
-       int file_read(int channel, audio_sample_t* dst, nframes_t start, 
nframes_t cnt, audio_sample_t* readbuffer) const;
+       int rb_read(audio_sample_t** dest, nframes_t start, nframes_t cnt);
+       void rb_seek_to_file_position(nframes_t position);
+       
+       int file_read(audio_sample_t** dst, nframes_t start, nframes_t cnt, 
audio_sample_t* readbuffer) const;
 
        int init();
        int get_error() const {return m_error;}
        int set_file(const QString& filename);
        void set_active(bool active);
-       void set_is_for_peaks(bool forPeaks);
        
        void set_audio_clip(AudioClip* clip);
-       Peak* get_peak(int channel);
        nframes_t get_nframes() const;
        
-       QList<MonoReader*> get_mono_readers() const {return m_sources;}
+       void sync(audio_sample_t** framebuffer, audio_sample_t* readbuffer);
+       void process_ringbuffer(audio_sample_t** framebuffer, audio_sample_t* 
readbuffer, bool seeking=false);
+       void prepare_buffer();
+       size_t is_active() const;
+       BufferStatus* get_buffer_status();
 
 private:
-       QList<MonoReader*> m_sources;
+       QList<RingBufferNPT<float>*> m_buffers;
+       AbstractAudioReader*    m_audioReader;
+       AudioClip*              m_clip;
        int     m_refcount;
        int     m_error;
-       AudioClip* m_clip;
        bool    m_silent;
-       bool    m_forPeaks;
+       uint                    m_bufferSize;
+       int                     m_chunkSize;
+       nframes_t               m_rbFileReadPos;
+       nframes_t               m_rbRelativeFileReadPos;
+       volatile size_t         m_syncPos;
+       volatile size_t         m_rbReady;
+       volatile size_t         m_needSync;
+       volatile size_t         m_active;
+       volatile size_t         m_wasActivated;
+       volatile size_t         m_bufferUnderRunDetected;
+       bool                    m_syncInProgress;
+       
+       BufferStatus*   m_bufferstatus;
        
        int ref() { return m_refcount++;}
-       int add_mono_reader(int channel, int channelNumber, const QString& 
fileName);
        
-       friend class MonoReader;
+       void private_init();
+       void start_resync(nframes_t position);
+       void finish_resync();
+       void recover_from_buffer_underrun(nframes_t position);
+       int rb_file_read(audio_sample_t** dst, nframes_t cnt, audio_sample_t* 
readbuffer);
+
        friend class ResourcesManager;
        
 signals:
        void stateChanged();
 };
 
+
+inline size_t ReadSource::is_active() const
+{
+       return m_active;
+}
+
 #endif

Index: core/ResampleAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/ResampleAudioReader.cpp        15 Jul 2007 05:14:47 -0000      1.6
+++ core/ResampleAudioReader.cpp        18 Jul 2007 13:13:06 -0000      1.7
@@ -36,8 +36,8 @@
        m_fileBuffer = 0;
        m_fileBufferLength = 0;
        
-       m_realReader = AbstractAudioReader::create_audio_reader(filename);
-       if (!m_realReader) {
+       m_reader = AbstractAudioReader::create_audio_reader(filename);
+       if (!m_reader) {
                PERROR("ResampleAudioReader: couldn't create AudioReader");
                return;
        }
@@ -53,8 +53,8 @@
                src_delete(m_srcState);
        }
        
-       if (m_realReader) {
-               delete m_realReader;
+       if (m_reader) {
+               delete m_reader;
        }
        
        if (m_fileBuffer) {
@@ -70,11 +70,11 @@
        }
        
        int error;
-       m_srcState = src_new (converter_type, m_realReader->get_num_channels(), 
&error);
+       m_srcState = src_new (converter_type, m_reader->get_num_channels(), 
&error);
        if (!m_srcState) {
                PERROR("ResampleAudioReader: couldn't create libSampleRate 
SRC_STATE");
-               delete m_realReader;
-               m_realReader = 0;
+               delete m_reader;
+               m_reader = 0;
        }
        
        reset();
@@ -93,8 +93,8 @@
 // Get from child AudioReader
 int ResampleAudioReader::get_num_channels()
 {
-       if (m_realReader) {
-               return m_realReader->get_num_channels();
+       if (m_reader) {
+               return m_reader->get_num_channels();
        }
        return 0;
 }
@@ -103,20 +103,23 @@
 // Get from child AudioReader, convert from file's frames to song's frames
 nframes_t ResampleAudioReader::get_length()
 {
-       if (m_realReader) {
-               if (audiodevice().get_sample_rate() == 
m_realReader->get_rate()) {
-                       return m_realReader->get_length();
+       if (m_reader) {
+               if (audiodevice().get_sample_rate() == 
(uint)m_reader->get_rate()) {
+                       return m_reader->get_length();
                }
-               return file_to_song_frame(m_realReader->get_length());
+               return file_to_song_frame(m_reader->get_length());
        }
        return 0;
 }
 
 
 // Always the rate of the audio device
+// Remon @ Ben: why is that? imo it should just return the real rate, how else
+// is anything gonna to know what the 'real' rate of an audiofile is ?
 int ResampleAudioReader::get_rate()
 {
-       return audiodevice().get_sample_rate();
+       return m_reader->get_rate();
+//     return audiodevice().get_sample_rate();
 }
 
 
@@ -124,17 +127,15 @@
 // otherwise convert and seek
 bool ResampleAudioReader::seek(nframes_t start)
 {
-       Q_ASSERT(m_realReader);
+       Q_ASSERT(m_reader);
        
-       if (audiodevice().get_sample_rate() == m_realReader->get_rate()) {
-               return m_realReader->seek(start);
+       if (audiodevice().get_sample_rate() == (uint)m_reader->get_rate()) {
+               return m_reader->seek(start);
        }
        
        reset();
        
-       m_nextFrame = start;
-       
-       return m_realReader->seek(song_to_file_frame(start));
+       return m_reader->seek(song_to_file_frame(start));
 }
 
 
@@ -143,7 +144,7 @@
 int ResampleAudioReader::read(audio_sample_t* dst, int sampleCount)
 {
        uint samplesRead;
-       Q_ASSERT(m_realReader);
+       Q_ASSERT(m_reader);
        
        /////////////////////////////////
        // Ben says: FIXME: Add an overflow buffer, and grab more samples at a 
time, saving the extra to the overflow.
@@ -151,9 +152,8 @@
        /////////////////////////////////
        
        // pass through if not changing sampleRate.
-       if (audiodevice().get_sample_rate() == m_realReader->get_rate()) {
-               samplesRead = m_realReader->read(dst, sampleCount);
-               m_nextFrame += samplesRead / get_num_channels();
+       if (audiodevice().get_sample_rate() == (uint)m_reader->get_rate()) {
+               samplesRead = m_reader->read(dst, sampleCount);
                return samplesRead;
        }
        
@@ -164,7 +164,7 @@
        }
        
        // make sure that the reusable m_fileBuffer is big enough for this read
-       if (m_fileBufferLength < fileCnt) {
+       if ((uint)m_fileBufferLength < fileCnt) {
                if (m_fileBuffer) {
                        delete m_fileBuffer;
                }
@@ -172,7 +172,7 @@
                m_fileBufferLength = fileCnt;
        }
        
-       samplesRead = m_realReader->read(m_fileBuffer, fileCnt);
+       samplesRead = m_reader->read(m_fileBuffer, fileCnt);
        
        //printf("Resampler: sampleCount %lu, fileCnt %lu, returned %lu\n", 
sampleCount/get_num_channels(), fileCnt/get_num_channels(), 
samplesRead/get_num_channels());
        
@@ -181,7 +181,7 @@
        m_srcData.input_frames = samplesRead / get_num_channels();
        m_srcData.data_out = dst;
        m_srcData.output_frames = sampleCount / get_num_channels();
-       m_srcData.src_ratio = (double) audiodevice().get_sample_rate() / 
m_realReader->get_rate();
+       m_srcData.src_ratio = (double) audiodevice().get_sample_rate() / 
m_reader->get_rate();
        src_set_ratio(m_srcState, m_srcData.src_ratio);
        
        if (src_process(m_srcState, &m_srcData)) {
@@ -193,7 +193,7 @@
        
        // Pad end of file with 0s if necessary
        int remainingSamplesRequested = sampleCount - samplesRead;
-       int remainingSamplesInFile = (get_length() - m_nextFrame - 
m_srcData.output_frames_gen) * get_num_channels();
+       int remainingSamplesInFile = (get_length() - m_readPos - 
m_srcData.output_frames_gen) * get_num_channels();
        
        if (samplesRead == 0 && remainingSamplesRequested > 0 && 
remainingSamplesInFile > 0) {
                int padLength = (remainingSamplesRequested > 
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
@@ -203,12 +203,11 @@
        }       
        
        // Truncate so we don't return too many samples
-       if (samplesRead > remainingSamplesInFile) {
+       if (samplesRead > (uint)remainingSamplesInFile) {
                printf("Resampler: truncating: %d\n", samplesRead - 
remainingSamplesInFile);
                samplesRead = remainingSamplesInFile;
        }
        
-       m_nextFrame += samplesRead / get_num_channels();
        
        //printf("Resampler: req: %d, got: %d\n", sampleCount, samplesRead);
        return samplesRead;
@@ -217,16 +216,16 @@
 
 nframes_t ResampleAudioReader::song_to_file_frame(nframes_t frame)
 {
-       Q_ASSERT(m_realReader);
+       Q_ASSERT(m_reader);
        
-       return (nframes_t)(frame * (((double) m_realReader->get_rate()) / 
audiodevice().get_sample_rate()));
+       return (nframes_t)(frame * (((double) m_reader->get_rate()) / 
audiodevice().get_sample_rate()));
 }
 
 
 nframes_t ResampleAudioReader::file_to_song_frame(nframes_t frame)
 {
-       Q_ASSERT(m_realReader);
+       Q_ASSERT(m_reader);
        
-       return (nframes_t)(frame * (((double) audiodevice().get_sample_rate()) 
/ m_realReader->get_rate()));
+       return (nframes_t)(frame * (((double) audiodevice().get_sample_rate()) 
/ m_reader->get_rate()));
 }
 

Index: core/ResampleAudioReader.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/ResampleAudioReader.h  15 Jul 2007 05:14:48 -0000      1.5
+++ core/ResampleAudioReader.h  18 Jul 2007 13:13:06 -0000      1.6
@@ -28,6 +28,7 @@
 
 class ResampleAudioReader : public AbstractAudioReader
 {
+
 public:
        ResampleAudioReader(QString filename, int converter_type);
        ~ResampleAudioReader();
@@ -38,8 +39,6 @@
        bool seek(nframes_t start);
        int read(audio_sample_t* dst, int sampleCount);
 
-       // Shouldn't ever actually get called
-       static bool can_decode(QString filename) {return false;}
 
 protected:
        void init(int converter_type);
@@ -48,7 +47,7 @@
        nframes_t song_to_file_frame(nframes_t frame);
        nframes_t file_to_song_frame(nframes_t frame);
 
-       AbstractAudioReader*    m_realReader;
+       AbstractAudioReader*    m_reader;
        SRC_STATE*      m_srcState;
        SRC_DATA        m_srcData;
        audio_sample_t  *m_fileBuffer;

Index: core/ResourcesManager.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResourcesManager.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- core/ResourcesManager.cpp   15 Jul 2007 05:09:47 -0000      1.20
+++ core/ResourcesManager.cpp   18 Jul 2007 13:13:07 -0000      1.21
@@ -211,7 +211,7 @@
 }
 
 
-ReadSource * ResourcesManager::get_readsource( qint64 id, bool forPeaks )
+ReadSource * ResourcesManager::get_readsource(qint64 id)
 {
        SourceData* data = m_sources.value(id);
        
@@ -230,8 +230,6 @@
                source->ref();
        }
        
-       source->set_is_for_peaks(forPeaks);
-       
        if ( source->init() < 0) {
                info().warning( tr("ResourcesManager::  Failed to initialize 
ReadSource %1")
                                .arg(source->get_filename()));
@@ -338,8 +336,9 @@
        SourceData* sourcedata = m_sources.value(clip->get_readsource_id());
        if (!sourcedata) {
                PERROR("Source %lld not in database", 
clip->get_readsource_id());
-       }
+       } else {
        sourcedata->clipCount--;
+       }
        
        emit clipRemoved(clip);
 }

Index: core/ResourcesManager.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResourcesManager.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- core/ResourcesManager.h     15 Jul 2007 05:09:47 -0000      1.12
+++ core/ResourcesManager.h     18 Jul 2007 13:13:07 -0000      1.13
@@ -63,7 +63,7 @@
        bool is_clip_in_use(qint64) const;
        bool is_source_in_use(qint64 id) const;
 
-       ReadSource* get_readsource(qint64 id, bool forPeaks = false);
+       ReadSource* get_readsource(qint64 id);
        
        
        QList<ReadSource*> get_all_audio_sources() const;

Index: core/SFAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/SFAudioReader.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- core/SFAudioReader.cpp      8 Jul 2007 23:16:56 -0000       1.3
+++ core/SFAudioReader.cpp      18 Jul 2007 13:13:07 -0000      1.4
@@ -115,6 +115,7 @@
 {
        Q_ASSERT(m_sf);
        
+       
        if (start >= get_length()) {
                return false;
        }
@@ -126,8 +127,6 @@
                return false;
        }
        
-       m_nextFrame = start;
-
        return true;
 }
 
@@ -140,8 +139,6 @@
        
        // FIXME: deinterlace here instead of in MonoReader
        
-       m_nextFrame += samplesRead / get_num_channels();
-       
        return samplesRead;
 }
 

Index: core/Song.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Song.cpp,v
retrieving revision 1.122
retrieving revision 1.123
diff -u -b -r1.122 -r1.123
--- core/Song.cpp       30 Jun 2007 00:15:31 -0000      1.122
+++ core/Song.cpp       18 Jul 2007 13:13:07 -0000      1.123
@@ -919,6 +919,13 @@
 void Song::audiodevice_params_changed()
 {
        resize_buffer(true, audiodevice().get_buffer_size());
+       
+       // The samplerate possibly has been changed, this initiates
+       // a seek in DiskIO, which clears the buffers and refills them
+       // with the correct resampled audio data!
+       // We need to seek to a different position then the current one,
+       // else the seek won't happen at all :)
+       set_transport_pos(m_transportFrame + audiodevice().get_buffer_size());
 }
 
 int Song::get_bitdepth( )

Index: core/Track.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Track.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- core/Track.cpp      5 Jun 2007 11:14:32 -0000       1.62
+++ core/Track.cpp      18 Jul 2007 13:13:07 -0000      1.63
@@ -414,7 +414,6 @@
        AudioBus* bus = m_song->get_render_bus();
        bus->silence_buffers(nframes);
        
-       audio_sample_t* mixdown = m_song->mixdown;
        int result;
        float gainFactor, panFactor;
 
@@ -422,8 +421,6 @@
        
        for (int i=0; i<audioClipList.size(); ++i) {
        
-               memset (mixdown, 0, sizeof (audio_sample_t) * nframes);
-               
                AudioClip* clip = audioClipList.at(i);
                
                if (isArmed && clip->recording_state() == 
AudioClip::NO_RECORDING) {
@@ -431,17 +428,18 @@
                                continue;
                }
                
-               for (int chan=0; chan<bus->get_channel_count(); ++chan) {
                
-                       result = clip->process(nframes, mixdown, chan);
+               result = clip->process(nframes);
                        
                        if (result <= 0) {
                                continue;
                        }
 
                        processResult |= result;
+       }
                        
-                       gainFactor = get_gain() * clip->get_gain();
+       for (int chan=0; chan<bus->get_channel_count(); ++chan) {
+               gainFactor = get_gain();
                        
                        if ( (chan == 0) && (m_pan > 0)) {
                                panFactor = 1 - m_pan;
@@ -453,8 +451,7 @@
                                gainFactor *= panFactor;
                        }
                        
-                       Mixer::mix_buffers_with_gain(bus->get_buffer(chan, 
nframes), mixdown, nframes, gainFactor);
-               }
+               Mixer::apply_gain_to_buffer(bus->get_buffer(chan, nframes), 
nframes, gainFactor);
        }
        
        processResult |= m_pluginChain->process_post_fader(bus, nframes);

Index: core/VorbisAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/VorbisAudioReader.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/VorbisAudioReader.cpp  15 Jul 2007 05:14:48 -0000      1.5
+++ core/VorbisAudioReader.cpp  18 Jul 2007 13:13:07 -0000      1.6
@@ -123,8 +123,6 @@
                return false;
        }
        
-       m_nextFrame = start;
-
        return true;
 }
 
@@ -164,8 +162,6 @@
                totalRead += samplesRead * get_num_channels();
        }
        
-       m_nextFrame += totalRead / get_num_channels();
-       
        return totalRead;
 }
 

Index: traverso/songcanvas/AudioClipView.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/songcanvas/AudioClipView.cpp,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -b -r1.80 -r1.81
--- traverso/songcanvas/AudioClipView.cpp       8 Jul 2007 19:45:06 -0000       
1.80
+++ traverso/songcanvas/AudioClipView.cpp       18 Jul 2007 13:13:07 -0000      
1.81
@@ -268,6 +268,10 @@
                nframes_t clipstartoffset = m_clip->get_source_start_frame();
                
                Peak* peak = m_clip->get_peak_for_channel(chan);
+               if (!peak) {
+                       PERROR("No Peak object available for clip %s channel 
%d", QS_C(m_clip->get_name()), chan);
+                       return;
+               }
                int availpeaks = peak->calculate_peaks( buffers[chan],
                                                        microView ? 
m_song->get_hzoom() : m_song->get_hzoom() + 1,
                                                        (xstart * 
m_sv->scalefactor) + clipstartoffset,

Index: core/MonoReader.cpp
===================================================================
RCS file: core/MonoReader.cpp
diff -N core/MonoReader.cpp
--- core/MonoReader.cpp 15 Jul 2007 20:17:51 -0000      1.22
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,418 +0,0 @@
-/*
-Copyright (C) 2006-2007 Remon Sijrier 
-
-This file is part of Traverso
-
-Traverso is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-
-*/
-
-
-#include "MonoReader.h"
-
-#include "Peak.h"
-#include "ProjectManager.h"
-#include "Project.h"
-#include "AudioClip.h"
-#include "ReadSource.h"
-#include "Utils.h"
-#include <Config.h>
-#include <AudioDevice.h>
-#include <DiskIO.h>
-#include <Song.h>
-#include "AbstractAudioReader.h"
-
-// Always put me below _all_ includes, this is needed
-// in case we run with memory leak detection enabled!
-#include "Debugger.h"
-
-
-
-MonoReader::MonoReader(ReadSource* source, int sourceChannelCount, int 
channelNumber, const QString& fileName)
-       : AudioSource(),
-         m_source(source),
-         m_buffer(0),
-         m_peak(0),
-         m_audioReader(0),
-         m_sourceChannelCount(sourceChannelCount), 
-         m_channelNumber(channelNumber), 
-         m_fileName(fileName)
-{
-       PENTERCONS;
-       m_bufferstatus = new BufferStatus;
-}
-
-MonoReader::~MonoReader()
-{
-       PENTERDES;
-       if (m_buffer) {
-               delete m_buffer;
-       }
-       if (m_peak) {
-               m_peak->close();
-       }
-       if (m_audioReader) {
-               delete m_audioReader;
-       }
-       
-       delete m_bufferstatus;
-}
-
-
-int MonoReader::init(bool forPeaks)
-{
-       PENTER;
-       
-       Q_ASSERT(m_audioReader == 0);
-       
-       m_rbFileReadPos = 0;
-       m_rbRelativeFileReadPos = 0;
-       m_rbReady = 0;
-       m_needSync = 0;
-       m_syncInProgress = 0;
-       m_clip = 0;
-       m_bufferUnderRunDetected = m_wasActivated = 0;
-       
-       bool useResampling = config().get_property("Conversion", 
"DynamicResampling", false).toBool();
-       
-       if (useResampling) {
-               int converter_type;
-               if (forPeaks) {
-                       converter_type = 4;  // Very fast, and acurate enough 
for drawing
-               }
-               else {
-                       converter_type = config().get_property("Conversion", 
"RTResamplingConverterType", 2).toInt();
-                       // There should be another config option for 
ConverterType to use for export (higher quality)
-                       //converter_type = config().get_property("Conversion", 
"ExportResamplingConverterType", 0).toInt();
-               }
-               m_audioReader = 
AbstractAudioReader::create_resampled_audio_reader(m_fileName, converter_type);
-       }
-       else {
-               m_audioReader = 
AbstractAudioReader::create_audio_reader(m_fileName);
-       }
-       
-       if (m_audioReader == 0) {
-               return ReadSource::COULD_NOT_OPEN_FILE;
-       }
-       
-       if (m_sourceChannelCount > m_audioReader->get_num_channels()) {
-               PERROR("ReadAudioSource: file only contains %d channels; %d is 
invalid as a channel number", m_audioReader->get_num_channels(), 
m_sourceChannelCount);
-               delete m_audioReader;
-               m_audioReader = 0;
-               return ReadSource::INVALID_CHANNEL_COUNT;
-       }
-
-       if (m_audioReader->get_num_channels() == 0) {
-               PERROR("ReadAudioSource: not a valid channel count: %d", 
m_audioReader->get_num_channels());
-               delete m_audioReader;
-               m_audioReader = 0;
-               return ReadSource::ZERO_CHANNELS;
-       }
-
-       m_source->m_length = m_audioReader->get_length();
-       m_length = m_audioReader->get_length();
-       m_source->m_rate = m_audioReader->get_rate();
-       
-       if (!forPeaks) {
-               m_peak = new Peak(m_source, m_channelNumber);
-       }
-       else {
-               m_peak = 0;
-       }
-       
-       return 1;
-}
-
-
-int MonoReader::file_read (audio_sample_t* dst, nframes_t start, nframes_t 
cnt, audio_sample_t* readbuffer) const
-{
-#if defined (profile)
-       trav_time_t starttime = get_microseconds();
-#endif
-       if (m_audioReader->get_num_channels() == 1) {
-               int result = m_audioReader->read_from(dst, start, cnt);
-#if defined (profile)
-               int processtime = (int) (get_microseconds() - starttime);
-               if (processtime > 40000)
-                       printf("Process time for %s, channel %d: %d 
useconds\n\n", QS_C(m_fileName), m_channelNumber, processtime);
-#endif
-               return result;
-       }
-
-       float *ptr;
-       uint real_cnt = cnt * m_audioReader->get_num_channels();
-       
-       // The readbuffer 'assumes' that there is max 2 channels...
-       Q_ASSERT(m_audioReader->get_num_channels() <= 2);
-       
-       int nread = m_audioReader->read_from(readbuffer, start, real_cnt);
-#if defined (profile)
-       int processtime = (int) (get_microseconds() - starttime);
-       if (processtime > 40000)
-               printf("Process time for %s, channel %d: %d useconds\n\n", 
QS_C(m_fileName), m_channelNumber, processtime);
-#endif
-       ptr = readbuffer + m_channelNumber;
-       nread /= m_audioReader->get_num_channels();
-
-       /* stride through the interleaved data */
-       // FIXME: deinterlace in AudioReader Classes instead of here
-
-       for (int32_t n = 0; n < nread; ++n) {
-               dst[n] = *ptr;
-               ptr += m_audioReader->get_num_channels();
-       }
-
-
-       return nread;
-}
-
-
-int MonoReader::rb_read(audio_sample_t* dst, nframes_t start, nframes_t count)
-{
-
-       if ( ! m_rbReady ) {
-//             printf("ringbuffer not ready\n");
-               return 0;
-       }
-
-       if (start != m_rbRelativeFileReadPos) {
-               int available = m_buffer->read_space();
-//             printf("start %d, m_rbFileReadPos %d\n", start, 
m_rbRelativeFileReadPos);
-               if ( (start > m_rbRelativeFileReadPos) && 
(m_rbRelativeFileReadPos + available) > (start + count)) {
-                       int advance = start - m_rbRelativeFileReadPos;
-                       if (available < advance)
-                               printf("available < advance !!!!!!!\n");
-                       m_buffer->increment_read_ptr(advance);
-                       m_rbRelativeFileReadPos += advance;
-               } else {
-                       start_resync(start + (m_clip->get_track_start_frame() + 
m_clip->get_source_start_frame()));
-                       return 0;
-               }
-       }
-
-       nframes_t readcount = m_buffer->read(dst, count);
-
-       if (readcount != count) {
-               // Hmm, not sure what to do in this case....
-       }
-
-       m_rbRelativeFileReadPos += readcount;
-
-       return readcount;
-}
-
-
-int MonoReader::rb_file_read(audio_sample_t* dst, nframes_t cnt, 
audio_sample_t* readbuffer )
-{
-       int readFrames = file_read( dst, m_rbFileReadPos, cnt, readbuffer);
-       m_rbFileReadPos += readFrames;
-
-       return readFrames;
-}
-
-
-void MonoReader::rb_seek_to_file_position( nframes_t position )
-{
-       Q_ASSERT(m_clip);
-       
-//     printf("rb_seek_to_file_position:: seeking to %d\n", position);
-       
-       // calculate position relative to the file!
-       long fileposition = position - (m_clip->get_track_start_frame() + 
m_clip->get_source_start_frame());
-       
-       if (m_rbFileReadPos == fileposition) {
-//             printf("ringbuffer allready at position %d\n", position);
-               return;
-       }
-
-       // check if the clip's start position is within the range
-       // if not, fill the buffer from the earliest point this clip
-       // will come into play.
-       if (fileposition < 0) {
-//             printf("not seeking to %ld, but too %d\n\n", 
fileposition,m_clip->get_source_start_frame()); 
-               // Song's start from 0, this makes a period start from
-               // 0 - 1023 for example, the nframes is 1024!
-               // Setting a songs new position is on 1024, and NOT 
-               // 1023.. Hmm, something isn't correct here, but at least 
substract 1
-               // to make this thing work!
-               fileposition = m_clip->get_source_start_frame() - 1;
-       }
-       
-//     printf("rb_seek_to_file_position:: seeking to relative pos: %d\n", 
fileposition);
-       m_buffer->reset();
-       m_rbFileReadPos = fileposition;
-       m_rbRelativeFileReadPos = fileposition;
-}
-
-void MonoReader::process_ringbuffer( audio_sample_t * framebuffer, 
audio_sample_t* readbuffer, bool seeking)
-{
-       // Do nothing if we passed the lenght of the AudioFile.
-       if (m_rbFileReadPos >= m_length) {
-//             printf("returning, m_rbFileReadPos > m_length! (%d >  %d)\n", 
m_rbFileReadPos, m_source->m_length);
-               if (m_syncInProgress) {
-                       finish_resync();
-               }
-               return;
-       }
-       
-       // Calculate the number of samples we can write into the buffer
-       int writeSpace = m_buffer->write_space();
-
-       // The amount of chunks which can be 'read'
-       int chunkCount = (int)(writeSpace / m_chunkSize);
-       
-       int toRead = m_chunkSize;
-       
-       if (seeking) {
-               toRead = writeSpace;
-//             printf("doing a full seek buffer fill\n");
-       } else if (m_syncInProgress) {
-               // Currently, we fill the buffer completely.
-               // For some reason, filling it with 1/4 at a time
-               // doesn't fill it consitently, and thus giving audible 
artifacts.
-/*             toRead = m_chunkSize * 2;*/
-               toRead = writeSpace;
-       } else if (chunkCount == 0) {
-               // If we are nearing the end of the source file it could be 
possible
-               // we only need to read the last samples which is smaller in 
size then 
-               // chunksize. If so, set toRead to m_source->m_length - 
rbFileReasPos
-               if ( (int) (m_source->m_length - m_rbFileReadPos) <= 
m_chunkSize) {
-                       toRead = m_source->m_length - m_rbFileReadPos;
-               } else {
-                       printf("MonoReader:: chunkCount == 0, but not at end of 
file, this shouldn't happen!!\n");
-                       return;
-               }
-       }
-       
-       // Read in the samples from source
-       nframes_t toWrite = rb_file_read(framebuffer, toRead, readbuffer);
-
-       // and write it to the ringbuffer
-       m_buffer->write(framebuffer, toWrite);
-       
-}
-
-void MonoReader::recover_from_buffer_underrun(nframes_t position)
-{
-//     printf("buffer underrun detected!\n");
-       m_bufferUnderRunDetected = 1;
-       start_resync(position);
-}
-
-void MonoReader::start_resync( nframes_t position )
-{
-//     printf("starting resync!\n");
-       m_syncPos = position;
-       m_rbReady = 0;
-       m_needSync = 1;
-}
-
-void MonoReader::finish_resync()
-{
-//     printf("sync finished\n");
-       m_needSync = 0;
-       m_bufferUnderRunDetected = 0;
-       m_rbReady = 1;
-       m_syncInProgress = 0;
-}
-
-void MonoReader::sync(audio_sample_t* framebuffer, audio_sample_t* readbuffer)
-{
-       PENTER2;
-       if (!m_needSync) {
-               return;
-       }
-       
-       if (!m_syncInProgress) {
-               rb_seek_to_file_position(m_syncPos);
-               m_syncInProgress = 1;
-       }
-       
-       // Currently, we fill the buffer completely.
-       // For some reason, filling it with 1/4 at a time
-       // doesn't fill it consitently, and thus giving audible artifacts.
-       process_ringbuffer(framebuffer, readbuffer);
-       
-       if (m_buffer->write_space() == 0) {
-               finish_resync();
-       }
-       
-//         PWARN("Resyncing ringbuffer finished");
-}
-
-
-void MonoReader::set_audio_clip( AudioClip * clip )
-{
-       m_clip = clip;
-}
-
-Peak* MonoReader::get_peak( )
-{
-       return m_peak;
-}
-
-void MonoReader::prepare_buffer( )
-{
-       PENTER;
-       
-       Q_ASSERT(m_clip);
-
-       float size = config().get_property("Hardware", "readbuffersize", 
1.0).toDouble();
-
-       m_bufferSize = (int) (size * audiodevice().get_sample_rate());
-
-       m_chunkSize = m_bufferSize / DiskIO::bufferdividefactor;
-
-       m_buffer = new RingBufferNPT<float>(m_bufferSize);
-
-       start_resync(m_clip->get_song()->get_working_frame());
-}
-
-BufferStatus* MonoReader::get_buffer_status()
-{
-       int freespace = m_buffer->write_space();
-
-       if (m_rbFileReadPos >= m_length) {
-               m_bufferstatus->fillStatus =  100;
-               freespace = 0;
-       } else {
-               m_bufferstatus->fillStatus = (int) (((float)freespace / 
m_bufferSize) * 100);
-       }
-       
-       m_bufferstatus->bufferUnderRun = m_bufferUnderRunDetected;
-       m_bufferstatus->needSync = m_needSync;
-
-       m_bufferstatus->priority = (int) (freespace / m_chunkSize);
-       
-       return m_bufferstatus;
-}
-
-void MonoReader::set_active(bool active)
-{
-       if (m_active == active)
-               return;
-
-       if (active) {
-               m_active = 1;
-//             m_wasActivated = 1;
-//             printf("setting private readsource %s to active\n", 
QS_C(m_fileName));
-       } else {
-//             printf("setting private readsource %s to IN-active\n", 
QS_C(m_fileName));
-               m_active = 0;
-       }
-}
-
-
-//eof

Index: core/MonoReader.h
===================================================================
RCS file: core/MonoReader.h
diff -N core/MonoReader.h
--- core/MonoReader.h   15 Jul 2007 05:11:10 -0000      1.7
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,105 +0,0 @@
-/*
-Copyright (C) 2006-2007 Remon Sijrier 
-
-This file is part of Traverso
-
-Traverso is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
-
-*/
-
-#ifndef MONO_READER_H
-#define MONO_READER_H
-
-#include "AudioSource.h"
-#include "RingBufferNPT.h"
-#include "defines.h"
-
-
-class AudioClip;
-class AbstractAudioReader;
-class Peak;
-class ReadSource;
-class QString;
-struct BufferStatus;
-
-class MonoReader : public AudioSource
-{
-public :
-       int rb_read(audio_sample_t* dst, nframes_t start, nframes_t cnt);
-       int rb_file_read(audio_sample_t* dst, nframes_t cnt, audio_sample_t* 
readbuffer);
-       void rb_seek_to_file_position(nframes_t position);
-
-       void process_ringbuffer(audio_sample_t* framebuffer, audio_sample_t* 
readbuffer, bool seeking=false);
-       BufferStatus* get_buffer_status();
-
-       int file_read(audio_sample_t* dst, nframes_t start, nframes_t cnt, 
audio_sample_t* readbuffer) const;
-
-       int init(bool forPeaks);
-       int ref();
-       
-       void sync(audio_sample_t* framebuffer, audio_sample_t* readbuffer);
-       void set_audio_clip(AudioClip* clip);
-       void prepare_buffer();
-
-       Peak* get_peak();
-       size_t is_active() const;
-
-private:
-       MonoReader(ReadSource* source, int sourceChannelCount, int 
channelNumber, const QString& fileName);
-       ~MonoReader();
-       
-       ReadSource*     m_source;
-       RingBufferNPT<float>*   m_buffer;
-       Peak*           m_peak;
-       AbstractAudioReader*    m_audioReader;
-       int             m_sourceChannelCount;
-       int             m_channelNumber;
-       uint            m_length;
-       uint            m_bufferSize;
-       int             m_chunkSize;
-       
-       nframes_t       m_rbFileReadPos;
-       nframes_t       m_rbRelativeFileReadPos;
-       volatile size_t m_syncPos;
-       volatile size_t m_rbReady;
-       volatile size_t m_needSync;
-       volatile size_t m_active;
-       volatile size_t m_wasActivated;
-       volatile size_t m_bufferUnderRunDetected;
-       bool            m_syncInProgress;
-       int             m_prio;
-       
-       AudioClip*      m_clip;
-       BufferStatus*   m_bufferstatus;
-       QString         m_fileName;
-       
-
-       void start_resync(nframes_t position);
-       void finish_resync();
-       void set_active(bool active);
-
-       void recover_from_buffer_underrun(nframes_t position);
-       
-       friend class ReadSource;
-       
-};
-
-inline size_t MonoReader::is_active() const
-{
-       return m_active;
-}
-
-
-#endif




reply via email to

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