2.5: warning fixes
[blender.git] / intern / audaspace / intern / AUD_FloatMixer.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 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 Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
19  *
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/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 #include "AUD_FloatMixer.h"
27 #include "AUD_ConverterFactory.h"
28 #include "AUD_SRCResampleFactory.h"
29 #include "AUD_ChannelMapperFactory.h"
30 #include "AUD_IReader.h"
31 #include "AUD_Buffer.h"
32
33 #include <cstring>
34
35 AUD_FloatMixer::AUD_FloatMixer()
36 {
37         m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
38
39         m_converter = NULL;
40         m_resampler = NULL;
41         m_mapper = NULL;
42 }
43
44 AUD_FloatMixer::~AUD_FloatMixer()
45 {
46         delete m_buffer; AUD_DELETE("buffer")
47
48         if(m_converter)
49         {
50                 delete m_converter; AUD_DELETE("factory")
51         }
52         if(m_resampler)
53         {
54                 delete m_resampler; AUD_DELETE("factory")
55         }
56         if(m_mapper)
57         {
58                 delete m_mapper; AUD_DELETE("factory")
59         }
60 }
61
62 AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
63 {
64         m_converter->setReader(reader);
65         reader = m_converter->createReader();
66
67         m_resampler->setReader(reader);
68         reader = m_resampler->createReader();
69
70         if(reader->getSpecs().channels != m_specs.channels)
71         {
72                 m_mapper->setReader(reader);
73                 reader = m_mapper->createReader();
74         }
75
76         return reader;
77 }
78
79 void AUD_FloatMixer::setSpecs(AUD_Specs specs)
80 {
81         m_specs = specs;
82
83         if(m_converter)
84         {
85                 delete m_converter; AUD_DELETE("factory")
86         }
87         if(m_resampler)
88         {
89                 delete m_resampler; AUD_DELETE("factory")
90         }
91         if(m_mapper)
92         {
93                 delete m_mapper; AUD_DELETE("factory")
94         }
95
96         specs.format = AUD_FORMAT_FLOAT32;
97
98         m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
99         m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
100         m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
101
102         int bigendian = 1;
103         bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
104
105         switch(m_specs.format)
106         {
107         case AUD_FORMAT_U8:
108                 m_convert = AUD_convert_float_u8;
109                 break;
110         case AUD_FORMAT_S16:
111                 m_convert = AUD_convert_float_s16;
112                 break;
113         case AUD_FORMAT_S24:
114                 if(bigendian)
115                         m_convert = AUD_convert_float_s24_be;
116                 else
117                         m_convert = AUD_convert_float_s24_le;
118                 break;
119         case AUD_FORMAT_S32:
120                 m_convert = AUD_convert_float_s32;
121                 break;
122         case AUD_FORMAT_FLOAT32:
123                 m_convert = AUD_convert_copy<float>;
124                 break;
125         case AUD_FORMAT_FLOAT64:
126                 m_convert = AUD_convert_float_double;
127                 break;
128         default:
129                 break;
130         }
131 }
132
133 void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
134                                                  float volume)
135 {
136         AUD_FloatMixerBuffer buf;
137         buf.buffer = buffer;
138         buf.length = length;
139         buf.volume = volume;
140         m_buffers.push_back(buf);
141 }
142
143 void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
144 {
145         AUD_FloatMixerBuffer buf;
146
147         int channels = m_specs.channels;
148
149         if(m_buffer->getSize() < length * channels * 4)
150                 m_buffer->resize(length * channels * 4);
151
152         float* out = (float*)m_buffer->getBuffer();
153         float* in;
154
155         memset(out, 0, length * channels * 4);
156
157         int end;
158
159         while(!m_buffers.empty())
160         {
161                 buf = m_buffers.front();
162                 m_buffers.pop_front();
163
164                 end = buf.length*channels;
165                 in = (float*) buf.buffer;
166
167                 for(int i = 0; i < end; i++)
168                         out[i] += in[i]*buf.volume * volume;
169         }
170
171         m_convert(buffer, (sample_t*) out, length * channels);
172 }