Blender V2.61 - r43446
|
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 }