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