xref: /haiku/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp (revision 106388ddbfdd00f4409c86bd3fe8d581bae532ec)
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 
17 using 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 
27 AudioAdapter::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 
78 AudioAdapter::~AudioAdapter()
79 {
80 	delete fFormatConverter;
81 	delete fChannelConverter;
82 	delete fResampler;
83 }
84 
85 
86 bigtime_t
87 AudioAdapter::InitialLatency() const
88 {
89 	return fSource->InitialLatency();
90 }
91 
92 
93 status_t
94 AudioAdapter::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 
107 status_t
108 AudioAdapter::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 
119 AudioReader*
120 AudioAdapter::Source() const
121 {
122 	return fSource;
123 }
124 
125