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_SRCResampleReader.h" 00031 00032 #include <cmath> 00033 #include <cstring> 00034 #include <cstdio> 00035 00036 static long src_callback(void *cb_data, float **data) 00037 { 00038 return ((AUD_SRCResampleReader*)cb_data)->doCallback(data); 00039 } 00040 00041 static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be " 00042 "created."; 00043 00044 AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, 00045 AUD_Specs specs) : 00046 AUD_ResampleReader(reader, specs.rate), 00047 m_channels(reader->getSpecs().channels), 00048 m_position(0) 00049 { 00050 int error; 00051 m_src = src_callback_new(src_callback, 00052 SRC_SINC_MEDIUM_QUALITY, 00053 m_channels, 00054 &error, 00055 this); 00056 00057 if(!m_src) 00058 { 00059 // XXX printf("%s\n", src_strerror(error)); 00060 AUD_THROW(AUD_ERROR_SRC, state_error); 00061 } 00062 } 00063 00064 AUD_SRCResampleReader::~AUD_SRCResampleReader() 00065 { 00066 src_delete(m_src); 00067 } 00068 00069 long AUD_SRCResampleReader::doCallback(float** data) 00070 { 00071 AUD_Specs specs; 00072 specs.channels = m_channels; 00073 specs.rate = m_rate; 00074 00075 int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(specs); 00076 00077 *data = m_buffer.getBuffer(); 00078 m_reader->read(length, m_eos, *data); 00079 00080 return length; 00081 } 00082 00083 void AUD_SRCResampleReader::seek(int position) 00084 { 00085 AUD_Specs specs = m_reader->getSpecs(); 00086 double factor = double(m_rate) / double(specs.rate); 00087 m_reader->seek(position / factor); 00088 src_reset(m_src); 00089 m_position = position; 00090 } 00091 00092 int AUD_SRCResampleReader::getLength() const 00093 { 00094 AUD_Specs specs = m_reader->getSpecs(); 00095 double factor = double(m_rate) / double(specs.rate); 00096 return m_reader->getLength() * factor; 00097 } 00098 00099 int AUD_SRCResampleReader::getPosition() const 00100 { 00101 return m_position; 00102 } 00103 00104 AUD_Specs AUD_SRCResampleReader::getSpecs() const 00105 { 00106 AUD_Specs specs = m_reader->getSpecs(); 00107 specs.rate = m_rate; 00108 return specs; 00109 } 00110 00111 void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer) 00112 { 00113 AUD_Specs specs = m_reader->getSpecs(); 00114 00115 double factor = double(m_rate) / double(specs.rate); 00116 00117 specs.rate = m_rate; 00118 00119 int size = length; 00120 00121 m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs)); 00122 00123 if(specs.channels != m_channels) 00124 { 00125 src_delete(m_src); 00126 00127 m_channels = specs.channels; 00128 00129 int error; 00130 m_src = src_callback_new(src_callback, 00131 SRC_SINC_MEDIUM_QUALITY, 00132 m_channels, 00133 &error, 00134 this); 00135 00136 if(!m_src) 00137 { 00138 // XXX printf("%s\n", src_strerror(error)); 00139 AUD_THROW(AUD_ERROR_SRC, state_error); 00140 } 00141 } 00142 00143 m_eos = false; 00144 00145 length = src_callback_read(m_src, factor, length, buffer); 00146 00147 m_position += length; 00148 00149 eos = m_eos && (length < size); 00150 }