10fc56ed5SStephan Aßmus /*
28dd3060dSAxel Dörfler * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de>
38dd3060dSAxel Dörfler * Copyright 2008 Stephan Aßmus <superstippi@gmx.de>
40fc56ed5SStephan Aßmus * All rights reserved. Distributed under the terms of the MIT licensce.
50fc56ed5SStephan Aßmus */
60fc56ed5SStephan Aßmus
78dd3060dSAxel Dörfler
80fc56ed5SStephan Aßmus #include "AudioFormatConverter.h"
90fc56ed5SStephan Aßmus
100fc56ed5SStephan Aßmus #include <ByteOrder.h>
110fc56ed5SStephan Aßmus #include <MediaDefs.h>
120fc56ed5SStephan Aßmus
130fc56ed5SStephan Aßmus
140fc56ed5SStephan Aßmus //#define TRACE_AUDIO_CONVERTER
150fc56ed5SStephan Aßmus #ifdef TRACE_AUDIO_CONVERTER
1630816b7eSStephan Aßmus # include <stdio.h>
170fc56ed5SStephan Aßmus # define TRACE(x...) printf(x)
180fc56ed5SStephan Aßmus #else
190fc56ed5SStephan Aßmus # define TRACE(x...)
200fc56ed5SStephan Aßmus #endif
210fc56ed5SStephan Aßmus
220fc56ed5SStephan Aßmus
230fc56ed5SStephan Aßmus struct ReadFloat {
operator ()ReadFloat240fc56ed5SStephan Aßmus inline int operator()(const void* buffer) const {
250fc56ed5SStephan Aßmus // 0 == mid, -1.0 == bottom, 1.0 == top
260fc56ed5SStephan Aßmus float b = *(float*)buffer;
270fc56ed5SStephan Aßmus if (b < -1.0f)
280fc56ed5SStephan Aßmus b = -1.0f;
290fc56ed5SStephan Aßmus else if (b > 1.0f)
300fc56ed5SStephan Aßmus b = 1.0f;
310fc56ed5SStephan Aßmus return (int)((double)b * (double)0x7fffffff);
320fc56ed5SStephan Aßmus }
330fc56ed5SStephan Aßmus };
340fc56ed5SStephan Aßmus
350fc56ed5SStephan Aßmus struct ReadInt {
operator ()ReadInt360fc56ed5SStephan Aßmus inline int operator()(const void* buffer) const {
370fc56ed5SStephan Aßmus // 0 == mid, 0x80000001 == bottom, 0x7fffffff == top
38edd11dcdSJérôme Duval int b = *(int*)buffer;
394c688b93SJérôme Duval if (b == INT_MIN)
400fc56ed5SStephan Aßmus b++;
410fc56ed5SStephan Aßmus return b;
420fc56ed5SStephan Aßmus }
430fc56ed5SStephan Aßmus };
440fc56ed5SStephan Aßmus
450fc56ed5SStephan Aßmus struct ReadShort {
operator ()ReadShort460fc56ed5SStephan Aßmus inline int operator()(const void* buffer) const {
470fc56ed5SStephan Aßmus // 0 == mid, -32767 == bottom, +32767
480fc56ed5SStephan Aßmus short b = *(short*)buffer;
490fc56ed5SStephan Aßmus if (b == -32768)
500fc56ed5SStephan Aßmus b++;
510fc56ed5SStephan Aßmus return int(int64(b) * 0x7fffffff / 32767);
520fc56ed5SStephan Aßmus }
530fc56ed5SStephan Aßmus };
540fc56ed5SStephan Aßmus
550fc56ed5SStephan Aßmus struct ReadUChar {
operator ()ReadUChar560fc56ed5SStephan Aßmus inline int operator()(const void* buffer) const {
570fc56ed5SStephan Aßmus // 128 == mid, 1 == bottom, 255 == top
580fc56ed5SStephan Aßmus uchar b = *(uchar*)buffer;
590fc56ed5SStephan Aßmus if (b == 0)
600fc56ed5SStephan Aßmus b++;
610fc56ed5SStephan Aßmus return int((int64(b) - 0x80) * 0x7fffffff / 127);
620fc56ed5SStephan Aßmus }
630fc56ed5SStephan Aßmus };
640fc56ed5SStephan Aßmus
650fc56ed5SStephan Aßmus struct ReadChar {
operator ()ReadChar660fc56ed5SStephan Aßmus inline int operator()(const void* buffer) const {
670fc56ed5SStephan Aßmus // 0 == mid, -127 == bottom, +127 == top
680fc56ed5SStephan Aßmus char b = *(char*)buffer;
690fc56ed5SStephan Aßmus if (b == 0)
700fc56ed5SStephan Aßmus b++;
710fc56ed5SStephan Aßmus return int(int64(b) * 0x7fffffff / 127);
720fc56ed5SStephan Aßmus }
730fc56ed5SStephan Aßmus };
740fc56ed5SStephan Aßmus
750fc56ed5SStephan Aßmus struct WriteFloat {
operator ()WriteFloat760fc56ed5SStephan Aßmus inline void operator()(void* buffer, int value) const {
770fc56ed5SStephan Aßmus *(float*)buffer = (double)value / (double)0x7fffffff;
780fc56ed5SStephan Aßmus }
790fc56ed5SStephan Aßmus
800fc56ed5SStephan Aßmus };
810fc56ed5SStephan Aßmus
820fc56ed5SStephan Aßmus struct WriteInt {
operator ()WriteInt830fc56ed5SStephan Aßmus inline void operator()(void* buffer, int value) const {
840fc56ed5SStephan Aßmus *(int*)buffer = value;
850fc56ed5SStephan Aßmus }
860fc56ed5SStephan Aßmus };
870fc56ed5SStephan Aßmus
880fc56ed5SStephan Aßmus struct WriteShort {
operator ()WriteShort890fc56ed5SStephan Aßmus inline void operator()(void* buffer, int value) const {
900fc56ed5SStephan Aßmus *(short*)buffer = (short)(value / (int)0x10000);
910fc56ed5SStephan Aßmus }
920fc56ed5SStephan Aßmus };
930fc56ed5SStephan Aßmus
940fc56ed5SStephan Aßmus struct WriteUChar {
operator ()WriteUChar950fc56ed5SStephan Aßmus inline void operator()(void* buffer, int value) const {
960fc56ed5SStephan Aßmus *(uchar*)buffer = (uchar)(value / (int)0x1000000 + 128);
970fc56ed5SStephan Aßmus }
980fc56ed5SStephan Aßmus };
990fc56ed5SStephan Aßmus
1000fc56ed5SStephan Aßmus struct WriteChar {
operator ()WriteChar1010fc56ed5SStephan Aßmus inline void operator()(void* buffer, int value) const {
1020fc56ed5SStephan Aßmus *(char*)buffer = (char)(value / (int)0x1000000);
1030fc56ed5SStephan Aßmus }
1040fc56ed5SStephan Aßmus };
1050fc56ed5SStephan Aßmus
1060fc56ed5SStephan Aßmus
1070fc56ed5SStephan Aßmus template<typename ReadT, typename WriteT>
1080fc56ed5SStephan Aßmus static void
convert(const ReadT & read,const WriteT & write,const char * inBuffer,char * outBuffer,int32 frames,int32 inSampleSize,int32 outSampleSize,int32 channelCount)1090fc56ed5SStephan Aßmus convert(const ReadT& read, const WriteT& write,
1100fc56ed5SStephan Aßmus const char* inBuffer, char* outBuffer, int32 frames,
1110fc56ed5SStephan Aßmus int32 inSampleSize, int32 outSampleSize, int32 channelCount)
1120fc56ed5SStephan Aßmus {
1130fc56ed5SStephan Aßmus for (int32 i = 0; i < frames; i++) {
1140fc56ed5SStephan Aßmus for (int32 c = 0; c < channelCount; c++) {
1150fc56ed5SStephan Aßmus write(outBuffer, read(inBuffer));
1160fc56ed5SStephan Aßmus inBuffer += inSampleSize;
1170fc56ed5SStephan Aßmus outBuffer += outSampleSize;
1180fc56ed5SStephan Aßmus }
1190fc56ed5SStephan Aßmus }
1200fc56ed5SStephan Aßmus }
1210fc56ed5SStephan Aßmus
1220fc56ed5SStephan Aßmus
1238dd3060dSAxel Dörfler static void
swap_sample_byte_order(void * buffer,uint32 format,size_t length)1240fc56ed5SStephan Aßmus swap_sample_byte_order(void* buffer, uint32 format, size_t length)
1250fc56ed5SStephan Aßmus {
1260fc56ed5SStephan Aßmus type_code type = B_ANY_TYPE;
1270fc56ed5SStephan Aßmus switch (format) {
1280fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
1290fc56ed5SStephan Aßmus type = B_FLOAT_TYPE;
1300fc56ed5SStephan Aßmus break;
1310fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
1320fc56ed5SStephan Aßmus type = B_INT32_TYPE;
1330fc56ed5SStephan Aßmus break;
1340fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
1350fc56ed5SStephan Aßmus type = B_INT16_TYPE;
1360fc56ed5SStephan Aßmus break;
1370fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
1380fc56ed5SStephan Aßmus break;
1390fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
1400fc56ed5SStephan Aßmus break;
1410fc56ed5SStephan Aßmus }
1420fc56ed5SStephan Aßmus if (type != B_ANY_TYPE)
1430fc56ed5SStephan Aßmus swap_data(type, buffer, length, B_SWAP_ALWAYS);
1440fc56ed5SStephan Aßmus }
1450fc56ed5SStephan Aßmus
1460fc56ed5SStephan Aßmus
1478dd3060dSAxel Dörfler // #pragma mark -
1488dd3060dSAxel Dörfler
1498dd3060dSAxel Dörfler
AudioFormatConverter(AudioReader * source,uint32 format,uint32 byteOrder)1508dd3060dSAxel Dörfler AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format,
15130816b7eSStephan Aßmus uint32 byteOrder)
1528dd3060dSAxel Dörfler :
1538dd3060dSAxel Dörfler AudioReader(),
1548dd3060dSAxel Dörfler fSource(NULL)
1558dd3060dSAxel Dörfler {
1568dd3060dSAxel Dörfler uint32 hostByteOrder
1578dd3060dSAxel Dörfler = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
1588dd3060dSAxel Dörfler if (source && source->Format().type == B_MEDIA_RAW_AUDIO
1598dd3060dSAxel Dörfler && source->Format().u.raw_audio.byte_order == hostByteOrder) {
1608dd3060dSAxel Dörfler fFormat = source->Format();
1618dd3060dSAxel Dörfler fFormat.u.raw_audio.format = format;
16230816b7eSStephan Aßmus fFormat.u.raw_audio.byte_order = byteOrder;
1638dd3060dSAxel Dörfler int32 inSampleSize = source->Format().u.raw_audio.format
1648dd3060dSAxel Dörfler & media_raw_audio_format::B_AUDIO_SIZE_MASK;
1658dd3060dSAxel Dörfler int32 outSampleSize = fFormat.u.raw_audio.format
1668dd3060dSAxel Dörfler & media_raw_audio_format::B_AUDIO_SIZE_MASK;
1678dd3060dSAxel Dörfler if (inSampleSize != outSampleSize) {
1688dd3060dSAxel Dörfler fFormat.u.raw_audio.buffer_size
1698dd3060dSAxel Dörfler = source->Format().u.raw_audio.buffer_size * outSampleSize
1708dd3060dSAxel Dörfler / inSampleSize;
1718dd3060dSAxel Dörfler }
1728dd3060dSAxel Dörfler } else
1738dd3060dSAxel Dörfler source = NULL;
1748dd3060dSAxel Dörfler fSource = source;
1758dd3060dSAxel Dörfler }
1768dd3060dSAxel Dörfler
1778dd3060dSAxel Dörfler
~AudioFormatConverter()1788dd3060dSAxel Dörfler AudioFormatConverter::~AudioFormatConverter()
1798dd3060dSAxel Dörfler {
1808dd3060dSAxel Dörfler }
1818dd3060dSAxel Dörfler
1828dd3060dSAxel Dörfler
1838dd3060dSAxel Dörfler bigtime_t
InitialLatency() const1848dd3060dSAxel Dörfler AudioFormatConverter::InitialLatency() const
1858dd3060dSAxel Dörfler {
186edd11dcdSJérôme Duval return fSource->InitialLatency();
1878dd3060dSAxel Dörfler }
1888dd3060dSAxel Dörfler
1890fc56ed5SStephan Aßmus status_t
Read(void * buffer,int64 pos,int64 frames)1900fc56ed5SStephan Aßmus AudioFormatConverter::Read(void* buffer, int64 pos, int64 frames)
1910fc56ed5SStephan Aßmus {
192*425ac1b6SAlexander von Gluck IV TRACE("AudioFormatConverter::Read(%p, %lld, %lld)\n", buffer, pos, frames);
1930fc56ed5SStephan Aßmus status_t error = InitCheck();
1940fc56ed5SStephan Aßmus if (error != B_OK) {
1950fc56ed5SStephan Aßmus TRACE("AudioFormatConverter::Read() done 1\n");
1960fc56ed5SStephan Aßmus return error;
1970fc56ed5SStephan Aßmus }
1980fc56ed5SStephan Aßmus pos += fOutOffset;
1990fc56ed5SStephan Aßmus
2000fc56ed5SStephan Aßmus if (fFormat.u.raw_audio.format == fSource->Format().u.raw_audio.format
2010fc56ed5SStephan Aßmus && fFormat.u.raw_audio.byte_order
2020fc56ed5SStephan Aßmus == fSource->Format().u.raw_audio.byte_order) {
2030fc56ed5SStephan Aßmus TRACE("AudioFormatConverter::Read() done 2\n");
2040fc56ed5SStephan Aßmus return fSource->Read(buffer, pos, frames);
2050fc56ed5SStephan Aßmus }
2060fc56ed5SStephan Aßmus
2070fc56ed5SStephan Aßmus int32 inSampleSize = fSource->Format().u.raw_audio.format
2080fc56ed5SStephan Aßmus & media_raw_audio_format::B_AUDIO_SIZE_MASK;
2090fc56ed5SStephan Aßmus int32 outSampleSize = fFormat.u.raw_audio.format
2100fc56ed5SStephan Aßmus & media_raw_audio_format::B_AUDIO_SIZE_MASK;
2110fc56ed5SStephan Aßmus int32 channelCount = fFormat.u.raw_audio.channel_count;
2120fc56ed5SStephan Aßmus int32 inFrameSize = inSampleSize * channelCount;
2130fc56ed5SStephan Aßmus int32 outFrameSize = outSampleSize * channelCount;
2140fc56ed5SStephan Aßmus char* reformatBuffer = NULL;
2150fc56ed5SStephan Aßmus char* inBuffer = (char*)buffer;
2160fc56ed5SStephan Aßmus
2170fc56ed5SStephan Aßmus #ifdef TRACE_AUDIO_CONVERTER
2180fc56ed5SStephan Aßmus char formatString[256];
2190fc56ed5SStephan Aßmus string_for_format(fSource->Format(), formatString, 256);
2200fc56ed5SStephan Aßmus TRACE(" source format: %s\n", formatString);
2210fc56ed5SStephan Aßmus TRACE(" in format : format: %lx, sample size: %ld, channels: %ld, "
2220fc56ed5SStephan Aßmus "byte order: %lu\n", fSource->Format().u.raw_audio.format,
2230fc56ed5SStephan Aßmus inSampleSize, channelCount,
2240fc56ed5SStephan Aßmus fSource->Format().u.raw_audio.byte_order);
2250fc56ed5SStephan Aßmus TRACE(" out format: format: %lx, sample size: %ld, channels: %ld, "
2260fc56ed5SStephan Aßmus "byte order: %lu\n", fFormat.u.raw_audio.format, outSampleSize,
2270fc56ed5SStephan Aßmus channelCount, fFormat.u.raw_audio.byte_order);
2280fc56ed5SStephan Aßmus #endif // TRACE_AUDIO_CONVERTER
2290fc56ed5SStephan Aßmus
2300fc56ed5SStephan Aßmus if (inSampleSize != outSampleSize) {
2310fc56ed5SStephan Aßmus reformatBuffer = new char[frames * inFrameSize];
2320fc56ed5SStephan Aßmus inBuffer = reformatBuffer;
2330fc56ed5SStephan Aßmus }
2340fc56ed5SStephan Aßmus error = fSource->Read(inBuffer, pos, frames);
2350fc56ed5SStephan Aßmus // convert samples to host endianess
2360fc56ed5SStephan Aßmus uint32 hostByteOrder
2370fc56ed5SStephan Aßmus = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
2380fc56ed5SStephan Aßmus if (fSource->Format().u.raw_audio.byte_order != hostByteOrder) {
2390fc56ed5SStephan Aßmus swap_sample_byte_order(inBuffer, fSource->Format().u.raw_audio.format,
2400fc56ed5SStephan Aßmus frames * inFrameSize);
2410fc56ed5SStephan Aßmus }
2420fc56ed5SStephan Aßmus // convert the sample type
2430fc56ed5SStephan Aßmus switch (fSource->Format().u.raw_audio.format) {
2440fc56ed5SStephan Aßmus // float
2450fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
2460fc56ed5SStephan Aßmus switch (fFormat.u.raw_audio.format) {
2470fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
2480fc56ed5SStephan Aßmus break;
2490fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
2500fc56ed5SStephan Aßmus convert(ReadFloat(), WriteInt(), inBuffer, (char*)buffer,
2510fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2520fc56ed5SStephan Aßmus break;
2530fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
2540fc56ed5SStephan Aßmus convert(ReadFloat(), WriteShort(), inBuffer, (char*)buffer,
2550fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2560fc56ed5SStephan Aßmus break;
2570fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
2580fc56ed5SStephan Aßmus convert(ReadFloat(), WriteUChar(), inBuffer, (char*)buffer,
2590fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2600fc56ed5SStephan Aßmus break;
2610fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
2620fc56ed5SStephan Aßmus convert(ReadFloat(), WriteChar(), inBuffer, (char*)buffer,
2630fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2640fc56ed5SStephan Aßmus break;
2650fc56ed5SStephan Aßmus }
2660fc56ed5SStephan Aßmus break;
2670fc56ed5SStephan Aßmus // int
2680fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
2690fc56ed5SStephan Aßmus switch (fFormat.u.raw_audio.format) {
2700fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
2710fc56ed5SStephan Aßmus convert(ReadInt(), WriteFloat(), inBuffer, (char*)buffer,
2720fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2730fc56ed5SStephan Aßmus break;
2740fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
2750fc56ed5SStephan Aßmus break;
2760fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
2770fc56ed5SStephan Aßmus convert(ReadInt(), WriteShort(), inBuffer, (char*)buffer,
2780fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2790fc56ed5SStephan Aßmus break;
2800fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
2810fc56ed5SStephan Aßmus convert(ReadInt(), WriteUChar(), inBuffer, (char*)buffer,
2820fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2830fc56ed5SStephan Aßmus break;
2840fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
2850fc56ed5SStephan Aßmus convert(ReadInt(), WriteChar(), inBuffer, (char*)buffer,
2860fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2870fc56ed5SStephan Aßmus break;
2880fc56ed5SStephan Aßmus }
2890fc56ed5SStephan Aßmus break;
2900fc56ed5SStephan Aßmus // short
2910fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
2920fc56ed5SStephan Aßmus switch (fFormat.u.raw_audio.format) {
2930fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
2940fc56ed5SStephan Aßmus convert(ReadShort(), WriteFloat(), inBuffer, (char*)buffer,
2950fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
2960fc56ed5SStephan Aßmus break;
2970fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
2980fc56ed5SStephan Aßmus convert(ReadShort(), WriteInt(), inBuffer, (char*)buffer,
2990fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3000fc56ed5SStephan Aßmus break;
3010fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
3020fc56ed5SStephan Aßmus break;
3030fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
3040fc56ed5SStephan Aßmus convert(ReadShort(), WriteUChar(), inBuffer, (char*)buffer,
3050fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3060fc56ed5SStephan Aßmus break;
3070fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
3080fc56ed5SStephan Aßmus convert(ReadShort(), WriteChar(), inBuffer, (char*)buffer,
3090fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3100fc56ed5SStephan Aßmus break;
3110fc56ed5SStephan Aßmus }
3120fc56ed5SStephan Aßmus break;
3130fc56ed5SStephan Aßmus // uchar
3140fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
3150fc56ed5SStephan Aßmus switch (fFormat.u.raw_audio.format) {
3160fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
3170fc56ed5SStephan Aßmus convert(ReadUChar(), WriteFloat(), inBuffer, (char*)buffer,
3180fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3190fc56ed5SStephan Aßmus break;
3200fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
3210fc56ed5SStephan Aßmus convert(ReadUChar(), WriteInt(), inBuffer, (char*)buffer,
3220fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3230fc56ed5SStephan Aßmus break;
3240fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
3250fc56ed5SStephan Aßmus convert(ReadUChar(), WriteShort(), inBuffer, (char*)buffer,
3260fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3270fc56ed5SStephan Aßmus break;
3280fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
3290fc56ed5SStephan Aßmus break;
3300fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
3310fc56ed5SStephan Aßmus convert(ReadUChar(), WriteChar(), inBuffer, (char*)buffer,
3320fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3330fc56ed5SStephan Aßmus break;
3340fc56ed5SStephan Aßmus }
3350fc56ed5SStephan Aßmus break;
3360fc56ed5SStephan Aßmus // char
3370fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
3380fc56ed5SStephan Aßmus switch (fFormat.u.raw_audio.format) {
3390fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_FLOAT:
3400fc56ed5SStephan Aßmus convert(ReadChar(), WriteFloat(), inBuffer, (char*)buffer,
3410fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3420fc56ed5SStephan Aßmus break;
3430fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_INT:
3440fc56ed5SStephan Aßmus convert(ReadChar(), WriteInt(), inBuffer, (char*)buffer,
3450fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3460fc56ed5SStephan Aßmus break;
3470fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_SHORT:
3480fc56ed5SStephan Aßmus convert(ReadChar(), WriteShort(), inBuffer, (char*)buffer,
3490fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3500fc56ed5SStephan Aßmus break;
3510fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_UCHAR:
3520fc56ed5SStephan Aßmus convert(ReadChar(), WriteUChar(), inBuffer, (char*)buffer,
3530fc56ed5SStephan Aßmus frames, inSampleSize, outSampleSize, channelCount);
3540fc56ed5SStephan Aßmus break;
3550fc56ed5SStephan Aßmus case media_raw_audio_format::B_AUDIO_CHAR:
3560fc56ed5SStephan Aßmus break;
3570fc56ed5SStephan Aßmus }
3580fc56ed5SStephan Aßmus break;
3590fc56ed5SStephan Aßmus }
3600fc56ed5SStephan Aßmus // convert samples to output endianess
3610fc56ed5SStephan Aßmus if (fFormat.u.raw_audio.byte_order != hostByteOrder) {
3620fc56ed5SStephan Aßmus swap_sample_byte_order(buffer, fFormat.u.raw_audio.format,
3630fc56ed5SStephan Aßmus frames * outFrameSize);
3640fc56ed5SStephan Aßmus }
3650fc56ed5SStephan Aßmus
3660fc56ed5SStephan Aßmus delete[] reformatBuffer;
3670fc56ed5SStephan Aßmus TRACE("AudioFormatConverter::Read() done\n");
3680fc56ed5SStephan Aßmus return B_OK;
3690fc56ed5SStephan Aßmus }
3700fc56ed5SStephan Aßmus
3710fc56ed5SStephan Aßmus
3720fc56ed5SStephan Aßmus status_t
InitCheck() const3730fc56ed5SStephan Aßmus AudioFormatConverter::InitCheck() const
3740fc56ed5SStephan Aßmus {
3750fc56ed5SStephan Aßmus status_t error = AudioReader::InitCheck();
3760fc56ed5SStephan Aßmus if (error == B_OK && !fSource)
3770fc56ed5SStephan Aßmus error = B_NO_INIT;
3780fc56ed5SStephan Aßmus if (error == B_OK)
3790fc56ed5SStephan Aßmus error = fSource->InitCheck();
3800fc56ed5SStephan Aßmus return error;
3810fc56ed5SStephan Aßmus }
3820fc56ed5SStephan Aßmus
3830fc56ed5SStephan Aßmus
3840fc56ed5SStephan Aßmus AudioReader*
Source() const3850fc56ed5SStephan Aßmus AudioFormatConverter::Source() const
3860fc56ed5SStephan Aßmus {
3870fc56ed5SStephan Aßmus return fSource;
3880fc56ed5SStephan Aßmus }
3890fc56ed5SStephan Aßmus
390