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