Chris@147: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@147: 
Chris@147: /*
Chris@147:     Sonic Visualiser
Chris@147:     An audio file viewer and annotation editor.
Chris@147:     Centre for Digital Music, Queen Mary, University of London.
Chris@202:     This file copyright 2006 Chris Cannam and QMUL.
Chris@147:     
Chris@147:     This program is free software; you can redistribute it and/or
Chris@147:     modify it under the terms of the GNU General Public License as
Chris@147:     published by the Free Software Foundation; either version 2 of the
Chris@147:     License, or (at your option) any later version.  See the file
Chris@147:     COPYING included with this distribution for more information.
Chris@147: */
Chris@147: 
Chris@147: #ifndef _WAVE_FILE_MODEL_H_
Chris@147: #define _WAVE_FILE_MODEL_H_
Chris@147: 
Chris@150: #include "base/Thread.h"
Chris@147: #include <QMutex>
Chris@147: #include <QTimer>
Chris@147: 
Chris@317: #include "data/fileio/FileSource.h"
Chris@316: 
Chris@147: #include "RangeSummarisableTimeValueModel.h"
Chris@147: #include "PowerOfSqrtTwoZoomConstraint.h"
Chris@147: 
Chris@147: #include <stdlib.h>
Chris@147: 
Chris@147: class AudioFileReader;
Chris@147: 
Chris@179: class WaveFileModel : public RangeSummarisableTimeValueModel
Chris@147: {
Chris@147:     Q_OBJECT
Chris@147: 
Chris@147: public:
Chris@317:     WaveFileModel(FileSource source, size_t targetRate = 0);
Chris@317:     WaveFileModel(FileSource source, AudioFileReader *reader);
Chris@147:     ~WaveFileModel();
Chris@147: 
Chris@147:     bool isOK() const;
Chris@147:     bool isReady(int *) const;
Chris@147: 
Chris@179:     const ZoomConstraint *getZoomConstraint() const { return &m_zoomConstraint; }
Chris@179: 
Chris@147:     size_t getFrameCount() const;
Chris@147:     size_t getChannelCount() const;
Chris@147:     size_t getSampleRate() const;
Chris@297:     size_t getNativeRate() const;
Chris@147: 
Chris@333:     QString getTitle() const;
Chris@333:     QString getMaker() const;
Chris@345:     QString getLocation() const;
Chris@333: 
Chris@147:     virtual Model *clone() const;
Chris@147: 
Chris@147:     float getValueMinimum() const { return -1.0f; }
Chris@147:     float getValueMaximum() const { return  1.0f; }
Chris@147: 
Chris@300:     virtual size_t getStartFrame() const { return m_startFrame; }
Chris@300:     virtual size_t getEndFrame() const { return m_startFrame + getFrameCount(); }
Chris@147: 
Chris@300:     void setStartFrame(size_t startFrame) { m_startFrame = startFrame; }
Chris@147: 
Chris@300:     virtual size_t getData(int channel, size_t start, size_t count,
Chris@300:                            float *buffer) const;
Chris@147: 
Chris@300:     virtual size_t getData(int channel, size_t start, size_t count,
Chris@300:                            double *buffer) const;
Chris@147: 
Chris@363:     virtual size_t getData(size_t fromchannel, size_t tochannel,
Chris@363:                            size_t start, size_t count,
Chris@363:                            float **buffers) const;
Chris@363: 
Chris@377:     virtual size_t getSummaryBlockSize(size_t desired) const;
Chris@377: 
Chris@300:     virtual void getSummaries(size_t channel, size_t start, size_t count,
Chris@300:                               RangeBlock &ranges,
Chris@300:                               size_t &blockSize) const;
Chris@300: 
Chris@300:     virtual Range getSummary(size_t channel, size_t start, size_t count) const;
Chris@147: 
Chris@345:     QString getTypeName() const { return tr("Wave File"); }
Chris@345: 
Chris@163:     virtual void toXml(QTextStream &out,
Chris@163:                        QString indent = "",
Chris@163:                        QString extraAttributes = "") const;
Chris@163: 
Chris@147: protected slots:
Chris@147:     void fillTimerTimedOut();
Chris@147:     void cacheFilled();
Chris@147:     
Chris@147: protected:
Chris@147:     void initialize();
Chris@147: 
Chris@147:     class RangeCacheFillThread : public Thread
Chris@147:     {
Chris@147:     public:
Chris@147:         RangeCacheFillThread(WaveFileModel &model) :
Chris@175: 	    m_model(model), m_fillExtent(0),
Chris@175:             m_frameCount(model.getFrameCount()) { }
Chris@147:     
Chris@147: 	size_t getFillExtent() const { return m_fillExtent; }
Chris@147:         virtual void run();
Chris@147: 
Chris@147:     protected:
Chris@147:         WaveFileModel &m_model;
Chris@147: 	size_t m_fillExtent;
Chris@175:         size_t m_frameCount;
Chris@147:     };
Chris@147:          
Chris@147:     void fillCache();
Chris@316: 
Chris@317:     FileSource m_source;
Chris@147:     QString m_path;
Chris@147:     AudioFileReader *m_reader;
Chris@175:     bool m_myReader;
Chris@147: 
Chris@300:     size_t m_startFrame;
Chris@300: 
Chris@147:     RangeBlock m_cache[2]; // interleaved at two base resolutions
Chris@147:     mutable QMutex m_mutex;
Chris@147:     RangeCacheFillThread *m_fillThread;
Chris@147:     QTimer *m_updateTimer;
Chris@147:     size_t m_lastFillExtent;
Chris@147:     bool m_exiting;
Chris@179:     static PowerOfSqrtTwoZoomConstraint m_zoomConstraint;
Chris@377: 
Chris@377:     mutable SampleBlock m_directRead;
Chris@377:     mutable size_t m_lastDirectReadStart;
Chris@377:     mutable size_t m_lastDirectReadCount;
Chris@377:     mutable QMutex m_directReadMutex;
Chris@147: };    
Chris@147: 
Chris@147: #endif