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_SndFileReader.h" 00031 00032 #include <cstring> 00033 00034 sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data) 00035 { 00036 AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data; 00037 return reader->m_membuffer->getSize(); 00038 } 00039 00040 sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, 00041 void *user_data) 00042 { 00043 AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data; 00044 00045 switch(whence) 00046 { 00047 case SEEK_SET: 00048 reader->m_memoffset = offset; 00049 break; 00050 case SEEK_CUR: 00051 reader->m_memoffset = reader->m_memoffset + offset; 00052 break; 00053 case SEEK_END: 00054 reader->m_memoffset = reader->m_membuffer->getSize() + offset; 00055 break; 00056 } 00057 00058 return reader->m_memoffset; 00059 } 00060 00061 sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, 00062 void *user_data) 00063 { 00064 AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data; 00065 00066 if(reader->m_memoffset + count > reader->m_membuffer->getSize()) 00067 count = reader->m_membuffer->getSize() - reader->m_memoffset; 00068 00069 memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) + 00070 reader->m_memoffset, count); 00071 reader->m_memoffset += count; 00072 00073 return count; 00074 } 00075 00076 sf_count_t AUD_SndFileReader::vio_tell(void *user_data) 00077 { 00078 AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data; 00079 00080 return reader->m_memoffset; 00081 } 00082 00083 static const char* fileopen_error = "AUD_SndFileReader: File couldn't be " 00084 "read."; 00085 00086 AUD_SndFileReader::AUD_SndFileReader(std::string filename) : 00087 m_position(0) 00088 { 00089 SF_INFO sfinfo; 00090 00091 sfinfo.format = 0; 00092 m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo); 00093 00094 if(!m_sndfile) 00095 AUD_THROW(AUD_ERROR_FILE, fileopen_error); 00096 00097 m_specs.channels = (AUD_Channels) sfinfo.channels; 00098 m_specs.rate = (AUD_SampleRate) sfinfo.samplerate; 00099 m_length = sfinfo.frames; 00100 m_seekable = sfinfo.seekable; 00101 } 00102 00103 AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer) : 00104 m_position(0), 00105 m_membuffer(buffer), 00106 m_memoffset(0) 00107 { 00108 m_vio.get_filelen = vio_get_filelen; 00109 m_vio.read = vio_read; 00110 m_vio.seek = vio_seek; 00111 m_vio.tell = vio_tell; 00112 m_vio.write = NULL; 00113 00114 SF_INFO sfinfo; 00115 00116 sfinfo.format = 0; 00117 m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this); 00118 00119 if(!m_sndfile) 00120 AUD_THROW(AUD_ERROR_FILE, fileopen_error); 00121 00122 m_specs.channels = (AUD_Channels) sfinfo.channels; 00123 m_specs.rate = (AUD_SampleRate) sfinfo.samplerate; 00124 m_length = sfinfo.frames; 00125 m_seekable = sfinfo.seekable; 00126 } 00127 00128 AUD_SndFileReader::~AUD_SndFileReader() 00129 { 00130 sf_close(m_sndfile); 00131 } 00132 00133 bool AUD_SndFileReader::isSeekable() const 00134 { 00135 return m_seekable; 00136 } 00137 00138 void AUD_SndFileReader::seek(int position) 00139 { 00140 if(m_seekable) 00141 { 00142 position = sf_seek(m_sndfile, position, SEEK_SET); 00143 m_position = position; 00144 } 00145 } 00146 00147 int AUD_SndFileReader::getLength() const 00148 { 00149 return m_length; 00150 } 00151 00152 int AUD_SndFileReader::getPosition() const 00153 { 00154 return m_position; 00155 } 00156 00157 AUD_Specs AUD_SndFileReader::getSpecs() const 00158 { 00159 return m_specs; 00160 } 00161 00162 void AUD_SndFileReader::read(int& length, bool& eos, sample_t* buffer) 00163 { 00164 int olen = length; 00165 00166 length = sf_readf_float(m_sndfile, buffer, length); 00167 00168 m_position += length; 00169 00170 eos = length < olen; 00171 }