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