1/* 2 * Copyright �� 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de> 3 * All rights reserved. Distributed under the terms of the MIT licensce. 4 */ 5#include "AudioAdapter.h" 6 7#include <new> 8#include <stdio.h> 9#include <string.h> 10 11#include <ByteOrder.h> 12 13#include "AudioChannelConverter.h" 14#include "AudioFormatConverter.h" 15#include "AudioResampler.h" 16 17using std::nothrow; 18 19//#define TRACE_AUDIO_ADAPTER 20#ifdef TRACE_AUDIO_ADAPTER 21# define TRACE(x...) printf(x) 22#else 23# define TRACE(x...) 24#endif 25 26 27AudioAdapter::AudioAdapter(AudioReader* source, const media_format& format) 28 : AudioReader(format), 29 fSource(source), 30 fFinalConverter(NULL), 31 fFormatConverter(NULL), 32 fChannelConverter(NULL), 33 fResampler(NULL) 34{ 35 uint32 hostByteOrder 36 = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; 37 fFormat.u.raw_audio.byte_order = hostByteOrder; 38 if (source && source->Format().type == B_MEDIA_RAW_AUDIO) { 39 40 if (fFormat.u.raw_audio.format != 0 41 && (fFormat.u.raw_audio.format 42 != source->Format().u.raw_audio.format 43 || source->Format().u.raw_audio.byte_order != hostByteOrder)) { 44 TRACE("AudioAdapter() - using format converter\n"); 45 fFormatConverter = new (nothrow) AudioFormatConverter(source, 46 fFormat.u.raw_audio.format, hostByteOrder); 47 source = fFormatConverter; 48 } 49 50 if (fFormat.u.raw_audio.frame_rate != 0 51 && fFormat.u.raw_audio.frame_rate 52 != source->Format().u.raw_audio.frame_rate) { 53 TRACE("AudioAdapter() - using resampler (%.1f -> %.1f)\n", 54 source->Format().u.raw_audio.frame_rate, 55 fFormat.u.raw_audio.frame_rate); 56 fResampler = new (nothrow) AudioResampler(source, 57 fFormat.u.raw_audio.frame_rate); 58 source = fResampler; 59 } 60 61 if (fFormat.u.raw_audio.channel_count != 0 62 && fFormat.u.raw_audio.channel_count 63 != source->Format().u.raw_audio.channel_count) { 64 TRACE("AudioAdapter() - using channel converter (%ld -> %ld)\n", 65 source->Format().u.raw_audio.channel_count, 66 fFormat.u.raw_audio.channel_count); 67 fChannelConverter = new (nothrow) AudioChannelConverter(source, 68 fFormat); 69 source = fChannelConverter; 70 } 71 72 fFinalConverter = source; 73 } else 74 fSource = NULL; 75} 76 77 78AudioAdapter::~AudioAdapter() 79{ 80 delete fFormatConverter; 81 delete fChannelConverter; 82 delete fResampler; 83} 84 85 86bigtime_t 87AudioAdapter::InitialLatency() const 88{ 89 return fSource->InitialLatency(); 90} 91 92 93status_t 94AudioAdapter::Read(void* buffer, int64 pos, int64 frames) 95{ 96 TRACE("AudioAdapter::Read(%p, %lld, %lld)\n", buffer, pos, frames); 97 status_t error = InitCheck(); 98 if (error != B_OK) 99 return error; 100 pos += fOutOffset; 101 status_t ret = fFinalConverter->Read(buffer, pos, frames); 102 TRACE("AudioAdapter::Read() done: %s\n", strerror(ret)); 103 return ret; 104} 105 106 107status_t 108AudioAdapter::InitCheck() const 109{ 110 status_t error = AudioReader::InitCheck(); 111 if (error == B_OK && !fFinalConverter) 112 error = B_NO_INIT; 113 if (error == B_OK && fFinalConverter) 114 error = fFinalConverter->InitCheck(); 115 return error; 116} 117 118 119AudioReader* 120AudioAdapter::Source() const 121{ 122 return fSource; 123} 124 125