2 * Copyright 2008 Stephan Aßmus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT licensce.
7 #include "AudioChannelConverter.h"
16 //#define TRACE_AUDIO_CONVERTER
17 #ifdef TRACE_AUDIO_CONVERTER
18 # define TRACE(x...) printf(x)
24 template<typename Type
, typename BigType
>
26 convert(Type
* inBuffer
, Type
* outBuffer
, int32 inChannels
, int32 outChannels
,
29 // TODO: more conversions!
34 switch (outChannels
) {
36 for (int32 i
= 0; i
< frames
; i
++) {
37 *outBuffer
++ = *inBuffer
;
38 *outBuffer
++ = *inBuffer
++;
44 switch (outChannels
) {
46 for (int32 i
= 0; i
< frames
; i
++) {
48 = (Type
)((BigType
)inBuffer
[0] + inBuffer
[1]) / 2;
55 switch (outChannels
) {
57 for (int32 i
= 0; i
< frames
; i
++) {
58 outBuffer
[0] = inBuffer
[0];
59 outBuffer
[1] = inBuffer
[1];
60 inBuffer
+= outChannels
;
73 AudioChannelConverter::AudioChannelConverter(AudioReader
* source
,
74 const media_format
& format
)
75 : AudioReader(format
),
78 // TODO: check the format and make sure everything matches
79 // except for channel count
83 AudioChannelConverter::~AudioChannelConverter()
89 AudioChannelConverter::InitialLatency() const
91 return fSource
->InitialLatency();
96 AudioChannelConverter::Read(void* outBuffer
, int64 pos
, int64 frames
)
98 TRACE("AudioChannelConverter::Read(%p, %Ld, %Ld)\n", outBuffer
, pos
, frames
);
99 status_t error
= InitCheck();
104 int32 inChannels
= fSource
->Format().u
.raw_audio
.channel_count
;
105 int32 outChannels
= fFormat
.u
.raw_audio
.channel_count
;
106 TRACE(" convert %ld -> %ld channels\n", inChannels
, outChannels
);
108 int32 inSampleSize
= fSource
->Format().u
.raw_audio
.format
109 & media_raw_audio_format::B_AUDIO_SIZE_MASK
;
110 int32 inFrameSize
= inSampleSize
* inChannels
;
111 uint8
* inBuffer
= new (nothrow
) uint8
[inFrameSize
* frames
];
113 TRACE(" fSource->Read()\n");
114 status_t ret
= fSource
->Read(inBuffer
, pos
, frames
);
120 // We know that both formats are the same except for channel count
121 switch (fFormat
.u
.raw_audio
.format
) {
122 case media_raw_audio_format::B_AUDIO_FLOAT
:
123 convert
<float, float>((float*)inBuffer
, (float*)outBuffer
,
124 inChannels
, outChannels
, frames
);
126 case media_raw_audio_format::B_AUDIO_INT
:
127 convert
<int32
, int64
>((int32
*)inBuffer
, (int32
*)outBuffer
,
128 inChannels
, outChannels
, frames
);
130 case media_raw_audio_format::B_AUDIO_SHORT
:
131 convert
<int16
, int32
>((int16
*)inBuffer
, (int16
*)outBuffer
,
132 inChannels
, outChannels
, frames
);
134 case media_raw_audio_format::B_AUDIO_UCHAR
:
135 convert
<uint8
, uint16
>((uint8
*)inBuffer
, (uint8
*)outBuffer
,
136 inChannels
, outChannels
, frames
);
138 case media_raw_audio_format::B_AUDIO_CHAR
:
139 convert
<int8
, int16
>((int8
*)inBuffer
, (int8
*)outBuffer
,
140 inChannels
, outChannels
, frames
);
146 TRACE("AudioChannelConverter::Read() done: %s\n", strerror(ret
));
152 AudioChannelConverter::InitCheck() const
154 status_t error
= AudioReader::InitCheck();
155 if (error
== B_OK
&& !fSource
)
162 AudioChannelConverter::Source() const