diff options
Diffstat (limited to 'intern/audaspace/FX/AUD_LimiterReader.cpp')
-rw-r--r-- | intern/audaspace/FX/AUD_LimiterReader.cpp | 92 |
1 files changed, 72 insertions, 20 deletions
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp index d67fbb4d0e5..dc31477d2eb 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.cpp +++ b/intern/audaspace/FX/AUD_LimiterReader.cpp @@ -32,30 +32,46 @@ #include "AUD_LimiterReader.h" #include "AUD_Buffer.h" -#include <iostream> - -AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader, +AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, float start, float end) : AUD_EffectReader(reader), - m_start(int(start * reader->getSpecs().rate)), - m_end(int(end * reader->getSpecs().rate)) + m_start(start), + m_end(end) { if(m_start > 0) { + AUD_Specs specs = m_reader->getSpecs(); + AUD_Specs specs2; + if(m_reader->isSeekable()) - m_reader->seek(m_start); + m_reader->seek(m_start * specs.rate); else { // skip first m_start samples by reading them int length = AUD_DEFAULT_BUFFER_SIZE; - sample_t* buffer; - for(int len = m_start; - length == AUD_DEFAULT_BUFFER_SIZE; - len -= AUD_DEFAULT_BUFFER_SIZE) + AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs)); + bool eos = false; + for(int len = m_start * specs.rate; + length > 0 && !eos; + len -= length) { if(len < AUD_DEFAULT_BUFFER_SIZE) length = len; - m_reader->read(length, buffer); + + m_reader->read(length, eos, buffer.getBuffer()); + + specs2 = m_reader->getSpecs(); + if(specs2.rate != specs.rate) + { + len = len * specs2.rate / specs.rate; + specs.rate = specs2.rate; + } + + if(specs2.channels != specs.channels) + { + specs = specs2; + buffer.assureSize(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs)); + } } } } @@ -63,35 +79,71 @@ AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader, void AUD_LimiterReader::seek(int position) { - m_reader->seek(position + m_start); + m_reader->seek(position + m_start * m_reader->getSpecs().rate); } int AUD_LimiterReader::getLength() const { int len = m_reader->getLength(); - if(len < 0 || (len > m_end && m_end >= 0)) - len = m_end; - return len - m_start; + AUD_SampleRate rate = m_reader->getSpecs().rate; + if(len < 0 || (len > m_end * rate && m_end >= 0)) + len = m_end * rate; + return len - m_start * rate; } int AUD_LimiterReader::getPosition() const { int pos = m_reader->getPosition(); - return AUD_MIN(pos, m_end) - m_start; + AUD_SampleRate rate = m_reader->getSpecs().rate; + return AUD_MIN(pos, m_end * rate) - m_start * rate; } -void AUD_LimiterReader::read(int & length, sample_t* & buffer) +void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer) { + eos = false; if(m_end >= 0) { int position = m_reader->getPosition(); - if(position + length > m_end) - length = m_end - position; + AUD_SampleRate rate = m_reader->getSpecs().rate; + + if(position + length > m_end * rate) + { + length = m_end * rate - position; + eos = true; + } + + if(position < m_start * rate) + { + int len2 = length; + for(int len = m_start * rate - position; + len2 == length && !eos; + len -= length) + { + if(len < length) + len2 = len; + + m_reader->read(len2, eos, buffer); + position += len2; + } + + if(position < m_start * rate) + { + length = 0; + return; + } + } + if(length < 0) { length = 0; return; } } - m_reader->read(length, buffer); + if(eos) + { + m_reader->read(length, eos, buffer); + eos = true; + } + else + m_reader->read(length, eos, buffer); } |