Blender V2.61 - r43446

AUD_ChannelMapperReader.cpp

Go to the documentation of this file.
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 };