aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2016-03-07 22:21:23 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2016-03-07 22:28:04 +0300
commit925e9e45cd6640ffb71ed1ba31e9289ed06eebde (patch)
treee5e3ac6d140251218731dfc65525f7a62ba95896
parentf7dbae4af76e76cb53ab34a7e9a16d78b83c6841 (diff)
downloadatracdenc-925e9e45cd6640ffb71ed1ba31e9289ed06eebde.tar.gz
remove suboptimal multiply readf (writef) libsndfile calls during reading or writing wav file
-rw-r--r--src/atracdenc.cpp8
-rw-r--r--src/pcmengin.h83
-rw-r--r--src/wav.h28
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>
diff --git a/src/wav.h b/src/wav.h
index 991f5dc..0d34c2e 100644
--- a/src/wav.h
+++ b/src/wav.h
@@ -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");
}
});
}