|
Blender
V2.59
|
00001 /* 00002 * $Id: AUD_LoopReader.cpp 35141 2011-02-25 10:21:56Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * Copyright 2009-2011 Jörg Hermann Müller 00007 * 00008 * This file is part of AudaSpace. 00009 * 00010 * Audaspace is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * AudaSpace is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with Audaspace; if not, write to the Free Software Foundation, 00022 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include "AUD_LoopReader.h" 00033 #include "AUD_Buffer.h" 00034 00035 #include <cstring> 00036 00037 AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) : 00038 AUD_EffectReader(reader), m_count(loop), m_left(loop) 00039 { 00040 } 00041 00042 void AUD_LoopReader::seek(int position) 00043 { 00044 int len = m_reader->getLength(); 00045 if(len < 0) 00046 m_reader->seek(position); 00047 else 00048 { 00049 if(m_count >= 0) 00050 { 00051 m_left = m_count - (position / len); 00052 if(m_left < 0) 00053 m_left = 0; 00054 } 00055 m_reader->seek(position % len); 00056 } 00057 } 00058 00059 int AUD_LoopReader::getLength() const 00060 { 00061 if(m_count < 0) 00062 return -1; 00063 return m_reader->getLength() * m_count; 00064 } 00065 00066 int AUD_LoopReader::getPosition() const 00067 { 00068 return m_reader->getPosition() * (m_count < 0 ? 1 : m_count); 00069 } 00070 00071 void AUD_LoopReader::read(int & length, sample_t* & buffer) 00072 { 00073 AUD_Specs specs = m_reader->getSpecs(); 00074 int samplesize = AUD_SAMPLE_SIZE(specs); 00075 00076 int len = length; 00077 00078 m_reader->read(len, buffer); 00079 00080 if(len < length && m_left) 00081 { 00082 int pos = 0; 00083 00084 if(m_buffer.getSize() < length * samplesize) 00085 m_buffer.resize(length * samplesize); 00086 00087 sample_t* buf = m_buffer.getBuffer(); 00088 00089 memcpy(buf + pos * specs.channels, buffer, len * samplesize); 00090 00091 pos += len; 00092 00093 while(pos < length && m_left) 00094 { 00095 if(m_left > 0) 00096 m_left--; 00097 00098 m_reader->seek(0); 00099 00100 len = length - pos; 00101 m_reader->read(len, buffer); 00102 00103 // prevent endless loop 00104 if(!len) 00105 break; 00106 00107 memcpy(buf + pos * specs.channels, buffer, len * samplesize); 00108 00109 pos += len; 00110 } 00111 00112 length = pos; 00113 buffer = buf; 00114 } 00115 else 00116 length = len; 00117 }