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.
8 #include "AudioFormatConverter.h"
10 #include <ByteOrder.h>
11 #include <MediaDefs.h>
14 //#define TRACE_AUDIO_CONVERTER
15 #ifdef TRACE_AUDIO_CONVERTER
17 # define TRACE(x...) printf(x)
24 inline int operator()(const void* buffer
) const {
25 // 0 == mid, -1.0 == bottom, 1.0 == top
26 float b
= *(float*)buffer
;
31 return (int)((double)b
* (double)0x7fffffff);
36 inline int operator()(const void* buffer
) const {
37 // 0 == mid, 0x80000001 == bottom, 0x7fffffff == top
38 int b
= *(int*)buffer
;
46 inline int operator()(const void* buffer
) const {
47 // 0 == mid, -32767 == bottom, +32767
48 short b
= *(short*)buffer
;
51 return int(int64(b
) * 0x7fffffff / 32767);
56 inline int operator()(const void* buffer
) const {
57 // 128 == mid, 1 == bottom, 255 == top
58 uchar b
= *(uchar
*)buffer
;
61 return int((int64(b
) - 0x80) * 0x7fffffff / 127);
66 inline int operator()(const void* buffer
) const {
67 // 0 == mid, -127 == bottom, +127 == top
68 char b
= *(char*)buffer
;
71 return int(int64(b
) * 0x7fffffff / 127);
76 inline void operator()(void* buffer
, int value
) const {
77 *(float*)buffer
= (double)value
/ (double)0x7fffffff;
83 inline void operator()(void* buffer
, int value
) const {
84 *(int*)buffer
= value
;
89 inline void operator()(void* buffer
, int value
) const {
90 *(short*)buffer
= (short)(value
/ (int)0x10000);
95 inline void operator()(void* buffer
, int value
) const {
96 *(uchar
*)buffer
= (uchar
)(value
/ (int)0x1000000 + 128);
101 inline void operator()(void* buffer
, int value
) const {
102 *(char*)buffer
= (char)(value
/ (int)0x1000000);
107 template<typename ReadT
, typename WriteT
>
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
;
124 swap_sample_byte_order(void* buffer
, uint32 format
, size_t length
)
126 type_code type
= B_ANY_TYPE
;
128 case media_raw_audio_format::B_AUDIO_FLOAT
:
131 case media_raw_audio_format::B_AUDIO_INT
:
134 case media_raw_audio_format::B_AUDIO_SHORT
:
137 case media_raw_audio_format::B_AUDIO_UCHAR
:
139 case media_raw_audio_format::B_AUDIO_CHAR
:
142 if (type
!= B_ANY_TYPE
)
143 swap_data(type
, buffer
, length
, B_SWAP_ALWAYS
);
150 AudioFormatConverter::AudioFormatConverter(AudioReader
* source
, uint32 format
,
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
178 AudioFormatConverter::~AudioFormatConverter()
184 AudioFormatConverter::InitialLatency() const
186 return fSource
->InitialLatency();
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();
195 TRACE("AudioFormatConverter::Read() done 1\n");
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
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
) {
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
:
249 case media_raw_audio_format::B_AUDIO_INT
:
250 convert(ReadFloat(), WriteInt(), inBuffer
, (char*)buffer
,
251 frames
, inSampleSize
, outSampleSize
, channelCount
);
253 case media_raw_audio_format::B_AUDIO_SHORT
:
254 convert(ReadFloat(), WriteShort(), inBuffer
, (char*)buffer
,
255 frames
, inSampleSize
, outSampleSize
, channelCount
);
257 case media_raw_audio_format::B_AUDIO_UCHAR
:
258 convert(ReadFloat(), WriteUChar(), inBuffer
, (char*)buffer
,
259 frames
, inSampleSize
, outSampleSize
, channelCount
);
261 case media_raw_audio_format::B_AUDIO_CHAR
:
262 convert(ReadFloat(), WriteChar(), inBuffer
, (char*)buffer
,
263 frames
, inSampleSize
, outSampleSize
, channelCount
);
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
);
274 case media_raw_audio_format::B_AUDIO_INT
:
276 case media_raw_audio_format::B_AUDIO_SHORT
:
277 convert(ReadInt(), WriteShort(), inBuffer
, (char*)buffer
,
278 frames
, inSampleSize
, outSampleSize
, channelCount
);
280 case media_raw_audio_format::B_AUDIO_UCHAR
:
281 convert(ReadInt(), WriteUChar(), inBuffer
, (char*)buffer
,
282 frames
, inSampleSize
, outSampleSize
, channelCount
);
284 case media_raw_audio_format::B_AUDIO_CHAR
:
285 convert(ReadInt(), WriteChar(), inBuffer
, (char*)buffer
,
286 frames
, inSampleSize
, outSampleSize
, channelCount
);
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
);
297 case media_raw_audio_format::B_AUDIO_INT
:
298 convert(ReadShort(), WriteInt(), inBuffer
, (char*)buffer
,
299 frames
, inSampleSize
, outSampleSize
, channelCount
);
301 case media_raw_audio_format::B_AUDIO_SHORT
:
303 case media_raw_audio_format::B_AUDIO_UCHAR
:
304 convert(ReadShort(), WriteUChar(), inBuffer
, (char*)buffer
,
305 frames
, inSampleSize
, outSampleSize
, channelCount
);
307 case media_raw_audio_format::B_AUDIO_CHAR
:
308 convert(ReadShort(), WriteChar(), inBuffer
, (char*)buffer
,
309 frames
, inSampleSize
, outSampleSize
, channelCount
);
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
);
320 case media_raw_audio_format::B_AUDIO_INT
:
321 convert(ReadUChar(), WriteInt(), inBuffer
, (char*)buffer
,
322 frames
, inSampleSize
, outSampleSize
, channelCount
);
324 case media_raw_audio_format::B_AUDIO_SHORT
:
325 convert(ReadUChar(), WriteShort(), inBuffer
, (char*)buffer
,
326 frames
, inSampleSize
, outSampleSize
, channelCount
);
328 case media_raw_audio_format::B_AUDIO_UCHAR
:
330 case media_raw_audio_format::B_AUDIO_CHAR
:
331 convert(ReadUChar(), WriteChar(), inBuffer
, (char*)buffer
,
332 frames
, inSampleSize
, outSampleSize
, channelCount
);
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
);
343 case media_raw_audio_format::B_AUDIO_INT
:
344 convert(ReadChar(), WriteInt(), inBuffer
, (char*)buffer
,
345 frames
, inSampleSize
, outSampleSize
, channelCount
);
347 case media_raw_audio_format::B_AUDIO_SHORT
:
348 convert(ReadChar(), WriteShort(), inBuffer
, (char*)buffer
,
349 frames
, inSampleSize
, outSampleSize
, channelCount
);
351 case media_raw_audio_format::B_AUDIO_UCHAR
:
352 convert(ReadChar(), WriteUChar(), inBuffer
, (char*)buffer
,
353 frames
, inSampleSize
, outSampleSize
, channelCount
);
355 case media_raw_audio_format::B_AUDIO_CHAR
:
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");
373 AudioFormatConverter::InitCheck() const
375 status_t error
= AudioReader::InitCheck();
376 if (error
== B_OK
&& !fSource
)
379 error
= fSource
->InitCheck();
385 AudioFormatConverter::Source() const