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_ReverseReader.h" 00031 00032 #include <cstring> 00033 00034 static const char* props_error = "AUD_ReverseReader: The reader has to be " 00035 "seekable and a finite length."; 00036 00037 AUD_ReverseReader::AUD_ReverseReader(AUD_Reference<AUD_IReader> reader) : 00038 AUD_EffectReader(reader), 00039 m_length(reader->getLength()), 00040 m_position(0) 00041 { 00042 if(m_length < 0 || !reader->isSeekable()) 00043 AUD_THROW(AUD_ERROR_PROPS, props_error); 00044 } 00045 00046 void AUD_ReverseReader::seek(int position) 00047 { 00048 m_position = position; 00049 } 00050 00051 int AUD_ReverseReader::getLength() const 00052 { 00053 return m_length; 00054 } 00055 00056 int AUD_ReverseReader::getPosition() const 00057 { 00058 return m_position; 00059 } 00060 00061 void AUD_ReverseReader::read(int& length, bool& eos, sample_t* buffer) 00062 { 00063 // first correct the length 00064 if(m_position + length > m_length) 00065 length = m_length - m_position; 00066 00067 if(length <= 0) 00068 { 00069 length = 0; 00070 eos = true; 00071 return; 00072 } 00073 00074 const AUD_Specs specs = getSpecs(); 00075 const int samplesize = AUD_SAMPLE_SIZE(specs); 00076 00077 sample_t temp[AUD_CHANNEL_MAX]; 00078 00079 int len = length; 00080 00081 // read from reader 00082 m_reader->seek(m_length - m_position - len); 00083 m_reader->read(len, eos, buffer); 00084 00085 // set null if reader didn't give enough data 00086 if(len < length) 00087 memset(buffer, 0, (length - len) * samplesize); 00088 00089 // copy the samples reverted 00090 for(int i = 0; i < length / 2; i++) 00091 { 00092 memcpy(temp, 00093 buffer + (len - 1 - i) * specs.channels, 00094 samplesize); 00095 memcpy(buffer + (len - 1 - i) * specs.channels, 00096 buffer + i * specs.channels, 00097 samplesize); 00098 memcpy(buffer + i * specs.channels, 00099 temp, 00100 samplesize); 00101 } 00102 00103 m_position += length; 00104 eos = false; 00105 }