3D Audio GSoC:
[blender.git] / intern / audaspace / intern / AUD_ChannelMapperFactory.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_ChannelMapperFactory.cpp
28  *  \ingroup audaspaceintern
29  */
30
31
32 #include "AUD_ChannelMapperFactory.h"
33 #include "AUD_ChannelMapperReader.h"
34
35 #include <cstring>
36
37 AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory,
38                                                                                                    AUD_DeviceSpecs specs) :
39                 AUD_MixerFactory(factory, specs)
40 {
41         memset(m_mapping, 0, sizeof(m_mapping));
42 }
43
44 AUD_ChannelMapperFactory::~AUD_ChannelMapperFactory()
45 {
46         for(int i = 1; i < 10; i++)
47                 deleteMapping(i);
48 }
49
50 float** AUD_ChannelMapperFactory::getMapping(int ic)
51 {
52         ic--;
53         if(ic > 8 || ic < 0)
54                 return 0;
55
56         if(m_mapping[ic])
57         {
58                 int channels = -1;
59                 while(m_mapping[ic][++channels] != 0);
60                 if(channels != m_specs.channels)
61                         deleteMapping(ic+1);
62         }
63
64         if(!m_mapping[ic])
65         {
66                 int channels = m_specs.channels;
67
68                 m_mapping[ic] = new float*[channels+1];
69                 m_mapping[ic][channels] = 0;
70
71                 for(int i = 0; i < channels; i++)
72                 {
73                         m_mapping[ic][i] = new float[ic+1];
74                         for(int j = 0; j <= ic; j++)
75                                 m_mapping[ic][i][j] = ((i == j) || (channels == 1) ||
76                                                                            (ic == 0)) ? 1.0f : 0.0f;
77                 }
78         }
79
80         return m_mapping[ic];
81 }
82
83 void AUD_ChannelMapperFactory::deleteMapping(int ic)
84 {
85         ic--;
86         if(ic > 8 || ic < 0)
87                 return;
88
89         if(m_mapping[ic])
90         {
91                 for(int i = 0; 1; i++)
92                 {
93                         if(m_mapping[ic][i] != 0)
94                         {
95                                 delete[] m_mapping[ic][i];
96                         }
97                         else
98                                 break;
99                 }
100                 delete[] m_mapping[ic];
101                 m_mapping[ic] = 0;
102         }
103 }
104
105 AUD_Reference<AUD_IReader> AUD_ChannelMapperFactory::createReader() const
106 {
107         AUD_Reference<AUD_IReader> reader = getReader();
108         int ic = reader->getSpecs().channels;
109
110         return new AUD_ChannelMapperReader(reader,
111                                    const_cast<AUD_ChannelMapperFactory*>(this)->getMapping(ic));
112 }