|
Blender
V2.59
|
00001 /* 00002 * $Id: AUD_DoubleReader.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_DoubleReader.h" 00033 00034 #include <cstring> 00035 00036 static const char* specs_error = "AUD_DoubleReader: Both readers have to have " 00037 "the same specs."; 00038 00039 AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1, 00040 AUD_IReader* reader2) : 00041 m_reader1(reader1), m_reader2(reader2), m_finished1(false) 00042 { 00043 AUD_Specs s1, s2; 00044 s1 = reader1->getSpecs(); 00045 s2 = reader2->getSpecs(); 00046 if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0) 00047 { 00048 delete reader1; 00049 delete reader2; 00050 AUD_THROW(AUD_ERROR_SPECS, specs_error); 00051 } 00052 } 00053 00054 AUD_DoubleReader::~AUD_DoubleReader() 00055 { 00056 delete m_reader1; 00057 delete m_reader2; 00058 } 00059 00060 bool AUD_DoubleReader::isSeekable() const 00061 { 00062 return m_reader1->isSeekable() && m_reader2->isSeekable(); 00063 } 00064 00065 void AUD_DoubleReader::seek(int position) 00066 { 00067 m_reader1->seek(position); 00068 00069 int pos1 = m_reader1->getPosition(); 00070 00071 if((m_finished1 = (pos1 < position))) 00072 m_reader2->seek(position - pos1); 00073 else 00074 m_reader2->seek(0); 00075 } 00076 00077 int AUD_DoubleReader::getLength() const 00078 { 00079 int len1 = m_reader1->getLength(); 00080 int len2 = m_reader2->getLength(); 00081 if(len1 < 0 || len2 < 0) 00082 return -1; 00083 return len1 + len2; 00084 } 00085 00086 int AUD_DoubleReader::getPosition() const 00087 { 00088 return m_reader1->getPosition() + m_reader2->getPosition(); 00089 } 00090 00091 AUD_Specs AUD_DoubleReader::getSpecs() const 00092 { 00093 return m_reader1->getSpecs(); 00094 } 00095 00096 void AUD_DoubleReader::read(int & length, sample_t* & buffer) 00097 { 00098 if(!m_finished1) 00099 { 00100 int len = length; 00101 m_reader1->read(len, buffer); 00102 00103 if(len < length) 00104 { 00105 AUD_Specs specs = m_reader1->getSpecs(); 00106 int samplesize = AUD_SAMPLE_SIZE(specs); 00107 00108 if(m_buffer.getSize() < length * samplesize) 00109 m_buffer.resize(length * samplesize); 00110 00111 sample_t* buf = buffer; 00112 buffer = m_buffer.getBuffer(); 00113 00114 memcpy(buffer, buf, len * samplesize); 00115 00116 len = length - len; 00117 length -= len; 00118 m_reader2->read(len, buf); 00119 00120 memcpy(buffer + length * specs.channels, buf, 00121 len * samplesize); 00122 00123 length += len; 00124 00125 m_finished1 = true; 00126 } 00127 } 00128 else 00129 { 00130 m_reader2->read(length, buffer); 00131 } 00132 }