btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / mediaplayer / media_node_framework / audio / AudioFormatConverter.cpp
blobf6e24f34e8f14262e6d26fe718f790cb82fddd6d
1 /*
2 * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de>
3 * Copyright 2008 Stephan Aßmus <superstippi@gmx.de>
4 * All rights reserved. Distributed under the terms of the MIT licensce.
5 */
8 #include "AudioFormatConverter.h"
10 #include <ByteOrder.h>
11 #include <MediaDefs.h>
14 //#define TRACE_AUDIO_CONVERTER
15 #ifdef TRACE_AUDIO_CONVERTER
16 # include <stdio.h>
17 # define TRACE(x...) printf(x)
18 #else
19 # define TRACE(x...)
20 #endif
23 struct ReadFloat {
24 inline int operator()(const void* buffer) const {
25 // 0 == mid, -1.0 == bottom, 1.0 == top
26 float b = *(float*)buffer;
27 if (b < -1.0f)
28 b = -1.0f;
29 else if (b > 1.0f)
30 b = 1.0f;
31 return (int)((double)b * (double)0x7fffffff);
35 struct ReadInt {
36 inline int operator()(const void* buffer) const {
37 // 0 == mid, 0x80000001 == bottom, 0x7fffffff == top
38 int b = *(int*)buffer;
39 if (b == INT_MIN)
40 b++;
41 return b;
45 struct ReadShort {
46 inline int operator()(const void* buffer) const {
47 // 0 == mid, -32767 == bottom, +32767
48 short b = *(short*)buffer;
49 if (b == -32768)
50 b++;
51 return int(int64(b) * 0x7fffffff / 32767);
55 struct ReadUChar {
56 inline int operator()(const void* buffer) const {
57 // 128 == mid, 1 == bottom, 255 == top
58 uchar b = *(uchar*)buffer;
59 if (b == 0)
60 b++;
61 return int((int64(b) - 0x80) * 0x7fffffff / 127);
65 struct ReadChar {
66 inline int operator()(const void* buffer) const {
67 // 0 == mid, -127 == bottom, +127 == top
68 char b = *(char*)buffer;
69 if (b == 0)
70 b++;
71 return int(int64(b) * 0x7fffffff / 127);
75 struct WriteFloat {
76 inline void operator()(void* buffer, int value) const {
77 *(float*)buffer = (double)value / (double)0x7fffffff;
82 struct WriteInt {
83 inline void operator()(void* buffer, int value) const {
84 *(int*)buffer = value;
88 struct WriteShort {
89 inline void operator()(void* buffer, int value) const {
90 *(short*)buffer = (short)(value / (int)0x10000);
94 struct WriteUChar {
95 inline void operator()(void* buffer, int value) const {
96 *(uchar*)buffer = (uchar)(value / (int)0x1000000 + 128);
100 struct WriteChar {
101 inline void operator()(void* buffer, int value) const {
102 *(char*)buffer = (char)(value / (int)0x1000000);
107 template<typename ReadT, typename WriteT>
108 static void
109 convert(const ReadT& read, const WriteT& write,
110 const char* inBuffer, char* outBuffer, int32 frames,
111 int32 inSampleSize, int32 outSampleSize, int32 channelCount)
113 for (int32 i = 0; i < frames; i++) {
114 for (int32 c = 0; c < channelCount; c++) {
115 write(outBuffer, read(inBuffer));
116 inBuffer += inSampleSize;
117 outBuffer += outSampleSize;
123 static void
124 swap_sample_byte_order(void* buffer, uint32 format, size_t length)
126 type_code type = B_ANY_TYPE;
127 switch (format) {
128 case media_raw_audio_format::B_AUDIO_FLOAT:
129 type = B_FLOAT_TYPE;
130 break;
131 case media_raw_audio_format::B_AUDIO_INT:
132 type = B_INT32_TYPE;
133 break;
134 case media_raw_audio_format::B_AUDIO_SHORT:
135 type = B_INT16_TYPE;
136 break;
137 case media_raw_audio_format::B_AUDIO_UCHAR:
138 break;
139 case media_raw_audio_format::B_AUDIO_CHAR:
140 break;
142 if (type != B_ANY_TYPE)
143 swap_data(type, buffer, length, B_SWAP_ALWAYS);
147 // #pragma mark -
150 AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format,
151 uint32 byteOrder)
153 AudioReader(),
154 fSource(NULL)
156 uint32 hostByteOrder
157 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
158 if (source && source->Format().type == B_MEDIA_RAW_AUDIO
159 && source->Format().u.raw_audio.byte_order == hostByteOrder) {
160 fFormat = source->Format();
161 fFormat.u.raw_audio.format = format;
162 fFormat.u.raw_audio.byte_order = byteOrder;
163 int32 inSampleSize = source->Format().u.raw_audio.format
164 & media_raw_audio_format::B_AUDIO_SIZE_MASK;
165 int32 outSampleSize = fFormat.u.raw_audio.format
166 & media_raw_audio_format::B_AUDIO_SIZE_MASK;
167 if (inSampleSize != outSampleSize) {
168 fFormat.u.raw_audio.buffer_size
169 = source->Format().u.raw_audio.buffer_size * outSampleSize
170 / inSampleSize;
172 } else
173 source = NULL;
174 fSource = source;
178 AudioFormatConverter::~AudioFormatConverter()
183 bigtime_t
184 AudioFormatConverter::InitialLatency() const
186 return fSource->InitialLatency();
189 status_t
190 AudioFormatConverter::Read(void* buffer, int64 pos, int64 frames)
192 TRACE("AudioFormatConverter::Read(%p, %Ld, %Ld)\n", buffer, pos, frames);
193 status_t error = InitCheck();
194 if (error != B_OK) {
195 TRACE("AudioFormatConverter::Read() done 1\n");
196 return error;
198 pos += fOutOffset;
200 if (fFormat.u.raw_audio.format == fSource->Format().u.raw_audio.format
201 && fFormat.u.raw_audio.byte_order
202 == fSource->Format().u.raw_audio.byte_order) {
203 TRACE("AudioFormatConverter::Read() done 2\n");
204 return fSource->Read(buffer, pos, frames);
207 int32 inSampleSize = fSource->Format().u.raw_audio.format
208 & media_raw_audio_format::B_AUDIO_SIZE_MASK;
209 int32 outSampleSize = fFormat.u.raw_audio.format
210 & media_raw_audio_format::B_AUDIO_SIZE_MASK;
211 int32 channelCount = fFormat.u.raw_audio.channel_count;
212 int32 inFrameSize = inSampleSize * channelCount;
213 int32 outFrameSize = outSampleSize * channelCount;
214 char* reformatBuffer = NULL;
215 char* inBuffer = (char*)buffer;
217 #ifdef TRACE_AUDIO_CONVERTER
218 char formatString[256];
219 string_for_format(fSource->Format(), formatString, 256);
220 TRACE(" source format: %s\n", formatString);
221 TRACE(" in format : format: %lx, sample size: %ld, channels: %ld, "
222 "byte order: %lu\n", fSource->Format().u.raw_audio.format,
223 inSampleSize, channelCount,
224 fSource->Format().u.raw_audio.byte_order);
225 TRACE(" out format: format: %lx, sample size: %ld, channels: %ld, "
226 "byte order: %lu\n", fFormat.u.raw_audio.format, outSampleSize,
227 channelCount, fFormat.u.raw_audio.byte_order);
228 #endif // TRACE_AUDIO_CONVERTER
230 if (inSampleSize != outSampleSize) {
231 reformatBuffer = new char[frames * inFrameSize];
232 inBuffer = reformatBuffer;
234 error = fSource->Read(inBuffer, pos, frames);
235 // convert samples to host endianess
236 uint32 hostByteOrder
237 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
238 if (fSource->Format().u.raw_audio.byte_order != hostByteOrder) {
239 swap_sample_byte_order(inBuffer, fSource->Format().u.raw_audio.format,
240 frames * inFrameSize);
242 // convert the sample type
243 switch (fSource->Format().u.raw_audio.format) {
244 // float
245 case media_raw_audio_format::B_AUDIO_FLOAT:
246 switch (fFormat.u.raw_audio.format) {
247 case media_raw_audio_format::B_AUDIO_FLOAT:
248 break;
249 case media_raw_audio_format::B_AUDIO_INT:
250 convert(ReadFloat(), WriteInt(), inBuffer, (char*)buffer,
251 frames, inSampleSize, outSampleSize, channelCount);
252 break;
253 case media_raw_audio_format::B_AUDIO_SHORT:
254 convert(ReadFloat(), WriteShort(), inBuffer, (char*)buffer,
255 frames, inSampleSize, outSampleSize, channelCount);
256 break;
257 case media_raw_audio_format::B_AUDIO_UCHAR:
258 convert(ReadFloat(), WriteUChar(), inBuffer, (char*)buffer,
259 frames, inSampleSize, outSampleSize, channelCount);
260 break;
261 case media_raw_audio_format::B_AUDIO_CHAR:
262 convert(ReadFloat(), WriteChar(), inBuffer, (char*)buffer,
263 frames, inSampleSize, outSampleSize, channelCount);
264 break;
266 break;
267 // int
268 case media_raw_audio_format::B_AUDIO_INT:
269 switch (fFormat.u.raw_audio.format) {
270 case media_raw_audio_format::B_AUDIO_FLOAT:
271 convert(ReadInt(), WriteFloat(), inBuffer, (char*)buffer,
272 frames, inSampleSize, outSampleSize, channelCount);
273 break;
274 case media_raw_audio_format::B_AUDIO_INT:
275 break;
276 case media_raw_audio_format::B_AUDIO_SHORT:
277 convert(ReadInt(), WriteShort(), inBuffer, (char*)buffer,
278 frames, inSampleSize, outSampleSize, channelCount);
279 break;
280 case media_raw_audio_format::B_AUDIO_UCHAR:
281 convert(ReadInt(), WriteUChar(), inBuffer, (char*)buffer,
282 frames, inSampleSize, outSampleSize, channelCount);
283 break;
284 case media_raw_audio_format::B_AUDIO_CHAR:
285 convert(ReadInt(), WriteChar(), inBuffer, (char*)buffer,
286 frames, inSampleSize, outSampleSize, channelCount);
287 break;
289 break;
290 // short
291 case media_raw_audio_format::B_AUDIO_SHORT:
292 switch (fFormat.u.raw_audio.format) {
293 case media_raw_audio_format::B_AUDIO_FLOAT:
294 convert(ReadShort(), WriteFloat(), inBuffer, (char*)buffer,
295 frames, inSampleSize, outSampleSize, channelCount);
296 break;
297 case media_raw_audio_format::B_AUDIO_INT:
298 convert(ReadShort(), WriteInt(), inBuffer, (char*)buffer,
299 frames, inSampleSize, outSampleSize, channelCount);
300 break;
301 case media_raw_audio_format::B_AUDIO_SHORT:
302 break;
303 case media_raw_audio_format::B_AUDIO_UCHAR:
304 convert(ReadShort(), WriteUChar(), inBuffer, (char*)buffer,
305 frames, inSampleSize, outSampleSize, channelCount);
306 break;
307 case media_raw_audio_format::B_AUDIO_CHAR:
308 convert(ReadShort(), WriteChar(), inBuffer, (char*)buffer,
309 frames, inSampleSize, outSampleSize, channelCount);
310 break;
312 break;
313 // uchar
314 case media_raw_audio_format::B_AUDIO_UCHAR:
315 switch (fFormat.u.raw_audio.format) {
316 case media_raw_audio_format::B_AUDIO_FLOAT:
317 convert(ReadUChar(), WriteFloat(), inBuffer, (char*)buffer,
318 frames, inSampleSize, outSampleSize, channelCount);
319 break;
320 case media_raw_audio_format::B_AUDIO_INT:
321 convert(ReadUChar(), WriteInt(), inBuffer, (char*)buffer,
322 frames, inSampleSize, outSampleSize, channelCount);
323 break;
324 case media_raw_audio_format::B_AUDIO_SHORT:
325 convert(ReadUChar(), WriteShort(), inBuffer, (char*)buffer,
326 frames, inSampleSize, outSampleSize, channelCount);
327 break;
328 case media_raw_audio_format::B_AUDIO_UCHAR:
329 break;
330 case media_raw_audio_format::B_AUDIO_CHAR:
331 convert(ReadUChar(), WriteChar(), inBuffer, (char*)buffer,
332 frames, inSampleSize, outSampleSize, channelCount);
333 break;
335 break;
336 // char
337 case media_raw_audio_format::B_AUDIO_CHAR:
338 switch (fFormat.u.raw_audio.format) {
339 case media_raw_audio_format::B_AUDIO_FLOAT:
340 convert(ReadChar(), WriteFloat(), inBuffer, (char*)buffer,
341 frames, inSampleSize, outSampleSize, channelCount);
342 break;
343 case media_raw_audio_format::B_AUDIO_INT:
344 convert(ReadChar(), WriteInt(), inBuffer, (char*)buffer,
345 frames, inSampleSize, outSampleSize, channelCount);
346 break;
347 case media_raw_audio_format::B_AUDIO_SHORT:
348 convert(ReadChar(), WriteShort(), inBuffer, (char*)buffer,
349 frames, inSampleSize, outSampleSize, channelCount);
350 break;
351 case media_raw_audio_format::B_AUDIO_UCHAR:
352 convert(ReadChar(), WriteUChar(), inBuffer, (char*)buffer,
353 frames, inSampleSize, outSampleSize, channelCount);
354 break;
355 case media_raw_audio_format::B_AUDIO_CHAR:
356 break;
358 break;
360 // convert samples to output endianess
361 if (fFormat.u.raw_audio.byte_order != hostByteOrder) {
362 swap_sample_byte_order(buffer, fFormat.u.raw_audio.format,
363 frames * outFrameSize);
366 delete[] reformatBuffer;
367 TRACE("AudioFormatConverter::Read() done\n");
368 return B_OK;
372 status_t
373 AudioFormatConverter::InitCheck() const
375 status_t error = AudioReader::InitCheck();
376 if (error == B_OK && !fSource)
377 error = B_NO_INIT;
378 if (error == B_OK)
379 error = fSource->InitCheck();
380 return error;
384 AudioReader*
385 AudioFormatConverter::Source() const
387 return fSource;