1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 /* 4 Sonic Visualiser 5 An audio file viewer and annotation editor. 6 Centre for Digital Music, Queen Mary, University of London. 7 This file copyright 2006 Chris Cannam. 8 9 This program is free software; you can redistribute it and/or 10 modify it under the terms of the GNU General Public License as 11 published by the Free Software Foundation; either version 2 of the 12 License, or (at your option) any later version. See the file 13 COPYING included with this distribution for more information. 14 */ 15 16 #ifndef SV_CODED_AUDIO_FILE_READER_H 17 #define SV_CODED_AUDIO_FILE_READER_H 18 19 #include "AudioFileReader.h" 20 21 #include <QMutex> 22 #include <QReadWriteLock> 23 24 #ifdef Q_OS_WIN 25 #include <windows.h> 26 #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1 27 #endif 28 29 #include <sndfile.h> 30 31 class WavFileReader; 32 class Serialiser; 33 34 namespace breakfastquay { 35 class Resampler; 36 } 37 38 class CodedAudioFileReader : public AudioFileReader 39 { 40 Q_OBJECT 41 42 public: 43 virtual ~CodedAudioFileReader(); 44 45 enum CacheMode { 46 CacheInTemporaryFile, 47 CacheInMemory 48 }; 49 50 enum DecodeMode { 51 DecodeAtOnce, // decode the file on construction, with progress 52 DecodeThreaded // decode in a background thread after construction 53 }; 54 55 floatvec_t getInterleavedFrames(sv_frame_t start, sv_frame_t count) const override; 56 getNativeRate()57 sv_samplerate_t getNativeRate() const override { return m_fileRate; } 58 getLocalFilename()59 QString getLocalFilename() const override { return m_cacheFileName; } 60 61 /// Intermediate cache means all CodedAudioFileReaders are quickly seekable isQuicklySeekable()62 bool isQuicklySeekable() const override { return true; } 63 64 signals: 65 void progress(int); 66 67 protected: 68 CodedAudioFileReader(CacheMode cacheMode, 69 sv_samplerate_t targetRate, 70 bool normalised); 71 72 void initialiseDecodeCache(); // samplerate, channels must have been set 73 74 // compensation for encoder delays: 75 void setFramesToTrim(sv_frame_t fromStart, sv_frame_t fromEnd); 76 77 // may throw InsufficientDiscSpace: 78 void addSamplesToDecodeCache(float **samples, sv_frame_t nframes); 79 void addSamplesToDecodeCache(float *samplesInterleaved, sv_frame_t nframes); 80 void addSamplesToDecodeCache(const floatvec_t &interleaved); 81 82 // may throw InsufficientDiscSpace: 83 void finishDecodeCache(); 84 isDecodeCacheInitialised()85 bool isDecodeCacheInitialised() const { return m_initialised; } 86 87 void startSerialised(QString id); 88 void endSerialised(); 89 90 private: 91 void pushCacheWriteBufferMaybe(bool final); 92 93 sv_frame_t pushBuffer(float *interleaved, sv_frame_t sz, bool final); 94 95 // to be called only by pushBuffer 96 void pushBufferResampling(float *interleaved, sv_frame_t sz, double ratio, bool final); 97 98 // to be called only by pushBuffer and pushBufferResampling 99 void pushBufferNonResampling(float *interleaved, sv_frame_t sz); 100 101 protected: 102 QMutex m_cacheMutex; 103 CacheMode m_cacheMode; 104 floatvec_t m_data; 105 mutable QMutex m_dataLock; 106 bool m_initialised; 107 Serialiser *m_serialiser; 108 sv_samplerate_t m_fileRate; 109 110 QString m_cacheFileName; 111 SNDFILE *m_cacheFileWritePtr; 112 WavFileReader *m_cacheFileReader; 113 float *m_cacheWriteBuffer; 114 sv_frame_t m_cacheWriteBufferIndex; // buffer write pointer in samples 115 sv_frame_t m_cacheWriteBufferFrames; // buffer size in frames 116 117 breakfastquay::Resampler *m_resampler; 118 float *m_resampleBuffer; 119 int m_resampleBufferFrames; 120 sv_frame_t m_fileFrameCount; 121 122 bool m_normalised; 123 float m_max; 124 float m_gain; 125 126 sv_frame_t m_trimFromStart; 127 sv_frame_t m_trimFromEnd; 128 129 sv_frame_t m_clippedCount; 130 sv_frame_t m_firstNonzero; 131 sv_frame_t m_lastNonzero; 132 }; 133 134 #endif 135