Blender V2.61 - r43446

AUD_LimiterReader.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * Copyright 2009-2011 Jörg Hermann Müller
00005  *
00006  * This file is part of AudaSpace.
00007  *
00008  * Audaspace is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * AudaSpace is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with Audaspace; if not, write to the Free Software Foundation,
00020  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021  *
00022  * ***** END GPL LICENSE BLOCK *****
00023  */
00024 
00030 #include "AUD_LimiterReader.h"
00031 #include "AUD_Buffer.h"
00032 
00033 AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader,
00034                                      float start, float end) :
00035         AUD_EffectReader(reader),
00036         m_start(start),
00037         m_end(end)
00038 {
00039     if(m_start > 0)
00040     {
00041         AUD_Specs specs = m_reader->getSpecs();
00042         AUD_Specs specs2;
00043 
00044         if(m_reader->isSeekable())
00045             m_reader->seek(m_start * specs.rate);
00046         else
00047         {
00048             // skip first m_start samples by reading them
00049             int length = AUD_DEFAULT_BUFFER_SIZE;
00050             AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
00051             bool eos = false;
00052             for(int len = m_start * specs.rate;
00053                 length > 0 && !eos;
00054                 len -= length)
00055             {
00056                 if(len < AUD_DEFAULT_BUFFER_SIZE)
00057                     length = len;
00058 
00059                 m_reader->read(length, eos, buffer.getBuffer());
00060 
00061                 specs2 = m_reader->getSpecs();
00062                 if(specs2.rate != specs.rate)
00063                 {
00064                     len = len * specs2.rate / specs.rate;
00065                     specs.rate = specs2.rate;
00066                 }
00067 
00068                 if(specs2.channels != specs.channels)
00069                 {
00070                     specs = specs2;
00071                     buffer.assureSize(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
00072                 }
00073             }
00074         }
00075     }
00076 }
00077 
00078 void AUD_LimiterReader::seek(int position)
00079 {
00080     m_reader->seek(position + m_start * m_reader->getSpecs().rate);
00081 }
00082 
00083 int AUD_LimiterReader::getLength() const
00084 {
00085     int len = m_reader->getLength();
00086     AUD_SampleRate rate = m_reader->getSpecs().rate;
00087     if(len < 0 || (len > m_end * rate && m_end >= 0))
00088         len = m_end * rate;
00089     return len - m_start * rate;
00090 }
00091 
00092 int AUD_LimiterReader::getPosition() const
00093 {
00094     int pos = m_reader->getPosition();
00095     AUD_SampleRate rate = m_reader->getSpecs().rate;
00096     return AUD_MIN(pos, m_end * rate) - m_start * rate;
00097 }
00098 
00099 void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
00100 {
00101     eos = false;
00102     if(m_end >= 0)
00103     {
00104         int position = m_reader->getPosition();
00105         AUD_SampleRate rate = m_reader->getSpecs().rate;
00106 
00107         if(position + length > m_end * rate)
00108         {
00109             length = m_end * rate - position;
00110             eos = true;
00111         }
00112 
00113         if(position < m_start * rate)
00114         {
00115             int len2 = length;
00116             for(int len = m_start * rate - position;
00117                 len2 == length && !eos;
00118                 len -= length)
00119             {
00120                 if(len < length)
00121                     len2 = len;
00122 
00123                 m_reader->read(len2, eos, buffer);
00124                 position += len2;
00125             }
00126 
00127             if(position < m_start * rate)
00128             {
00129                 length = 0;
00130                 return;
00131             }
00132         }
00133 
00134         if(length < 0)
00135         {
00136             length = 0;
00137             return;
00138         }
00139     }
00140     if(eos)
00141     {
00142         m_reader->read(length, eos, buffer);
00143         eos = true;
00144     }
00145     else
00146         m_reader->read(length, eos, buffer);
00147 }