* Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de>
* All rights reserved. Distributed under the terms of the MIT licensce.
*/
#include "AudioAdapter.h"
#include <new>
#include <stdio.h>
#include <string.h>
#include <ByteOrder.h>
#include "AudioChannelConverter.h"
#include "AudioFormatConverter.h"
#include "AudioResampler.h"
using std::nothrow;
#ifdef TRACE_AUDIO_ADAPTER
# define TRACE(x...) printf(x)
#else
# define TRACE(x...)
#endif
AudioAdapter::AudioAdapter(AudioReader* source, const media_format& format)
: AudioReader(format),
fSource(source),
fFinalConverter(NULL),
fFormatConverter(NULL),
fChannelConverter(NULL),
fResampler(NULL)
{
uint32 hostByteOrder
= (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
fFormat.u.raw_audio.byte_order = hostByteOrder;
if (source && source->Format().type == B_MEDIA_RAW_AUDIO) {
if (fFormat.u.raw_audio.format != 0
&& (fFormat.u.raw_audio.format
!= source->Format().u.raw_audio.format
|| source->Format().u.raw_audio.byte_order != hostByteOrder)) {
TRACE("AudioAdapter() - using format converter\n");
fFormatConverter = new (nothrow) AudioFormatConverter(source,
fFormat.u.raw_audio.format, hostByteOrder);
source = fFormatConverter;
}
if (fFormat.u.raw_audio.frame_rate != 0
&& fFormat.u.raw_audio.frame_rate
!= source->Format().u.raw_audio.frame_rate) {
TRACE("AudioAdapter() - using resampler (%.1f -> %.1f)\n",
source->Format().u.raw_audio.frame_rate,
fFormat.u.raw_audio.frame_rate);
fResampler = new (nothrow) AudioResampler(source,
fFormat.u.raw_audio.frame_rate);
source = fResampler;
}
if (fFormat.u.raw_audio.channel_count != 0
&& fFormat.u.raw_audio.channel_count
!= source->Format().u.raw_audio.channel_count) {
TRACE("AudioAdapter() - using channel converter (%ld -> %ld)\n",
source->Format().u.raw_audio.channel_count,
fFormat.u.raw_audio.channel_count);
fChannelConverter = new (nothrow) AudioChannelConverter(source,
fFormat);
source = fChannelConverter;
}
fFinalConverter = source;
} else
fSource = NULL;
}
AudioAdapter::~AudioAdapter()
{
delete fFormatConverter;
delete fChannelConverter;
delete fResampler;
}
bigtime_t
AudioAdapter::InitialLatency() const
{
return fSource->InitialLatency();
}
status_t
AudioAdapter::Read(void* buffer, int64 pos, int64 frames)
{
TRACE("AudioAdapter::Read(%p, %lld, %lld)\n", buffer, pos, frames);
status_t error = InitCheck();
if (error != B_OK)
return error;
pos += fOutOffset;
status_t ret = fFinalConverter->Read(buffer, pos, frames);
TRACE("AudioAdapter::Read() done: %s\n", strerror(ret));
return ret;
}
status_t
AudioAdapter::InitCheck() const
{
status_t error = AudioReader::InitCheck();
if (error == B_OK && !fFinalConverter)
error = B_NO_INIT;
if (error == B_OK && fFinalConverter)
error = fFinalConverter->InitCheck();
return error;
}
AudioReader*
AudioAdapter::Source() const
{
return fSource;
}