2
* $Id: AUD_ChannelMapperReader.cpp 25646 2010-01-01 11:55:56Z nexyon $
4
* ***** BEGIN LGPL LICENSE BLOCK *****
6
* Copyright 2009 Jörg Hermann Müller
2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* Copyright 2009-2011 Jörg Hermann Müller
8
6
* This file is part of AudaSpace.
10
* AudaSpace is free software: you can redistribute it and/or modify
11
* it under the terms of the GNU Lesser General Public License as published by
12
* the Free Software Foundation, either version 3 of the License, or
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
13
11
* (at your option) any later version.
15
13
* AudaSpace is distributed in the hope that it will be useful,
16
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public License
21
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
23
* ***** END LGPL LICENSE BLOCK *****
16
* GNU General Public License for more details.
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.
22
* ***** END GPL LICENSE BLOCK *****
25
/** \file audaspace/intern/AUD_ChannelMapperReader.cpp
26
* \ingroup audaspaceintern
32
#define M_PI 3.14159265358979323846
36
#define M_PI_2 1.57079632679489661923
26
39
#include "AUD_ChannelMapperReader.h"
27
#include "AUD_Buffer.h"
29
AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
31
AUD_EffectReader(reader)
41
AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<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)
33
m_specs = reader->getSpecs();
36
m_rch = m_specs.channels;
37
while(mapping[++channels] != 0);
39
m_mapping = new float*[channels]; AUD_NEW("mapping")
40
m_specs.channels = (AUD_Channels)channels;
47
m_mapping[channels] = new float[m_rch]; AUD_NEW("mapping")
49
for(i=0; i < m_rch; i++)
50
sum += mapping[channels][i];
51
for(i=0; i < m_rch; i++)
52
m_mapping[channels][i] = sum > 0.0f ?
53
mapping[channels][i]/sum : 0.0f;
56
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
59
48
AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
61
int channels = m_specs.channels;
65
delete[] m_mapping[channels]; AUD_DELETE("mapping")
68
delete[] m_mapping; AUD_DELETE("mapping")
70
delete m_buffer; AUD_DELETE("buffer")
73
AUD_Specs AUD_ChannelMapperReader::getSpecs()
78
void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
80
m_reader->read(length, buffer);
82
int channels = m_specs.channels;
84
if(m_buffer->getSize() < length * 4 * channels)
85
m_buffer->resize(length * 4 * channels);
87
sample_t* in = buffer;
88
sample_t* out = m_buffer->getBuffer();
53
void AUD_ChannelMapperReader::setChannels(AUD_Channels channels)
55
m_target_channels = channels;
59
void AUD_ChannelMapperReader::setMonoAngle(float angle)
64
if(m_source_channels == AUD_CHANNELS_MONO)
68
float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
70
alpha = fabs(alpha - beta);
73
alpha = fabs(alpha - 2 * M_PI);
78
void AUD_ChannelMapperReader::calculateMapping()
80
if(m_map_size < m_source_channels * m_target_channels)
83
m_mapping = new float[m_source_channels * m_target_channels];
84
m_map_size = m_source_channels * m_target_channels;
87
for(int i = 0; i < m_source_channels * m_target_channels; i++)
90
const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
91
const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
95
for(int i = 0; i < m_target_channels; i++)
97
if(target_channels[i] == AUD_CHANNEL_LFE)
104
const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
105
const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
107
if(m_source_channels == AUD_CHANNELS_MONO)
108
source_angles = &m_mono_angle;
110
int channel_min1, channel_min2;
111
float angle_min1, angle_min2, angle;
113
for(int i = 0; i < m_source_channels; i++)
115
if(source_channels[i] == AUD_CHANNEL_LFE)
118
m_mapping[lfe * m_source_channels + i] = 1;
123
channel_min1 = channel_min2 = -1;
124
angle_min1 = angle_min2 = 2 * M_PI;
126
for(int j = 0; j < m_target_channels; j++)
130
angle = angleDistance(source_angles[i], target_angles[j]);
131
if(angle < angle_min1)
133
channel_min2 = channel_min1;
134
angle_min2 = angle_min1;
139
else if(angle < angle_min2)
146
angle = angle_min1 + angle_min2;
147
if(channel_min2 == -1 || angle == 0)
149
m_mapping[channel_min1 * m_source_channels + i] = 1;
153
m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle);
154
m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle);
158
/* AUD_XXX for(int i = 0; i < m_source_channels; i++)
160
for(int j = 0; j < m_target_channels; j++)
162
std::cout << m_mapping[i * m_source_channels + j] << " ";
164
std::cout << std::endl;
168
AUD_Specs AUD_ChannelMapperReader::getSpecs() const
170
AUD_Specs specs = m_reader->getSpecs();
171
specs.channels = m_target_channels;
175
void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
177
AUD_Channels channels = m_reader->getSpecs().channels;
178
if(channels != m_source_channels)
180
m_source_channels = channels;
184
if(m_source_channels == m_target_channels)
186
m_reader->read(length, eos, buffer);
190
m_buffer.assureSize(length * channels * sizeof(sample_t));
192
sample_t* in = m_buffer.getBuffer();
194
m_reader->read(length, eos, in);
91
198
for(int i = 0; i < length; i++)
93
for(int j = 0; j < channels; j++)
200
for(int j = 0; j < m_target_channels; j++)
96
for(int k = 0; k < m_rch; k++)
97
sum += m_mapping[j][k] * in[i * m_rch + k];
98
out[i * channels + j] = sum;
203
for(int k = 0; k < m_source_channels; k++)
204
sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
205
buffer[i * m_target_channels + j] = sum;
102
buffer = m_buffer->getBuffer();
210
const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] =
212
AUD_CHANNEL_FRONT_CENTER
215
const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] =
217
AUD_CHANNEL_FRONT_LEFT,
218
AUD_CHANNEL_FRONT_RIGHT
221
const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] =
223
AUD_CHANNEL_FRONT_LEFT,
224
AUD_CHANNEL_FRONT_RIGHT,
228
const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] =
230
AUD_CHANNEL_FRONT_LEFT,
231
AUD_CHANNEL_FRONT_RIGHT,
232
AUD_CHANNEL_REAR_LEFT,
233
AUD_CHANNEL_REAR_RIGHT
236
const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] =
238
AUD_CHANNEL_FRONT_LEFT,
239
AUD_CHANNEL_FRONT_RIGHT,
240
AUD_CHANNEL_FRONT_CENTER,
241
AUD_CHANNEL_REAR_LEFT,
242
AUD_CHANNEL_REAR_RIGHT
245
const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] =
247
AUD_CHANNEL_FRONT_LEFT,
248
AUD_CHANNEL_FRONT_RIGHT,
249
AUD_CHANNEL_FRONT_CENTER,
251
AUD_CHANNEL_REAR_LEFT,
252
AUD_CHANNEL_REAR_RIGHT
255
const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] =
257
AUD_CHANNEL_FRONT_LEFT,
258
AUD_CHANNEL_FRONT_RIGHT,
259
AUD_CHANNEL_FRONT_CENTER,
261
AUD_CHANNEL_REAR_CENTER,
262
AUD_CHANNEL_REAR_LEFT,
263
AUD_CHANNEL_REAR_RIGHT
266
const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] =
268
AUD_CHANNEL_FRONT_LEFT,
269
AUD_CHANNEL_FRONT_RIGHT,
270
AUD_CHANNEL_FRONT_CENTER,
272
AUD_CHANNEL_REAR_LEFT,
273
AUD_CHANNEL_REAR_RIGHT,
274
AUD_CHANNEL_SIDE_LEFT,
275
AUD_CHANNEL_SIDE_RIGHT
278
const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] =
280
AUD_ChannelMapperReader::MONO_MAP,
281
AUD_ChannelMapperReader::STEREO_MAP,
282
AUD_ChannelMapperReader::STEREO_LFE_MAP,
283
AUD_ChannelMapperReader::SURROUND4_MAP,
284
AUD_ChannelMapperReader::SURROUND5_MAP,
285
AUD_ChannelMapperReader::SURROUND51_MAP,
286
AUD_ChannelMapperReader::SURROUND61_MAP,
287
AUD_ChannelMapperReader::SURROUND71_MAP
290
const float AUD_ChannelMapperReader::MONO_ANGLES[] =
295
const float AUD_ChannelMapperReader::STEREO_ANGLES[] =
297
-90.0f * M_PI / 180.0f,
298
90.0f * M_PI / 180.0f
301
const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] =
303
-90.0f * M_PI / 180.0f,
304
90.0f * M_PI / 180.0f,
308
const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] =
310
-45.0f * M_PI / 180.0f,
311
45.0f * M_PI / 180.0f,
312
-135.0f * M_PI / 180.0f,
313
135.0f * M_PI / 180.0f
316
const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] =
318
-30.0f * M_PI / 180.0f,
319
30.0f * M_PI / 180.0f,
320
0.0f * M_PI / 180.0f,
321
-110.0f * M_PI / 180.0f,
322
110.0f * M_PI / 180.0f
325
const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] =
327
-30.0f * M_PI / 180.0f,
328
30.0f * M_PI / 180.0f,
329
0.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
335
const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] =
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
180.0f * M_PI / 180.0f,
342
-110.0f * M_PI / 180.0f,
343
110.0f * M_PI / 180.0f
346
const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] =
348
-30.0f * M_PI / 180.0f,
349
30.0f * M_PI / 180.0f,
350
0.0f * M_PI / 180.0f,
351
0.0f * M_PI / 180.0f,
352
-110.0f * M_PI / 180.0f,
353
110.0f * M_PI / 180.0f,
354
-150.0f * M_PI / 180.0f,
355
150.0f * M_PI / 180.0f
358
const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] =
360
AUD_ChannelMapperReader::MONO_ANGLES,
361
AUD_ChannelMapperReader::STEREO_ANGLES,
362
AUD_ChannelMapperReader::STEREO_LFE_ANGLES,
363
AUD_ChannelMapperReader::SURROUND4_ANGLES,
364
AUD_ChannelMapperReader::SURROUND5_ANGLES,
365
AUD_ChannelMapperReader::SURROUND51_ANGLES,
366
AUD_ChannelMapperReader::SURROUND61_ANGLES,
367
AUD_ChannelMapperReader::SURROUND71_ANGLES