3D Audio GSoC:
authorJoerg Mueller <nexyon@gmail.com>
Tue, 21 Jun 2011 20:14:53 +0000 (20:14 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Tue, 21 Jun 2011 20:14:53 +0000 (20:14 +0000)
Streaming improved.

43 files changed:
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
intern/audaspace/FX/AUD_BaseIIRFilterReader.h
intern/audaspace/FX/AUD_DelayReader.cpp
intern/audaspace/FX/AUD_DelayReader.h
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_DoubleReader.h
intern/audaspace/FX/AUD_EffectReader.cpp
intern/audaspace/FX/AUD_EffectReader.h
intern/audaspace/FX/AUD_FaderReader.cpp
intern/audaspace/FX/AUD_FaderReader.h
intern/audaspace/FX/AUD_LimiterReader.cpp
intern/audaspace/FX/AUD_LimiterReader.h
intern/audaspace/FX/AUD_LoopReader.cpp
intern/audaspace/FX/AUD_LoopReader.h
intern/audaspace/FX/AUD_ReverseReader.cpp
intern/audaspace/FX/AUD_ReverseReader.h
intern/audaspace/FX/AUD_SuperposeReader.cpp
intern/audaspace/FX/AUD_SuperposeReader.h
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/SRC/AUD_SRCResampleReader.cpp
intern/audaspace/SRC/AUD_SRCResampleReader.h
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
intern/audaspace/intern/AUD_BufferReader.cpp
intern/audaspace/intern/AUD_BufferReader.h
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_ChannelMapperReader.cpp
intern/audaspace/intern/AUD_ChannelMapperReader.h
intern/audaspace/intern/AUD_ConverterReader.cpp
intern/audaspace/intern/AUD_ConverterReader.h
intern/audaspace/intern/AUD_IReader.h
intern/audaspace/intern/AUD_LinearResampleReader.cpp
intern/audaspace/intern/AUD_LinearResampleReader.h
intern/audaspace/intern/AUD_SequencerReader.cpp
intern/audaspace/intern/AUD_SequencerReader.h
intern/audaspace/intern/AUD_SilenceReader.cpp
intern/audaspace/intern/AUD_SilenceReader.h
intern/audaspace/intern/AUD_SinusReader.cpp
intern/audaspace/intern/AUD_SinusReader.h
intern/audaspace/intern/AUD_SoftwareDevice.cpp
intern/audaspace/intern/AUD_StreamBufferFactory.cpp
intern/audaspace/sndfile/AUD_SndFileReader.cpp
intern/audaspace/sndfile/AUD_SndFileReader.h

index 9ddd8af019bd329714754e862f5801241dcdf950..79039ca605b868808b823b66cd0b2f2f5b9318ed 100644 (file)
@@ -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++)
        {
index 2d1f21446a09dfdea1b38ccf98ee33cd586d84c2..a300ff9d24137a5a1c21d49dc71f823cbcf2551a 100644 (file)
@@ -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;
 };
index 2e93184358eacc1884f4ed856391fcb6e4894a49..7d58b3dae4f33c82269e4e85c17df2c864b097fa 100644 (file)
@@ -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);
 }
index cb0ec9bcd9d838f6a67d558c1cc31fc3dd7437e1..a89afe73b372be8e9977a32b3e40c3aa97a1b6f1 100644 (file)
@@ -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
index 605c49066d2ba7a83d970e271786d85bc9a0f7fe..5d9ebbd618708fb9d133930f418bce75f148db92 100644 (file)
@@ -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);
        }
 }
index d68000fe81ae230fa7a32527fb24139aec286c02..86f636e2cb28fa18d760e5227c5fd4421cf78d32 100644 (file)
@@ -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
index aa8fe7a7f354de700e1d6d01302eb631c920d4cd..4d14af76438ac1ede4de8492890b2905ffaf078b 100644 (file)
@@ -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);
 }
index cfb8e5b6e77390f0a382f182cb4cef365c1f55e1..c03abd1182891577e149c485ff58a15170593922 100644 (file)
@@ -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
index 7fe5c503c23f83d803688a7ef9e86e3e084acc33..4a6050cf0f359984310b56df07f63b9d5f72aa67 100644 (file)
@@ -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)
        {
index c0eb3d27d368cab0862099d81093b6a71c6fe3f4..e702ac0ec19be9c79792d5bcfd03bb1189fadc04 100644 (file)
@@ -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
index 0f87679410e5d4690a8af36ef453973524ab46a1..52add8635e3b0bbb17ca2f8866bda295d0c1dd13 100644 (file)
@@ -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);
 }
index 660dc26b7a3f2fc99fb40e0a3f5e11747ffc4a69..5a12b990eee99070d2bb48355e3c910f1dd75f01 100644 (file)
@@ -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
index 0efee5b55c0b47594fbe5fc86f637c6cd5bf1f0f..de67a445ab2d29a52b0a8e7d00dfcdaf8a96261b 100644 (file)
@@ -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;
 }
