|
Blender
V2.59
|
00001 /* 00002 * $Id: AUD_SequencerReader.cpp 36092 2011-04-10 22:40:37Z nexyon $ 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_SequencerReader.h" 00033 #include "AUD_DefaultMixer.h" 00034 00035 #include <math.h> 00036 00037 typedef std::list<AUD_SequencerStrip*>::iterator AUD_StripIterator; 00038 typedef std::list<AUD_SequencerEntry*>::iterator AUD_EntryIterator; 00039 00040 AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory, 00041 std::list<AUD_SequencerEntry*> &entries, AUD_Specs specs, 00042 void* data, AUD_volumeFunction volume) 00043 { 00044 AUD_DeviceSpecs dspecs; 00045 dspecs.specs = specs; 00046 dspecs.format = AUD_FORMAT_FLOAT32; 00047 00048 m_mixer = new AUD_DefaultMixer(dspecs); 00049 m_factory = factory; 00050 m_data = data; 00051 m_volume = volume; 00052 00053 AUD_SequencerStrip* strip; 00054 00055 for(AUD_EntryIterator i = entries.begin(); i != entries.end(); i++) 00056 { 00057 strip = new AUD_SequencerStrip; 00058 strip->entry = *i; 00059 strip->old_sound = NULL; 00060 00061 if(strip->old_sound) 00062 strip->reader = m_mixer->prepare(strip->old_sound->createReader()); 00063 else 00064 strip->reader = NULL; 00065 00066 m_strips.push_front(strip); 00067 } 00068 00069 m_position = 0; 00070 } 00071 00072 AUD_SequencerReader::~AUD_SequencerReader() 00073 { 00074 if(m_factory != NULL) 00075 m_factory->removeReader(this); 00076 00077 AUD_SequencerStrip* strip; 00078 00079 while(!m_strips.empty()) 00080 { 00081 strip = m_strips.front(); 00082 m_strips.pop_front(); 00083 if(strip->reader) 00084 { 00085 delete strip->reader; 00086 } 00087 delete strip; 00088 } 00089 00090 delete m_mixer; 00091 } 00092 00093 void AUD_SequencerReader::destroy() 00094 { 00095 m_factory = NULL; 00096 AUD_SequencerStrip* strip; 00097 00098 while(!m_strips.empty()) 00099 { 00100 strip = m_strips.front(); 00101 m_strips.pop_front(); 00102 delete strip; 00103 } 00104 } 00105 00106 void AUD_SequencerReader::add(AUD_SequencerEntry* entry) 00107 { 00108 AUD_SequencerStrip* strip = new AUD_SequencerStrip; 00109 strip->entry = entry; 00110 00111 if(*strip->entry->sound) 00112 { 00113 strip->old_sound = *strip->entry->sound; 00114 strip->reader = m_mixer->prepare(strip->old_sound->createReader()); 00115 } 00116 else 00117 { 00118 strip->reader = NULL; 00119 strip->old_sound = NULL; 00120 } 00121 m_strips.push_front(strip); 00122 } 00123 00124 void AUD_SequencerReader::remove(AUD_SequencerEntry* entry) 00125 { 00126 AUD_SequencerStrip* strip; 00127 for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++) 00128 { 00129 strip = *i; 00130 if(strip->entry == entry) 00131 { 00132 i++; 00133 if(strip->reader) 00134 { 00135 delete strip->reader; 00136 } 00137 m_strips.remove(strip); 00138 delete strip; 00139 return; 00140 } 00141 } 00142 } 00143 00144 bool AUD_SequencerReader::isSeekable() const 00145 { 00146 return true; 00147 } 00148 00149 void AUD_SequencerReader::seek(int position) 00150 { 00151 m_position = position; 00152 } 00153 00154 int AUD_SequencerReader::getLength() const 00155 { 00156 return -1; 00157 } 00158 00159 int AUD_SequencerReader::getPosition() const 00160 { 00161 return m_position; 00162 } 00163 00164 AUD_Specs AUD_SequencerReader::getSpecs() const 00165 { 00166 return m_mixer->getSpecs().specs; 00167 } 00168 00169 void AUD_SequencerReader::read(int & length, sample_t* & buffer) 00170 { 00171 AUD_DeviceSpecs specs = m_mixer->getSpecs(); 00172 int samplesize = AUD_SAMPLE_SIZE(specs); 00173 int rate = specs.rate; 00174 00175 int size = length * samplesize; 00176 00177 int start, end, current, skip, len; 00178 AUD_SequencerStrip* strip; 00179 sample_t* buf; 00180 00181 if(m_buffer.getSize() < size) 00182 m_buffer.resize(size); 00183 buffer = m_buffer.getBuffer(); 00184 00185 if(!m_factory->getMute()) 00186 { 00187 for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++) 00188 { 00189 strip = *i; 00190 if(!strip->entry->muted) 00191 { 00192 if(strip->old_sound != *strip->entry->sound) 00193 { 00194 strip->old_sound = *strip->entry->sound; 00195 if(strip->reader) 00196 delete strip->reader; 00197 00198 if(strip->old_sound) 00199 { 00200 try 00201 { 00202 strip->reader = m_mixer->prepare(strip->old_sound->createReader()); 00203 } 00204 catch(AUD_Exception) 00205 { 00206 strip->reader = NULL; 00207 } 00208 } 00209 else 00210 strip->reader = NULL; 00211 } 00212 00213 if(strip->reader) 00214 { 00215 end = floor(strip->entry->end * rate); 00216 if(m_position < end) 00217 { 00218 start = floor(strip->entry->begin * rate); 00219 if(m_position + length > start) 00220 { 00221 current = m_position - start; 00222 if(current < 0) 00223 { 00224 skip = -current; 00225 current = 0; 00226 } 00227 else 00228 skip = 0; 00229 current += strip->entry->skip * rate; 00230 len = length > end - m_position ? end - m_position : length; 00231 len -= skip; 00232 if(strip->reader->getPosition() != current) 00233 strip->reader->seek(current); 00234 strip->reader->read(len, buf); 00235 m_mixer->add(buf, skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate)); 00236 } 00237 } 00238 } 00239 } 00240 } 00241 } 00242 00243 m_mixer->superpose((data_t*)buffer, length, 1.0f); 00244 00245 m_position += length; 00246 }