xref: /haiku/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp (revision 37c7d5d83a2372a6971e383411d5bacbeef0ebdc)
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 != source->Format().u.raw_audio.format
41 			|| source->Format().u.raw_audio.byte_order != hostByteOrder) {
42 			TRACE("AudioAdapter() - using format converter\n");
43 			fFormatConverter = new (nothrow) AudioFormatConverter(source,
44 				fFormat.u.raw_audio.format, hostByteOrder);
45 			source = fFormatConverter;
46 		}
47 
48 		if (fFormat.u.raw_audio.frame_rate
49 				!= source->Format().u.raw_audio.frame_rate) {
50 			TRACE("AudioAdapter() - using resampler\n");
51 			fResampler = new (nothrow) AudioResampler(source,
52 				fFormat.u.raw_audio.frame_rate);
53 			source = fResampler;
54 		}
55 
56 		if (fFormat.u.raw_audio.channel_count
57 				!= source->Format().u.raw_audio.channel_count) {
58 			TRACE("AudioAdapter() - using channel converter (%ld -> %ld)\n",
59 				source->Format().u.raw_audio.channel_count,
60 				fFormat.u.raw_audio.channel_count);
61 			fChannelConverter = new (nothrow) AudioChannelConverter(source,
62 				fFormat);
63 			source = fChannelConverter;
64 		}
65 
66 		fFinalConverter = source;
67 	} else
68 		fSource = NULL;
69 }
70 
71 
72 AudioAdapter::~AudioAdapter()
73 {
74 	delete fFormatConverter;
75 	delete fChannelConverter;
76 	delete fResampler;
77 }
78 
79 
80 bigtime_t
81 AudioAdapter::InitialLatency() const
82 {
83 	return fSource->InitialLatency();
84 }
85 
86 
87 status_t
88 AudioAdapter::Read(void* buffer, int64 pos, int64 frames)
89 {
90 //	TRACE("AudioAdapter::Read(%p, %Ld, %Ld)\n", buffer, pos, frames);
91 	status_t error = InitCheck();
92 	if (error != B_OK)
93 		return error;
94 	pos += fOutOffset;
95 	status_t ret = fFinalConverter->Read(buffer, pos, frames);
96 //	TRACE("AudioAdapter::Read() done: %s\n", strerror(ret));
97 	return ret;
98 }
99 
100 
101 status_t
102 AudioAdapter::InitCheck() const
103 {
104 	status_t error = AudioReader::InitCheck();
105 	if (error == B_OK && !fFinalConverter)
106 		error = B_NO_INIT;
107 	if (error == B_OK && fFinalConverter)
108 		error = fFinalConverter->InitCheck();
109 	return error;
110 }
111 
112 
113 AudioReader*
114 AudioAdapter::Source() const
115 {
116 	return fSource;
117 }
118 
119