index d1338245df4168d99b3db6ebd7de19a64cf0d125..5ccf7e543a0c7d8d543c249081ad7e933870bb19 100644 (file)
@@ -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
index 3d5828dd129909752af94b3758b7d071f4dce5e9..1a5083d3eb4d3a4d91b6a0968d6fe87e7a2d4eae 100644 (file)
@@ -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;
 }
index 8525acaab36aaef4d3bc3f5103296c3d6a4a54e2..da0add9464e49b89c06dc4eb988e761115ebb16f 100644 (file)
@@ -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
index 49e29d2b0f9d3f951956a4ed128019c0eda2a5ef..fadd064da7601b2af7ac9ae255e6703441ecd037 100644 (file)
@@ -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;
 }
index 5a2a2a1d8d1d8431ac1934409eb5fece5392e163..a87f1fdb739e42b3c4c429491487302b2774faa6 100644 (file)
@@ -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
index 18c50d292258cd1930bf22c354a02a7379396e9c..465ad5b5ae6f53fc28b606597f5ed6c7802ea7e8 100644 (file)
@@ -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;
 }
index 85f935bab8ee5ef3a810119c8ed7d23426f993a9..59854a7a2c439a68687da353eba1d8ca00773dea 100644 (file)
@@ -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);
 }
index 2d67e636bd70f7a1dfa472e2d47bb73663b781d7..5b210a61e70294cce26520a14eceba78045ddac9 100644 (file)
@@ -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
index bacbbf2a725971f4a5d929d91a4ca8eaaa315486..852b93d24a8ee023377bc40c3ff244698883caff 100644 (file)
@@ -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;
 }
index c5bfd11dcbce40740a7aba7b91241b355818c091..06d6fe1e5f699a566e188eabef5aa22999583454 100644 (file)
@@ -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
index 08ed52ea497aec12a6f4b987246da00a2e6bedd9..3ab226558acd510b922d8376afdc5e395d0099fb 100644 (file)
@@ -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)
        {
index 16d7136ab63d0b04db40ad2e855e063afc35d52d..5ba6c5038558c8ac39015aab106657eef0e024f4 100644 (file)
@@ -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
index 61d7616f6946f26fd6abf850ca68ece8d32163fa..0b2e782925ce7e78485901ca6bbb5e19793f46dc 100644 (file)
@@ -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;
index bfc5596bb21d676354ab49932a9e25394c81aded..5c135153d0e2a52a6d94c6ab863ce5c814865bde 100644 (file)
@@ -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;
 
index 31c22b8cf5aaf7e4d7cf25438505db04914be772..b1246c08f75f8b190fcb6f6ab61e3f174cdcec7a 100644 (file)
@@ -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
index 4fed746c96ba6b8488cd804e1a2ef9111fcda930..60d8bda5ef6d031ebb424a6a2bfea5b2b0432724 100644 (file)
@@ -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);
index 958fe6d1897ce24276bebdbd231355c45538b0ae..6fcfa195098b130fc92a4815529d6579b448927c 100644 (file)
@@ -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
index 01baf13f540427b1f7d2dd4706a156ec60553876..b1a282c9d495351484617cacc0dada7d370bc89a 100644 (file)
@@ -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
index a8bd9749a2b514debaa546dc0b69b8974f265f0b..7e4f7a5b45d132bc92b466fcfa1c367ca1018035 100644 (file)
@@ -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;
 }
index f673cd0ee661c90041a7745a6ab74aa3e9eb9fdd..f7dd0e96aa6a93b113d024810d072619ae65a814 100644 (file)
@@ -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
index 2cf9222673e8aa262700f9729661c278cb091641..40ac7f3134ba79f20e661a36ab9c4e12b8f6ccaf 100644 (file)
@@ -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;
 }
index 8b90c27ed9e80a9267ecadc03b98307b792099a6..e769b342d1b1a51aeef4c4810eaa4b2c99494d64 100644 (file)
@@ -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
index cd109c2352cf65631af646174e346169f043f2bd..d34fea72bb3486312969a0dadc59d35f26ebdaa8 100644 (file)
@@ -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;
 }
index 753cda896be48ed1301ec142834cad1eadcc97bb..29966aef0a7440094c0c3238e3a92cc849c016a8 100644 (file)
@@ -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
index d8acd0f1a8f684874431b3c5bc7699232951717f..288e86bb8d32c653f094be2dcab586d088647fdf 100644 (file)
@@ -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;
 }
index dca00c156377927573f00529d1d4b2fb156479d9..69e9a3ca576ac75b77ed16aec492cdd2d926355b 100644 (file)
@@ -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
index f80d3d12748a393dd6aa552910e8b8d0a887e83b..f522772fc61c3d666e1ab36960884aada950a8ab 100644 (file)
@@ -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);
index 64e226373293f4407b5c68b374934df057c1232e..ff966c8602582e373d404ea16f41fe2271b584d7 100644 (file)
@@ -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;
        }
 
index cfe42b0725d71df4987f4cd47f2faa3596dbc3ad..16c90b6f0f1ba20013e9a7ad1857f4a96dd844ba 100644 (file)
@@ -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;
 }
index 54ab05c63dad6912bfc38bef0aed14363d29552e..e7f9e9bf6d65abd14b67e7fa91f57cda7365bade 100644 (file)
@@ -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