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 00029 #include <cmath> 00030 00031 #ifndef M_PI 00032 #define M_PI 3.14159265358979323846 00033 #endif 00034 00035 #ifndef M_PI_2 00036 #define M_PI_2 1.57079632679489661923 00037 #endif 00038 00039 #include "AUD_ChannelMapperReader.h" 00040 00041 AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, 00042 AUD_Channels channels) : 00043 AUD_EffectReader(reader), m_target_channels(channels), 00044 m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0), m_map_size(0), m_mono_angle(0) 00045 { 00046 } 00047 00048 AUD_ChannelMapperReader::~AUD_ChannelMapperReader() 00049 { 00050 delete[] m_mapping; 00051 } 00052 00053 void AUD_ChannelMapperReader::setChannels(AUD_Channels channels) 00054 { 00055 m_target_channels = channels; 00056 calculateMapping(); 00057 } 00058 00059 void AUD_ChannelMapperReader::setMonoAngle(float angle) 00060 { 00061 if(angle != angle) 00062 angle = 0; 00063 m_mono_angle = angle; 00064 if(m_source_channels == AUD_CHANNELS_MONO) 00065 calculateMapping(); 00066 } 00067 00068 float AUD_ChannelMapperReader::angleDistance(float alpha, float beta) 00069 { 00070 alpha = fabs(alpha - beta); 00071 00072 if(alpha > M_PI) 00073 alpha = fabs(alpha - 2 * M_PI); 00074 00075 return alpha; 00076 } 00077 00078 void AUD_ChannelMapperReader::calculateMapping() 00079 { 00080 if(m_map_size < m_source_channels * m_target_channels) 00081 { 00082 delete[] m_mapping; 00083 m_mapping = new float[m_source_channels * m_target_channels]; 00084 m_map_size = m_source_channels * m_target_channels; 00085 } 00086 00087 for(int i = 0; i < m_source_channels * m_target_channels; i++) 00088 m_mapping[i] = 0; 00089 00090 const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1]; 00091 const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1]; 00092 00093 int lfe = -1; 00094 00095 for(int i = 0; i < m_target_channels; i++) 00096 { 00097 if(target_channels[i] == AUD_CHANNEL_LFE) 00098 { 00099 lfe = i; 00100 break; 00101 } 00102 } 00103 00104 const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1]; 00105 const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1]; 00106 00107 if(m_source_channels == AUD_CHANNELS_MONO) 00108 source_angles = &m_mono_angle; 00109 00110 int channel_min1, channel_min2; 00111 float angle_min1, angle_min2, angle; 00112 00113 for(int i = 0; i < m_source_channels; i++) 00114 { 00115 if(source_channels[i] == AUD_CHANNEL_LFE) 00116 { 00117 if(lfe != -1) 00118 m_mapping[lfe * m_source_channels + i] = 1; 00119 00120 continue; 00121 } 00122 00123 channel_min1 = channel_min2 = -1; 00124 angle_min1 = angle_min2 = 2 * M_PI; 00125 00126 for(int j = 0; j < m_target_channels; j++) 00127 { 00128 if(j == lfe) 00129 continue; 00130 angle = angleDistance(source_angles[i], target_angles[j]); 00131 if(angle < angle_min1) 00132 { 00133 channel_min2 = channel_min1; 00134 angle_min2 = angle_min1; 00135 00136 channel_min1 = j; 00137 angle_min1 = angle; 00138 } 00139 else if(angle < angle_min2) 00140 { 00141 channel_min2 = j; 00142 angle_min2 = angle; 00143 } 00144 } 00145 00146 angle = angle_min1 + angle_min2; 00147 if(channel_min2 == -1 || angle == 0) 00148 { 00149 m_mapping[channel_min1 * m_source_channels + i] = 1; 00150 } 00151 else 00152 { 00153 m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle); 00154 m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle); 00155 } 00156 } 00157 00158 /* AUD_XXX for(int i = 0; i < m_source_channels; i++) 00159 { 00160 for(int j = 0; j < m_target_channels; j++) 00161 { 00162 std::cout << m_mapping[i * m_source_channels + j] << " "; 00163 } 00164 std::cout << std::endl; 00165 }*/ 00166 } 00167 00168 AUD_Specs AUD_ChannelMapperReader::getSpecs() const 00169 { 00170 AUD_Specs specs = m_reader->getSpecs(); 00171 specs.channels = m_target_channels; 00172 return specs; 00173 } 00174 00175 void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer) 00176 { 00177 AUD_Channels channels = m_reader->getSpecs().channels; 00178 if(channels != m_source_channels) 00179 { 00180 m_source_channels = channels; 00181 calculateMapping(); 00182 } 00183 00184 if(m_source_channels == m_target_channels) 00185 { 00186 m_reader->read(length, eos, buffer); 00187 return; 00188 } 00189 00190 m_buffer.assureSize(length * channels * sizeof(sample_t)); 00191 00192 sample_t* in = m_buffer.getBuffer(); 00193 00194 m_reader->read(length, eos, in); 00195 00196 sample_t sum; 00197 00198 for(int i = 0; i < length; i++) 00199 { 00200 for(int j = 0; j < m_target_channels; j++) 00201 { 00202 sum = 0; 00203 for(int k = 0; k < m_source_channels; k++) 00204 sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k]; 00205 buffer[i * m_target_channels + j] = sum; 00206 } 00207 } 00208 } 00209 00210 const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] = 00211 { 00212 AUD_CHANNEL_FRONT_CENTER 00213 }; 00214 00215 const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] = 00216 { 00217 AUD_CHANNEL_FRONT_LEFT, 00218 AUD_CHANNEL_FRONT_RIGHT 00219 }; 00220 00221 const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] = 00222 { 00223 AUD_CHANNEL_FRONT_LEFT, 00224 AUD_CHANNEL_FRONT_RIGHT, 00225 AUD_CHANNEL_LFE 00226 }; 00227 00228 const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] = 00229 { 00230 AUD_CHANNEL_FRONT_LEFT, 00231 AUD_CHANNEL_FRONT_RIGHT, 00232 AUD_CHANNEL_REAR_LEFT, 00233 AUD_CHANNEL_REAR_RIGHT 00234 }; 00235 00236 const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] = 00237 { 00238 AUD_CHANNEL_FRONT_LEFT, 00239 AUD_CHANNEL_FRONT_RIGHT, 00240 AUD_CHANNEL_FRONT_CENTER, 00241 AUD_CHANNEL_REAR_LEFT, 00242 AUD_CHANNEL_REAR_RIGHT 00243 }; 00244 00245 const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] = 00246 { 00247 AUD_CHANNEL_FRONT_LEFT, 00248 AUD_CHANNEL_FRONT_RIGHT, 00249 AUD_CHANNEL_FRONT_CENTER, 00250 AUD_CHANNEL_LFE, 00251 AUD_CHANNEL_REAR_LEFT, 00252 AUD_CHANNEL_REAR_RIGHT 00253 }; 00254 00255 const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] = 00256 { 00257 AUD_CHANNEL_FRONT_LEFT, 00258 AUD_CHANNEL_FRONT_RIGHT, 00259 AUD_CHANNEL_FRONT_CENTER, 00260 AUD_CHANNEL_LFE, 00261 AUD_CHANNEL_REAR_CENTER, 00262 AUD_CHANNEL_REAR_LEFT, 00263 AUD_CHANNEL_REAR_RIGHT 00264 }; 00265 00266 const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] = 00267 { 00268 AUD_CHANNEL_FRONT_LEFT, 00269 AUD_CHANNEL_FRONT_RIGHT, 00270 AUD_CHANNEL_FRONT_CENTER, 00271 AUD_CHANNEL_LFE, 00272 AUD_CHANNEL_REAR_LEFT, 00273 AUD_CHANNEL_REAR_RIGHT, 00274 AUD_CHANNEL_SIDE_LEFT, 00275 AUD_CHANNEL_SIDE_RIGHT 00276 }; 00277 00278 const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] = 00279 { 00280 AUD_ChannelMapperReader::MONO_MAP, 00281 AUD_ChannelMapperReader::STEREO_MAP, 00282 AUD_ChannelMapperReader::STEREO_LFE_MAP, 00283 AUD_ChannelMapperReader::SURROUND4_MAP, 00284 AUD_ChannelMapperReader::SURROUND5_MAP, 00285 AUD_ChannelMapperReader::SURROUND51_MAP, 00286 AUD_ChannelMapperReader::SURROUND61_MAP, 00287 AUD_ChannelMapperReader::SURROUND71_MAP 00288 }; 00289 00290 const float AUD_ChannelMapperReader::MONO_ANGLES[] = 00291 { 00292 0.0f * M_PI / 180.0f 00293 }; 00294 00295 const float AUD_ChannelMapperReader::STEREO_ANGLES[] = 00296 { 00297 -90.0f * M_PI / 180.0f, 00298 90.0f * M_PI / 180.0f 00299 }; 00300 00301 const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] = 00302 { 00303 -90.0f * M_PI / 180.0f, 00304 90.0f * M_PI / 180.0f, 00305 0.0f * M_PI / 180.0f 00306 }; 00307 00308 const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] = 00309 { 00310 -45.0f * M_PI / 180.0f, 00311 45.0f * M_PI / 180.0f, 00312 -135.0f * M_PI / 180.0f, 00313 135.0f * M_PI / 180.0f 00314 }; 00315 00316 const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] = 00317 { 00318 -30.0f * M_PI / 180.0f, 00319 30.0f * M_PI / 180.0f, 00320 0.0f * M_PI / 180.0f, 00321 -110.0f * M_PI / 180.0f, 00322 110.0f * M_PI / 180.0f 00323 }; 00324 00325 const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] = 00326 { 00327 -30.0f * M_PI / 180.0f, 00328 30.0f * M_PI / 180.0f, 00329 0.0f * M_PI / 180.0f, 00330 0.0f * M_PI / 180.0f, 00331 -110.0f * M_PI / 180.0f, 00332 110.0f * M_PI / 180.0f 00333 }; 00334 00335 const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] = 00336 { 00337 -30.0f * M_PI / 180.0f, 00338 30.0f * M_PI / 180.0f, 00339 0.0f * M_PI / 180.0f, 00340 0.0f * M_PI / 180.0f, 00341 180.0f * M_PI / 180.0f, 00342 -110.0f * M_PI / 180.0f, 00343 110.0f * M_PI / 180.0f 00344 }; 00345 00346 const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] = 00347 { 00348 -30.0f * M_PI / 180.0f, 00349 30.0f * M_PI / 180.0f, 00350 0.0f * M_PI / 180.0f, 00351 0.0f * M_PI / 180.0f, 00352 -110.0f * M_PI / 180.0f, 00353 110.0f * M_PI / 180.0f, 00354 -150.0f * M_PI / 180.0f, 00355 150.0f * M_PI / 180.0f 00356 }; 00357 00358 const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] = 00359 { 00360 AUD_ChannelMapperReader::MONO_ANGLES, 00361 AUD_ChannelMapperReader::STEREO_ANGLES, 00362 AUD_ChannelMapperReader::STEREO_LFE_ANGLES, 00363 AUD_ChannelMapperReader::SURROUND4_ANGLES, 00364 AUD_ChannelMapperReader::SURROUND5_ANGLES, 00365 AUD_ChannelMapperReader::SURROUND51_ANGLES, 00366 AUD_ChannelMapperReader::SURROUND61_ANGLES, 00367 AUD_ChannelMapperReader::SURROUND71_ANGLES 00368 };