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_LoopReader.h" 00031 #include "AUD_Buffer.h" 00032 00033 #include <cstring> 00034 00035 AUD_LoopReader::AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop) : 00036 AUD_EffectReader(reader), m_count(loop), m_left(loop) 00037 { 00038 } 00039 00040 void AUD_LoopReader::seek(int position) 00041 { 00042 int len = m_reader->getLength(); 00043 if(len < 0) 00044 m_reader->seek(position); 00045 else 00046 { 00047 if(m_count >= 0) 00048 { 00049 m_left = m_count - (position / len); 00050 if(m_left < 0) 00051 m_left = 0; 00052 } 00053 m_reader->seek(position % len); 00054 } 00055 } 00056 00057 int AUD_LoopReader::getLength() const 00058 { 00059 if(m_count < 0) 00060 return -1; 00061 return m_reader->getLength() * m_count; 00062 } 00063 00064 int AUD_LoopReader::getPosition() const 00065 { 00066 return m_reader->getPosition() * (m_count < 0 ? 1 : m_count); 00067 } 00068 00069 void AUD_LoopReader::read(int& length, bool& eos, sample_t* buffer) 00070 { 00071 const AUD_Specs specs = m_reader->getSpecs(); 00072 00073 int len = length; 00074 00075 m_reader->read(length, eos, buffer); 00076 00077 if(length < len && eos && m_left) 00078 { 00079 int pos = length; 00080 length = len; 00081 00082 while(pos < length && eos && m_left) 00083 { 00084 if(m_left > 0) 00085 m_left--; 00086 00087 m_reader->seek(0); 00088 00089 len = length - pos; 00090 m_reader->read(len, eos, buffer + pos * specs.channels); 00091 00092 // prevent endless loop 00093 if(!len) 00094 break; 00095 00096 pos += len; 00097 } 00098 00099 length = pos; 00100 } 00101 }