diff options
author | Joerg Mueller <nexyon@gmail.com> | 2011-06-22 00:14:53 +0400 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2011-06-22 00:14:53 +0400 |
commit | cc71dcc218d9ee4612bfe955be6f00be521be5b1 (patch) | |
tree | 5f868efc11f940b72cdf0e0c5d19f27e7d3067c7 /intern | |
parent | 7ba4362c72c3ccd4763762414bd928682a51b7ce (diff) |
3D Audio GSoC:
Streaming improved.
Diffstat (limited to 'intern')
43 files changed, 175 insertions, 108 deletions
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp index 9ddd8af019b..79039ca605b 100644 --- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp +++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp @@ -55,9 +55,9 @@ AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader() delete[] m_y; } -void AUD_BaseIIRFilterReader::read(int & length, sample_t* buffer) +void AUD_BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer) { - m_reader->read(length, buffer); + m_reader->read(length, eos, buffer); for(m_channel = 0; m_channel < m_channels; m_channel++) { diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h index 2d1f21446a0..a300ff9d241 100644 --- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h +++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h @@ -107,7 +107,7 @@ public: virtual ~AUD_BaseIIRFilterReader(); - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); virtual sample_t filter()=0; }; diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp index 2e93184358e..7d58b3dae4f 100644 --- a/intern/audaspace/FX/AUD_DelayReader.cpp +++ b/intern/audaspace/FX/AUD_DelayReader.cpp @@ -69,7 +69,7 @@ int AUD_DelayReader::getPosition() const return m_reader->getPosition() + m_delay; } -void AUD_DelayReader::read(int & length, sample_t* buffer) +void AUD_DelayReader::read(int& length, bool& eos, sample_t* buffer) { if(m_remdelay > 0) { @@ -81,10 +81,9 @@ void AUD_DelayReader::read(int & length, sample_t* buffer) memset(buffer, 0, m_remdelay * samplesize); int len = length - m_remdelay; - m_reader->read(len, buffer + m_remdelay * specs.channels); + m_reader->read(len, eos, buffer + m_remdelay * specs.channels); - if(len < length-m_remdelay) - length = m_remdelay + len; + length = m_remdelay + len; m_remdelay = 0; } @@ -95,5 +94,5 @@ void AUD_DelayReader::read(int & length, sample_t* buffer) } } else - m_reader->read(length, buffer); + m_reader->read(length, eos, buffer); } diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h index cb0ec9bcd9d..a89afe73b37 100644 --- a/intern/audaspace/FX/AUD_DelayReader.h +++ b/intern/audaspace/FX/AUD_DelayReader.h @@ -66,7 +66,7 @@ public: virtual void seek(int position); virtual int getLength() const; virtual int getPosition() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_DELAYREADER diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 605c49066d2..5d9ebbd6187 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -89,29 +89,27 @@ AUD_Specs AUD_DoubleReader::getSpecs() const return m_reader1->getSpecs(); } -void AUD_DoubleReader::read(int & length, sample_t* buffer) +void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer) { if(!m_finished1) { int len = length; - m_reader1->read(len, buffer); + m_reader1->read(len, m_finished1, buffer); - if(len < length) + if(m_finished1) { const AUD_Specs specs = m_reader1->getSpecs(); len = length - len; length -= len; - m_reader2->read(len, buffer + length * specs.channels); + m_reader2->read(len, eos, buffer + length * specs.channels); length += len; - - m_finished1 = true; } } else { - m_reader2->read(length, buffer); + m_reader2->read(length, eos, buffer); } } diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h index d68000fe81a..86f636e2cb2 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.h +++ b/intern/audaspace/FX/AUD_DoubleReader.h @@ -85,7 +85,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_DOUBLEREADER diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp index aa8fe7a7f35..4d14af76438 100644 --- a/intern/audaspace/FX/AUD_EffectReader.cpp +++ b/intern/audaspace/FX/AUD_EffectReader.cpp @@ -65,7 +65,7 @@ AUD_Specs AUD_EffectReader::getSpecs() const return m_reader->getSpecs(); } -void AUD_EffectReader::read(int & length, sample_t* buffer) +void AUD_EffectReader::read(int& length, bool& eos, sample_t* buffer) { - m_reader->read(length, buffer); + m_reader->read(length, eos, buffer); } diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h index cfb8e5b6e77..c03abd11828 100644 --- a/intern/audaspace/FX/AUD_EffectReader.h +++ b/intern/audaspace/FX/AUD_EffectReader.h @@ -69,7 +69,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_EFFECTREADER diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp index 7fe5c503c23..4a6050cf0f3 100644 --- a/intern/audaspace/FX/AUD_FaderReader.cpp +++ b/intern/audaspace/FX/AUD_FaderReader.cpp @@ -42,13 +42,13 @@ AUD_FaderReader::AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType { } -void AUD_FaderReader::read(int & length, sample_t* buffer) +void AUD_FaderReader::read(int& length, bool& eos, sample_t* buffer) { int position = m_reader->getPosition(); AUD_Specs specs = m_reader->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); - m_reader->read(length, buffer); + m_reader->read(length, eos, buffer); if((position + length) / (float)specs.rate <= m_start) { diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h index c0eb3d27d36..e702ac0ec19 100644 --- a/intern/audaspace/FX/AUD_FaderReader.h +++ b/intern/audaspace/FX/AUD_FaderReader.h @@ -72,7 +72,7 @@ public: AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type, float start,float length); - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_FADERREADER diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp index 0f87679410e..52add8635e3 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.cpp +++ b/intern/audaspace/FX/AUD_LimiterReader.cpp @@ -49,13 +49,15 @@ AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, // skip first m_start samples by reading them int length = AUD_DEFAULT_BUFFER_SIZE; AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(m_reader->getSpecs())); + bool eos = false; for(int len = m_start; - length == AUD_DEFAULT_BUFFER_SIZE; + length == AUD_DEFAULT_BUFFER_SIZE && !eos; len -= AUD_DEFAULT_BUFFER_SIZE) { if(len < AUD_DEFAULT_BUFFER_SIZE) length = len; - m_reader->read(length, buffer.getBuffer()); + + m_reader->read(length, eos, buffer.getBuffer()); } } } @@ -80,18 +82,50 @@ int AUD_LimiterReader::getPosition() const return AUD_MIN(pos, m_end) - m_start; } -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; + eos = true; + } + + if(position < m_start) + { + int len2 = length; + for(int len = m_start - position; + len2 == length && !eos; + len -= length) + { + if(len < length) + len2 = len; + + m_reader->read(len2, eos, buffer); + position += len2; + } + + if(position < m_start) + { + 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); } diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h index 660dc26b7a3..5a12b990eee 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.h +++ b/intern/audaspace/FX/AUD_LimiterReader.h @@ -67,7 +67,7 @@ public: virtual void seek(int position); virtual int getLength() const; virtual int getPosition() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_LIMITERREADER diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp index 0efee5b55c0..de67a445ab2 100644 --- a/intern/audaspace/FX/AUD_LoopReader.cpp +++ b/intern/audaspace/FX/AUD_LoopReader.cpp @@ -68,21 +68,20 @@ int AUD_LoopReader::getPosition() const return m_reader->getPosition() * (m_count < 0 ? 1 : m_count); } -void AUD_LoopReader::read(int & length, sample_t* buffer) +void AUD_LoopReader::read(int& length, bool& eos, sample_t* buffer) { - AUD_Specs specs = m_reader->getSpecs(); + const AUD_Specs specs = m_reader->getSpecs(); int len = length; - m_reader->read(len, buffer); + m_reader->read(length, eos, buffer); - if(len < length && m_left) + if(length < len && eos && m_left) { - int pos = 0; - - pos += len; + int pos = length; + length = len; - while(pos < length && m_left) + while(pos < length && eos && m_left) { if(m_left > 0) m_left--; @@ -90,7 +89,7 @@ void AUD_LoopReader::read(int & length, sample_t* buffer) m_reader->seek(0); len = length - pos; - m_reader->read(len, buffer + pos * specs.channels); + m_reader->read(len, eos, buffer + pos * specs.channels); // prevent endless loop if(!len) @@ -101,6 +100,4 @@ void AUD_LoopReader::read(int & length, sample_t* buffer) length = pos; } - else - length = len; } diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h index d1338245df4..5ccf7e543a0 100644 --- a/intern/audaspace/FX/AUD_LoopReader.h +++ b/intern/audaspace/FX/AUD_LoopReader.h @@ -68,7 +68,7 @@ public: virtual void seek(int position); virtual int getLength() const; virtual int getPosition() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_LOOPREADER diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp index 3d5828dd129..1a5083d3eb4 100644 --- a/intern/audaspace/FX/AUD_ReverseReader.cpp +++ b/intern/audaspace/FX/AUD_ReverseReader.cpp @@ -60,7 +60,7 @@ int AUD_ReverseReader::getPosition() const return m_position; } -void AUD_ReverseReader::read(int & length, sample_t* buffer) +void AUD_ReverseReader::read(int& length, bool& eos, sample_t* buffer) { // first correct the length if(m_position + length > m_length) @@ -69,6 +69,7 @@ void AUD_ReverseReader::read(int & length, sample_t* buffer) if(length <= 0) { length = 0; + eos = true; return; } @@ -81,7 +82,7 @@ void AUD_ReverseReader::read(int & length, sample_t* buffer) // read from reader m_reader->seek(m_length - m_position - len); - m_reader->read(len, buffer); + m_reader->read(len, eos, buffer); // set null if reader didn't give enough data if(len < length) @@ -102,4 +103,5 @@ void AUD_ReverseReader::read(int & length, sample_t* buffer) } m_position += length; + eos = false; } diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h index 8525acaab36..da0add9464e 100644 --- a/intern/audaspace/FX/AUD_ReverseReader.h +++ b/intern/audaspace/FX/AUD_ReverseReader.h @@ -68,7 +68,7 @@ public: virtual void seek(int position); virtual int getLength() const; virtual int getPosition() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_REVERSEREADER diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp index 49e29d2b0f9..fadd064da76 100644 --- a/intern/audaspace/FX/AUD_SuperposeReader.cpp +++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp @@ -82,7 +82,7 @@ AUD_Specs AUD_SuperposeReader::getSpecs() const return m_reader1->getSpecs(); } -void AUD_SuperposeReader::read(int & length, sample_t* buffer) +void AUD_SuperposeReader::read(int& length, bool& eos, sample_t* buffer) { AUD_Specs specs = m_reader1->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); @@ -90,17 +90,19 @@ void AUD_SuperposeReader::read(int & length, sample_t* buffer) m_buffer.assureSize(length * samplesize); int len1 = length; - m_reader1->read(len1, buffer); + m_reader1->read(len1, eos, buffer); if(len1 < length) memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize); int len2 = length; + bool eos2; sample_t* buf = m_buffer.getBuffer(); - m_reader2->read(len2, buf); + m_reader2->read(len2, eos2, buf); for(int i = 0; i < len2 * specs.channels; i++) buffer[i] += buf[i]; length = AUD_MAX(len1, len2); + eos &= eos2; } diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h index 5a2a2a1d8d1..a87f1fdb739 100644 --- a/intern/audaspace/FX/AUD_SuperposeReader.h +++ b/intern/audaspace/FX/AUD_SuperposeReader.h @@ -80,7 +80,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SUPERPOSEREADER diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 18c50d29225..465ad5b5ae6 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -70,7 +70,7 @@ struct AUD_OpenALHandle : AUD_Handle int current; /// Whether the stream doesn't return any more data. - bool data_end; + bool eos; /// The loop count of the source. int loopcount; @@ -166,11 +166,11 @@ void AUD_OpenALDevice::updateStreams() while(info--) { // if there's still data to play back - if(!sound->data_end) + if(!sound->eos) { // read data length = m_buffersize; - sound->reader->read(length, m_buffer.getBuffer()); + sound->reader->read(length, sound->eos, m_buffer.getBuffer()); // looping necessary? if(length == 0 && sound->loopcount) @@ -181,13 +181,15 @@ void AUD_OpenALDevice::updateStreams() sound->reader->seek(0); length = m_buffersize; - sound->reader->read(length, m_buffer.getBuffer()); + sound->reader->read(length, sound->eos, m_buffer.getBuffer()); } + if(sound->loopcount != 0) + sound->eos = false; + // read nothing? if(length == 0) { - sound->data_end = true; break; } @@ -197,7 +199,7 @@ void AUD_OpenALDevice::updateStreams() ALenum err; if((err = alGetError()) != AL_NO_ERROR) { - sound->data_end = true; + sound->eos = true; break; } @@ -210,7 +212,7 @@ void AUD_OpenALDevice::updateStreams() if((err = alGetError()) != AL_NO_ERROR) { - sound->data_end = true; + sound->eos = true; break; } @@ -219,7 +221,7 @@ void AUD_OpenALDevice::updateStreams() &sound->buffers[sound->current]); if(alGetError() != AL_NO_ERROR) { - sound->data_end = true; + sound->eos = true; break; } @@ -238,7 +240,7 @@ void AUD_OpenALDevice::updateStreams() if(info != AL_PLAYING) { // if it really stopped - if(sound->data_end) + if(sound->eos) { if(sound->stop) sound->stop(sound->stop_data); @@ -556,7 +558,6 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep) sound->reader = reader; sound->current = 0; sound->isBuffered = false; - sound->data_end = false; sound->loopcount = 0; sound->stop = NULL; sound->stop_data = NULL; @@ -587,7 +588,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep) for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++) { length = m_buffersize; - reader->read(length, m_buffer.getBuffer()); + reader->read(length,sound->eos, m_buffer.getBuffer()); alBufferData(sound->buffers[i], sound->format, m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate); @@ -658,7 +659,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool kee sound->keep = keep; sound->current = -1; sound->isBuffered = true; - sound->data_end = true; + sound->eos = true; sound->loopcount = 0; sound->stop = NULL; sound->stop_data = NULL; @@ -862,7 +863,7 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) { alhandle->reader->seek((int)(position * alhandle->reader->getSpecs().rate)); - alhandle->data_end = false; + alhandle->eos = false; ALint info; @@ -887,7 +888,7 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++) { length = m_buffersize; - alhandle->reader->read(length, m_buffer.getBuffer()); + alhandle->reader->read(length, alhandle->eos, m_buffer.getBuffer()); alBufferData(alhandle->buffers[i], alhandle->format, m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), @@ -897,6 +898,9 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) break; } + if(alhandle->loopcount != 0) + alhandle->eos = false; + alSourceQueueBuffers(alhandle->source, AUD_OPENAL_CYCLE_BUFFERS, alhandle->buffers); @@ -1045,7 +1049,10 @@ bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count) lock(); bool result = isValid(handle); if(result) + { ((AUD_OpenALHandle*)handle)->loopcount = count; + ((AUD_OpenALHandle*)handle)->eos = false; + } unlock(); return result; } diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp index 85f935bab8e..59854a7a2c4 100644 --- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp +++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp @@ -77,7 +77,7 @@ long AUD_SRCResampleReader::doCallback(float** data) int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(m_tspecs); *data = m_buffer.getBuffer(); - m_reader->read(length, *data); + m_reader->read(length, m_eos, *data); return length; } @@ -104,13 +104,17 @@ AUD_Specs AUD_SRCResampleReader::getSpecs() const return m_tspecs; } -void AUD_SRCResampleReader::read(int & length, sample_t* buffer) +void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer) { - int size = length * AUD_SAMPLE_SIZE(m_tspecs); + int size = length; - m_buffer.assureSize(size); + m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_tspecs)); + + m_eos = false; length = src_callback_read(m_src, m_factor, length, buffer); m_position += length; + + eos = m_eos && (length < size); } diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h index 2d67e636bd7..5b210a61e70 100644 --- a/intern/audaspace/SRC/AUD_SRCResampleReader.h +++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h @@ -73,6 +73,11 @@ private: */ int m_position; + /** + * Whether reader reached end of stream. + */ + bool m_eos; + // hide copy constructor and operator= AUD_SRCResampleReader(const AUD_SRCResampleReader&); AUD_SRCResampleReader& operator=(const AUD_SRCResampleReader&); @@ -104,7 +109,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SRCRESAMPLEREADER diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index bacbbf2a725..852b93d24a8 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -342,13 +342,14 @@ void AUD_FFMPEGReader::seek(int position) // read until we're at the right position int length = AUD_DEFAULT_BUFFER_SIZE; AUD_Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs)); + bool eos; for(int len = position - m_position; length == AUD_DEFAULT_BUFFER_SIZE; len -= AUD_DEFAULT_BUFFER_SIZE) { if(len < AUD_DEFAULT_BUFFER_SIZE) length = len; - read(length, buffer.getBuffer()); + read(length, eos, buffer.getBuffer()); } } } @@ -381,7 +382,7 @@ AUD_Specs AUD_FFMPEGReader::getSpecs() const return m_specs.specs; } -void AUD_FFMPEGReader::read(int & length, sample_t* buffer) +void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer) { // read packages and decode them AVPacket packet; @@ -431,7 +432,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* buffer) pkgbuf_pos-data_size); } - if(left > 0) + if(eos = (left > 0)) length -= left; + m_position += length; } diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h index c5bfd11dcbc..06d6fe1e5f6 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h @@ -162,7 +162,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_FFMPEGREADER diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp index 08ed52ea497..3ab226558ac 100644 --- a/intern/audaspace/intern/AUD_BufferReader.cpp +++ b/intern/audaspace/intern/AUD_BufferReader.cpp @@ -66,7 +66,7 @@ AUD_Specs AUD_BufferReader::getSpecs() const return m_specs; } -void AUD_BufferReader::read(int & length, sample_t* buffer) +void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer) { int sample_size = AUD_SAMPLE_SIZE(m_specs); @@ -74,7 +74,10 @@ void AUD_BufferReader::read(int & length, sample_t* buffer) // in case the end of the buffer is reached if(m_buffer->getSize() < (m_position + length) * sample_size) + { length = m_buffer->getSize() / sample_size - m_position; + eos = true; + } if(length < 0) { diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h index 16d7136ab63..5ba6c503855 100644 --- a/intern/audaspace/intern/AUD_BufferReader.h +++ b/intern/audaspace/intern/AUD_BufferReader.h @@ -76,7 +76,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_BUFFERREADER diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 61d7616f694..0b2e782925c 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -804,13 +804,14 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high, int len; int position = 0; + bool eos; do { len = samplerate; buffer.resize((position + len) * sizeof(float), true); - reader->read(len, buffer.getBuffer() + position); + reader->read(len, eos, buffer.getBuffer() + position); position += len; - } while(len != 0); + } while(!eos); float* result = (float*)malloc(position * sizeof(float)); memcpy(result, buffer.getBuffer(), position * sizeof(float)); @@ -903,6 +904,7 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length) int len = reader->getLength(); float samplejump = (float)len / (float)length; float min, max; + bool eos; for(int i = 0; i < length; i++) { @@ -914,9 +916,9 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length) buf = aBuffer.getBuffer(); } - reader->read(len, buf); + reader->read(len, eos, buf); - if(len < 1) + if(eos) { length = i; break; diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp index bfc5596bb21..5c135153d0e 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp @@ -76,13 +76,13 @@ AUD_Specs AUD_ChannelMapperReader::getSpecs() const return m_specs; } -void AUD_ChannelMapperReader::read(int & length, sample_t* buffer) +void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer) { m_buffer.assureSize(length * m_rch * sizeof(sample_t)); sample_t* in = m_buffer.getBuffer(); - m_reader->read(length, in); + m_reader->read(length, eos, in); sample_t sum; diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h index 31c22b8cf5a..b1246c08f75 100644 --- a/intern/audaspace/intern/AUD_ChannelMapperReader.h +++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h @@ -80,7 +80,7 @@ public: ~AUD_ChannelMapperReader(); virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_CHANNELMAPPERREADER diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp index 4fed746c96b..60d8bda5ef6 100644 --- a/intern/audaspace/intern/AUD_ConverterReader.cpp +++ b/intern/audaspace/intern/AUD_ConverterReader.cpp @@ -75,13 +75,13 @@ AUD_Specs AUD_ConverterReader::getSpecs() const return m_specs.specs; } -void AUD_ConverterReader::read(int & length, sample_t* buffer) +void AUD_ConverterReader::read(int& length, bool& eos, sample_t* buffer) { int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs()); m_buffer.assureSize(length * samplesize); - m_reader->read(length, m_buffer.getBuffer()); + m_reader->read(length, eos, m_buffer.getBuffer()); m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(), length * m_specs.channels); diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h index 958fe6d1897..6fcfa195098 100644 --- a/intern/audaspace/intern/AUD_ConverterReader.h +++ b/intern/audaspace/intern/AUD_ConverterReader.h @@ -70,7 +70,7 @@ public: AUD_ConverterReader(AUD_Reference<AUD_IReader> reader, AUD_DeviceSpecs specs); virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_CONVERTERREADER diff --git a/intern/audaspace/intern/AUD_IReader.h b/intern/audaspace/intern/AUD_IReader.h index 01baf13f540..b1a282c9d49 100644 --- a/intern/audaspace/intern/AUD_IReader.h +++ b/intern/audaspace/intern/AUD_IReader.h @@ -92,15 +92,15 @@ public: /** * Request to read the next length samples out of the source. - * The buffer for reading has to stay valid until the next call of this - * method or until the reader is deleted. + * The buffer supplied has the needed size. * \param[in,out] length The count of samples that should be read. Shall * contain the real count of samples after reading, in case * there were only fewer samples available. * A smaller value also indicates the end of the reader. - * \param[out] buffer The pointer to the buffer with the samples. + * \param[out] eos End of stream, whether the end is reached or not. + * \param[int] buffer The pointer to the buffer to read into. */ - virtual void read(int & length, sample_t* buffer)=0; + virtual void read(int& length, bool& eos, sample_t* buffer)=0; }; #endif //AUD_IREADER diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp index a8bd9749a2b..7e4f7a5b45d 100644 --- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp +++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp @@ -71,18 +71,18 @@ AUD_Specs AUD_LinearResampleReader::getSpecs() const return m_tspecs; } -void AUD_LinearResampleReader::read(int & length, sample_t* buffer) +void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer) { int samplesize = AUD_SAMPLE_SIZE(m_tspecs); - int size = length * AUD_SAMPLE_SIZE(m_sspecs); + int size = length; - m_buffer.assureSize(size); + m_buffer.assureSize(size * AUD_SAMPLE_SIZE(m_sspecs)); int need = ceil((m_position + length) / m_factor) + 1 - m_sposition; int len = need; sample_t* buf = m_buffer.getBuffer(); - m_reader->read(len, buf); + m_reader->read(len, eos, buf); if(len < need) length = floor((m_sposition + len - 1) * m_factor) - m_position; @@ -123,4 +123,5 @@ void AUD_LinearResampleReader::read(int & length, sample_t* buffer) m_sposition += len; m_position += length; + eos &= length < size; } diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h index f673cd0ee66..f7dd0e96aa6 100644 --- a/intern/audaspace/intern/AUD_LinearResampleReader.h +++ b/intern/audaspace/intern/AUD_LinearResampleReader.h @@ -92,7 +92,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_LINEARRESAMPLEREADER diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp index 2cf9222673e..40ac7f3134b 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.cpp +++ b/intern/audaspace/intern/AUD_SequencerReader.cpp @@ -113,7 +113,7 @@ AUD_Specs AUD_SequencerReader::getSpecs() const return m_mixer->getSpecs().specs; } -void AUD_SequencerReader::read(int & length, sample_t* buffer) +void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) { AUD_DeviceSpecs specs = m_mixer->getSpecs(); int rate = specs.rate; @@ -171,7 +171,7 @@ void AUD_SequencerReader::read(int & length, sample_t* buffer) len -= skip; if(strip->reader->getPosition() != current) strip->reader->seek(current); - strip->reader->read(len, m_buffer.getBuffer()); + strip->reader->read(len, eos, m_buffer.getBuffer()); m_mixer->mix(m_buffer.getBuffer(), skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate)); } } @@ -183,4 +183,6 @@ void AUD_SequencerReader::read(int & length, sample_t* buffer) m_mixer->read((data_t*)buffer, 1.0f); m_position += length; + + eos = false; } diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h index 8b90c27ed9e..e769b342d1b 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.h +++ b/intern/audaspace/intern/AUD_SequencerReader.h @@ -100,7 +100,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SEQUENCERREADER diff --git a/intern/audaspace/intern/AUD_SilenceReader.cpp b/intern/audaspace/intern/AUD_SilenceReader.cpp index cd109c2352c..d34fea72bb3 100644 --- a/intern/audaspace/intern/AUD_SilenceReader.cpp +++ b/intern/audaspace/intern/AUD_SilenceReader.cpp @@ -66,8 +66,9 @@ AUD_Specs AUD_SilenceReader::getSpecs() const return specs; } -void AUD_SilenceReader::read(int & length, sample_t* buffer) +void AUD_SilenceReader::read(int& length, bool& eos, sample_t* buffer) { memset(buffer, 0, length * sizeof(sample_t)); m_position += length; + eos = false; } diff --git a/intern/audaspace/intern/AUD_SilenceReader.h b/intern/audaspace/intern/AUD_SilenceReader.h index 753cda896be..29966aef0a7 100644 --- a/intern/audaspace/intern/AUD_SilenceReader.h +++ b/intern/audaspace/intern/AUD_SilenceReader.h @@ -66,7 +66,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SILENCEREADER diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp index d8acd0f1a8f..288e86bb8d3 100644 --- a/intern/audaspace/intern/AUD_SinusReader.cpp +++ b/intern/audaspace/intern/AUD_SinusReader.cpp @@ -72,7 +72,7 @@ AUD_Specs AUD_SinusReader::getSpecs() const return specs; } -void AUD_SinusReader::read(int & length, sample_t* buffer) +void AUD_SinusReader::read(int& length, bool& eos, sample_t* buffer) { // fill with sine data for(int i = 0; i < length; i++) @@ -82,4 +82,5 @@ void AUD_SinusReader::read(int & length, sample_t* buffer) } m_position += length; + eos = false; } diff --git a/intern/audaspace/intern/AUD_SinusReader.h b/intern/audaspace/intern/AUD_SinusReader.h index dca00c15637..69e9a3ca576 100644 --- a/intern/audaspace/intern/AUD_SinusReader.h +++ b/intern/audaspace/intern/AUD_SinusReader.h @@ -78,7 +78,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SINUSREADER diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index f80d3d12748..f522772fc61 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -112,6 +112,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) AUD_SoftwareHandle* sound; int len; int pos; + bool eos; std::list<AUD_SoftwareHandle*> stopSounds; sample_t* buf = m_buffer.getBuffer(); @@ -130,10 +131,10 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) pos = 0; len = length; - sound->reader->read(len, buf); + sound->reader->read(len, eos, buf); // in case of looping - while(pos + len < length && sound->loopcount) + while(pos + len < length && sound->loopcount && eos) { m_mixer->mix(buf, pos, len, sound->volume); @@ -145,7 +146,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) sound->reader->seek(0); len = length - pos; - sound->reader->read(len, buf); + sound->reader->read(len, eos, buf); // prevent endless loop if(!len) @@ -156,7 +157,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) pos += len; // in case the end of the sound is reached - if(pos < length) + if(eos && !sound->loopcount) { if(sound->stop) sound->stop(sound->stop_data); diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp index 64e22637329..ff966c86025 100644 --- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp +++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp @@ -45,6 +45,7 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> fac int sample_size = AUD_SAMPLE_SIZE(m_specs); int length; int index = 0; + bool eos = false; // get an approximated size if possible int size = reader->getLength(); @@ -54,16 +55,17 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> fac else size += m_specs.rate; - // as long as we fill our buffer to the end - while(index == m_buffer->getSize() / sample_size) + // as long as the end of the stream is not reached + while(!eos) { // increase m_buffer->resize(size*sample_size, true); // read more length = size-index; - reader->read(length, m_buffer->getBuffer() + index * m_specs.channels); - size += AUD_BUFFER_RESIZE_BYTES / sample_size; + reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels); + if(index == m_buffer->getSize() / sample_size) + size += AUD_BUFFER_RESIZE_BYTES / sample_size; index += length; } diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp index cfe42b0725d..16c90b6f0f1 100644 --- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp +++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp @@ -161,9 +161,13 @@ AUD_Specs AUD_SndFileReader::getSpecs() const return m_specs; } -void AUD_SndFileReader::read(int & length, sample_t* buffer) +void AUD_SndFileReader::read(int& length, bool& eos, sample_t* buffer) { + int olen = length; + length = sf_readf_float(m_sndfile, buffer, length); m_position += length; + + eos = length < olen; } diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h index 54ab05c63da..e7f9e9bf6d6 100644 --- a/intern/audaspace/sndfile/AUD_SndFileReader.h +++ b/intern/audaspace/sndfile/AUD_SndFileReader.h @@ -124,7 +124,7 @@ public: virtual int getLength() const; virtual int getPosition() const; virtual AUD_Specs getSpecs() const; - virtual void read(int & length, sample_t* buffer); + virtual void read(int& length, bool& eos, sample_t* buffer); }; #endif //AUD_SNDFILEREADER |