svn merge -r39781:39792 https://svn.blender.org/svnroot/bf-blender/trunk/blender...
[blender-staging.git] / intern / audaspace / intern / AUD_ChannelMapperReader.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * Copyright 2009-2011 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * Audaspace is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Audaspace; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file audaspace/intern/AUD_ChannelMapperReader.cpp
28  *  \ingroup audaspaceintern
29  */
30
31 #include <cmath>
32
33 #ifndef M_PI
34 #define M_PI 3.14159265358979323846
35 #endif
36
37 #ifndef M_PI_2
38 #define M_PI_2 1.57079632679489661923
39 #endif
40
41 #include "AUD_ChannelMapperReader.h"
42
43 AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader,
44                                                                                                  AUD_Channels channels) :
45                 AUD_EffectReader(reader), m_target_channels(channels),
46         m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0), m_map_size(0), m_mono_angle(0)
47 {
48 }
49
50 AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
51 {
52         delete[] m_mapping;
53 }
54
55 void AUD_ChannelMapperReader::setChannels(AUD_Channels channels)
56 {
57         m_target_channels = channels;
58         calculateMapping();
59 }
60
61 void AUD_ChannelMapperReader::setMonoAngle(float angle)
62 {
63         if(angle != angle)
64                 angle = 0;
65         m_mono_angle = angle;
66         if(m_source_channels == AUD_CHANNELS_MONO)
67                 calculateMapping();
68 }
69
70 float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
71 {
72         alpha = fabs(alpha - beta);
73
74         if(alpha > M_PI)
75                 alpha = fabs(alpha - 2 * M_PI);
76
77         return alpha;
78 }
79
80 void AUD_ChannelMapperReader::calculateMapping()
81 {
82         if(m_map_size < m_source_channels * m_target_channels)
83         {
84                 delete[] m_mapping;
85                 m_mapping = new float[m_source_channels * m_target_channels];
86                 m_map_size = m_source_channels * m_target_channels;
87         }
88
89         for(int i = 0; i < m_source_channels * m_target_channels; i++)
90                 m_mapping[i] = 0;
91
92         const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
93         const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
94
95         int lfe = -1;
96
97         for(int i = 0; i < m_target_channels; i++)
98         {
99                 if(target_channels[i] == AUD_CHANNEL_LFE)
100                 {
101                         lfe = i;
102                         break;
103                 }
104         }
105
106         const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
107         const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
108
109         if(m_source_channels == AUD_CHANNELS_MONO)
110                 source_angles = &m_mono_angle;
111
112         int channel_min1, channel_min2;
113         float angle_min1, angle_min2, angle;
114
115         for(int i = 0; i < m_source_channels; i++)
116         {
117                 if(source_channels[i] == AUD_CHANNEL_LFE)
118                 {
119                         if(lfe != -1)
120                                 m_mapping[lfe * m_source_channels + i] = 1;
121
122                         continue;
123                 }
124
125                 channel_min1 = channel_min2 = -1;
126                 angle_min1 = angle_min2 = 2 * M_PI;
127
128                 for(int j = 0; j < m_target_channels; j++)
129                 {
130                         if(j == lfe)
131                                 continue;
132                         angle = angleDistance(source_angles[i], target_angles[j]);
133                         if(angle < angle_min1)
134                         {
135                                 channel_min2 = channel_min1;
136                                 angle_min2 = angle_min1;
137
138                                 channel_min1 = j;
139                                 angle_min1 = angle;
140                         }
141                         else if(angle < angle_min2)
142                         {
143                                 channel_min2 = j;
144                                 angle_min2 = angle;
145                         }
146                 }
147
148                 angle = angle_min1 + angle_min2;
149                 if(channel_min2 == -1 || angle == 0)
150                 {
151                         m_mapping[channel_min1 * m_source_channels + i] = 1;
152                 }
153                 else
154                 {
155                         m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle);
156                         m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle);
157                 }
158         }
159
160         /* AUD_XXX for(int i = 0; i < m_source_channels; i++)
161         {
162                 for(int j = 0; j < m_target_channels; j++)
163                 {
164                         std::cout << m_mapping[i * m_source_channels + j] << " ";
165                 }
166                 std::cout << std::endl;
167         }*/
168 }
169
170 AUD_Specs AUD_ChannelMapperReader::getSpecs() const
171 {
172         AUD_Specs specs = m_reader->getSpecs();
173         specs.channels = m_target_channels;
174         return specs;
175 }
176
177 void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
178 {
179         AUD_Channels channels = m_reader->getSpecs().channels;
180         if(channels != m_source_channels)
181         {
182                 m_source_channels = channels;
183                 calculateMapping();
184         }
185
186         if(m_source_channels == m_target_channels)
187         {
188                 m_reader->read(length, eos, buffer);
189                 return;
190         }
191
192         m_buffer.assureSize(length * channels * sizeof(sample_t));
193
194         sample_t* in = m_buffer.getBuffer();
195
196         m_reader->read(length, eos, in);
197
198         sample_t sum;
199
200         for(int i = 0; i < length; i++)
201         {
202                 for(int j = 0; j < m_target_channels; j++)
203                 {
204                         sum = 0;
205                         for(int k = 0; k < m_source_channels; k++)
206                                 sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
207                         buffer[i * m_target_channels + j] = sum;
208                 }
209         }
210 }
211
212 const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] =
213 {
214         AUD_CHANNEL_FRONT_CENTER
215 };
216
217 const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] =
218 {
219         AUD_CHANNEL_FRONT_LEFT,
220         AUD_CHANNEL_FRONT_RIGHT
221 };
222
223 const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] =
224 {
225         AUD_CHANNEL_FRONT_LEFT,
226         AUD_CHANNEL_FRONT_RIGHT,
227         AUD_CHANNEL_LFE
228 };
229
230 const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] =
231 {
232         AUD_CHANNEL_FRONT_LEFT,
233         AUD_CHANNEL_FRONT_RIGHT,
234         AUD_CHANNEL_REAR_LEFT,
235         AUD_CHANNEL_REAR_RIGHT
236 };
237
238 const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] =
239 {
240         AUD_CHANNEL_FRONT_LEFT,
241         AUD_CHANNEL_FRONT_RIGHT,
242         AUD_CHANNEL_FRONT_CENTER,
243         AUD_CHANNEL_REAR_LEFT,
244         AUD_CHANNEL_REAR_RIGHT
245 };
246
247 const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] =
248 {
249         AUD_CHANNEL_FRONT_LEFT,
250         AUD_CHANNEL_FRONT_RIGHT,
251         AUD_CHANNEL_FRONT_CENTER,
252         AUD_CHANNEL_LFE,
253         AUD_CHANNEL_REAR_LEFT,
254         AUD_CHANNEL_REAR_RIGHT
255 };
256
257 const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] =
258 {
259         AUD_CHANNEL_FRONT_LEFT,
260         AUD_CHANNEL_FRONT_RIGHT,
261         AUD_CHANNEL_FRONT_CENTER,
262         AUD_CHANNEL_LFE,
263         AUD_CHANNEL_REAR_CENTER,
264         AUD_CHANNEL_REAR_LEFT,
265         AUD_CHANNEL_REAR_RIGHT
266 };
267
268 const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] =
269 {
270         AUD_CHANNEL_FRONT_LEFT,
271         AUD_CHANNEL_FRONT_RIGHT,
272         AUD_CHANNEL_FRONT_CENTER,
273         AUD_CHANNEL_LFE,
274         AUD_CHANNEL_REAR_LEFT,
275         AUD_CHANNEL_REAR_RIGHT,
276         AUD_CHANNEL_SIDE_LEFT,
277         AUD_CHANNEL_SIDE_RIGHT
278 };
279
280 const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] =
281 {
282         AUD_ChannelMapperReader::MONO_MAP,
283         AUD_ChannelMapperReader::STEREO_MAP,
284         AUD_ChannelMapperReader::STEREO_LFE_MAP,
285         AUD_ChannelMapperReader::SURROUND4_MAP,
286         AUD_ChannelMapperReader::SURROUND5_MAP,
287         AUD_ChannelMapperReader::SURROUND51_MAP,
288         AUD_ChannelMapperReader::SURROUND61_MAP,
289         AUD_ChannelMapperReader::SURROUND71_MAP
290 };
291
292 const float AUD_ChannelMapperReader::MONO_ANGLES[] =
293 {
294         0.0f * M_PI / 180.0f
295 };
296
297 const float AUD_ChannelMapperReader::STEREO_ANGLES[] =
298 {
299         -90.0f * M_PI / 180.0f,
300          90.0f * M_PI / 180.0f
301 };
302
303 const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] =
304 {
305    -90.0f * M_PI / 180.0f,
306         90.0f * M_PI / 180.0f,
307          0.0f * M_PI / 180.0f
308 };
309
310 const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] =
311 {
312          -45.0f * M_PI / 180.0f,
313           45.0f * M_PI / 180.0f,
314         -135.0f * M_PI / 180.0f,
315          135.0f * M_PI / 180.0f
316 };
317
318 const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] =
319 {
320          -30.0f * M_PI / 180.0f,
321           30.0f * M_PI / 180.0f,
322            0.0f * M_PI / 180.0f,
323         -110.0f * M_PI / 180.0f,
324          110.0f * M_PI / 180.0f
325 };
326
327 const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] =
328 {
329           -30.0f * M_PI / 180.0f,
330            30.0f * M_PI / 180.0f,
331            0.0f * M_PI / 180.0f,
332            0.0f * M_PI / 180.0f,
333         -110.0f * M_PI / 180.0f,
334          110.0f * M_PI / 180.0f
335 };
336
337 const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] =
338 {
339           -30.0f * M_PI / 180.0f,
340            30.0f * M_PI / 180.0f,
341            0.0f * M_PI / 180.0f,
342            0.0f * M_PI / 180.0f,
343          180.0f * M_PI / 180.0f,
344         -110.0f * M_PI / 180.0f,
345          110.0f * M_PI / 180.0f
346 };
347
348 const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] =
349 {
350           -30.0f * M_PI / 180.0f,
351            30.0f * M_PI / 180.0f,
352            0.0f * M_PI / 180.0f,
353            0.0f * M_PI / 180.0f,
354         -110.0f * M_PI / 180.0f,
355          110.0f * M_PI / 180.0f
356         -150.0f * M_PI / 180.0f,
357          150.0f * M_PI / 180.0f
358 };
359
360 const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] =
361 {
362         AUD_ChannelMapperReader::MONO_ANGLES,
363         AUD_ChannelMapperReader::STEREO_ANGLES,
364         AUD_ChannelMapperReader::STEREO_LFE_ANGLES,
365         AUD_ChannelMapperReader::SURROUND4_ANGLES,
366         AUD_ChannelMapperReader::SURROUND5_ANGLES,
367         AUD_ChannelMapperReader::SURROUND51_ANGLES,
368         AUD_ChannelMapperReader::SURROUND61_ANGLES,
369         AUD_ChannelMapperReader::SURROUND71_ANGLES
370 };