diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-03-07 22:21:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2016-03-07 22:28:04 +0300 |
commit | 925e9e45cd6640ffb71ed1ba31e9289ed06eebde (patch) | |
tree | e5e3ac6d140251218731dfc65525f7a62ba95896 | |
parent | f7dbae4af76e76cb53ab34a7e9a16d78b83c6841 (diff) | |
download | atracdenc-925e9e45cd6640ffb71ed1ba31e9289ed06eebde.tar.gz |
remove suboptimal multiply readf (writef) libsndfile calls during reading or writing wav file
-rw-r--r-- | src/atracdenc.cpp | 8 | ||||
-rw-r--r-- | src/pcmengin.h | 83 | ||||
-rw-r--r-- | src/wav.h | 28 |
3 files changed, 71 insertions, 48 deletions
diff --git a/src/atracdenc.cpp b/src/atracdenc.cpp index 092059c..1982ba6 100644 --- a/src/atracdenc.cpp +++ b/src/atracdenc.cpp @@ -140,7 +140,7 @@ void TAtrac1MDCT::IMdct(double Specs[512], const TBlockSize& mode, double* low, } TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetDecodeLambda() { - return [this](vector<double>* data) { + return [this](double* data) { double sum[512]; const uint32_t srcChannels = Aea->GetChannelNum(); for (uint32_t channel = 0; channel < srcChannels; channel++) { @@ -162,7 +162,7 @@ TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetDecodeLambda() { if (sum[i] < PcmValueMin) sum[i] = PcmValueMin; - data[i][channel] = sum[i]; + data[i * srcChannels + channel] = sum[i]; } } @@ -180,12 +180,12 @@ TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetEncodeLambda() { bitAlloc.push_back(new TAtrac1SimpleBitAlloc(atrac1container, Settings.GetBfuIdxConst(), Settings.GetFastBfuNumSearch())); } - return [this, srcChannels, bitAlloc](vector<double>* data) { + return [this, srcChannels, bitAlloc](double* data) { for (uint32_t channel = 0; channel < srcChannels; channel++) { double src[NumSamples]; vector<double> specs(512); for (int i = 0; i < NumSamples; ++i) { - src[i] = data[i][channel]; + src[i] = data[i * srcChannels + channel]; } SplitFilterBank[channel].Split(&src[0], &PcmBufLow[channel][0], &PcmBufMid[channel][0], &PcmBufHi[channel][0]); diff --git a/src/pcmengin.h b/src/pcmengin.h index 3395c5c..802d2d8 100644 --- a/src/pcmengin.h +++ b/src/pcmengin.h @@ -27,9 +27,43 @@ class TEndOfRead : public std::exception { }; template <class T> +class TPCMBuffer { + std::vector<T> Buf_; + int32_t NumChannels; +public: + TPCMBuffer(const int32_t bufSize, const int32_t numChannels) + : NumChannels(numChannels) + { + Buf_.resize(bufSize*numChannels); + } + size_t Size() { + return Buf_.size() / NumChannels; + } + T* operator[](size_t pos) { + size_t rpos = pos * NumChannels; + if (rpos >= Buf_.size()) + abort(); + return &Buf_[rpos]; + } + const T* operator[](size_t pos) const { + size_t rpos = pos * NumChannels; + if (rpos >= Buf_.size()) + abort(); + return &Buf_[rpos]; + } + size_t Channels() const { + return NumChannels; + } + void Zero(size_t pos, size_t len) { + assert((pos + len) * NumChannels <= Buf_.size()); + memset(&Buf_[pos*NumChannels], 0, len*NumChannels); + } +}; + +template <class T> class IPCMWriter { public: - virtual void Write(const std::vector<std::vector<T>>& data , const uint32_t size) const = 0; + virtual void Write(const TPCMBuffer<T>& data , const uint32_t size) const = 0; IPCMWriter() {}; virtual ~IPCMWriter() {}; }; @@ -37,72 +71,61 @@ class IPCMWriter { template <class T> class IPCMReader { public: - virtual void Read(std::vector<std::vector<T>>& data , const uint32_t size) const = 0; + virtual void Read(TPCMBuffer<T>& data , const uint32_t size) const = 0; IPCMReader() {}; virtual ~IPCMReader() {}; }; - - template<class T> class TPCMEngine { - std::vector<std::vector<T>> Buffers; public: typedef std::unique_ptr<IPCMWriter<T>> TWriterPtr; typedef std::unique_ptr<IPCMReader<T>> TReaderPtr; private: + TPCMBuffer<T> Buffer; TWriterPtr Writer; TReaderPtr Reader; uint64_t Processed = 0; public: - TPCMEngine(const int32_t bufSize, const int32_t numChannels) { - InitBuffers(bufSize, numChannels); + TPCMEngine(const int32_t bufSize, const int32_t numChannels) + : Buffer(bufSize, numChannels) { } TPCMEngine(const int32_t bufSize, const int32_t numChannels, TWriterPtr&& writer) - : Writer(std::move(writer)) { - InitBuffers(bufSize, numChannels); + : Buffer(bufSize, numChannels) + , Writer(std::move(writer)) { } TPCMEngine(const int32_t bufSize, const int32_t numChannels, TReaderPtr&& reader) - : Reader(std::move(reader)) { - InitBuffers(bufSize, numChannels); + : Buffer(bufSize, numChannels) + , Reader(std::move(reader)) { } TPCMEngine(const int32_t bufSize, const int32_t numChannels, TWriterPtr&& writer, TReaderPtr&& reader) - : Writer(std::move(writer)) + : Buffer(bufSize, numChannels) + , Writer(std::move(writer)) , Reader(std::move(reader)) { - InitBuffers(bufSize, numChannels); } - typedef std::function<void(std::vector<T>* data)> TProcessLambda; + typedef std::function<void(T* data)> TProcessLambda; uint64_t ApplyProcess(int step, TProcessLambda lambda) { - if (step > Buffers.size()) { + if (step > Buffer.Size()) { throw TPCMBufferTooSmall(); } if (Reader) { - const uint32_t sizeToRead = Buffers.size(); - Reader->Read(Buffers, sizeToRead); + const uint32_t sizeToRead = Buffer.Size(); + Reader->Read(Buffer, sizeToRead); } int32_t lastPos = 0; - for (int i = 0; i + step <= Buffers.size(); i+=step) { - lambda(&Buffers[i]); + for (int i = 0; i + step <= Buffer.Size(); i+=step) { + lambda(Buffer[i]); lastPos = i + step; } - assert(lastPos == Buffers.size()); + assert(lastPos == Buffer.Size()); if (Writer) { - Writer->Write(Buffers, lastPos); + Writer->Write(Buffer, lastPos); } Processed += lastPos; return Processed; } - - -private: - void InitBuffers(const int32_t bufSize, const int32_t numChannels) { - Buffers.resize(bufSize); - for (std::vector<T>& channel : Buffers) { - channel.resize(numChannels); - } - } }; template<class T> @@ -29,12 +29,12 @@ public: template<class T> class TWavPcmReader : public IPCMReader<T> { public: - typedef std::function<void(std::vector<std::vector<T>>& data, const uint32_t size)> TLambda; + typedef std::function<void(TPCMBuffer<T>& data, const uint32_t size)> TLambda; TLambda Lambda; TWavPcmReader(TLambda lambda) : Lambda(lambda) {} - void Read(std::vector<std::vector<T>>& data , const uint32_t size) const override { + void Read(TPCMBuffer<T>& data , const uint32_t size) const override { Lambda(data, size); } }; @@ -42,12 +42,12 @@ public: template<class T> class TWavPcmWriter : public IPCMWriter<T> { public: - typedef std::function<void(const std::vector<std::vector<T>>& data, const uint32_t size)> TLambda; + typedef std::function<void(const TPCMBuffer<T>& data, const uint32_t size)> TLambda; TLambda Lambda; TWavPcmWriter(TLambda lambda) : Lambda(lambda) {} - void Write(const std::vector<std::vector<T>>& data , const uint32_t size) const override { + void Write(const TPCMBuffer<T>& data , const uint32_t size) const override { Lambda(data, size); } }; @@ -76,24 +76,24 @@ typedef std::unique_ptr<TWav> TWavPtr; template<class T> IPCMReader<T>* TWav::GetPCMReader() const { - return new TWavPcmReader<T>([this](std::vector<std::vector<T>>& data, const uint32_t size) { - if (data[0].size() != File.channels()) + return new TWavPcmReader<T>([this](TPCMBuffer<T>& data, const uint32_t size) { + if (data.Channels() != File.channels()) throw TWrongReadBuffer(); - uint32_t dataRead = 0; - for (uint32_t i = 0; i < size; i++) { - dataRead += File.readf(&data[i][0], 1); + if (size_t read = File.readf(data[0], size) != size) { + assert(read < size); + //fprintf(stderr, "to zero: %d\n", size-read); + data.Zero(read, size - read); } }); } template<class T> IPCMWriter<T>* TWav::GetPCMWriter() { - return new TWavPcmWriter<T>([this](const std::vector<std::vector<T>>& data, const uint32_t size) { - if (data[0].size() != File.channels()) + return new TWavPcmWriter<T>([this](const TPCMBuffer<T>& data, const uint32_t size) { + if (data.Channels() != File.channels()) throw TWrongReadBuffer(); - uint32_t dataWrite = 0; - for (uint32_t i = 0; i < size; i++) { - dataWrite += File.writef(&data[i][0], 1); + if (File.writef(data[0], size) != size) { + fprintf(stderr, "can't write block\n"); } }); } |