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