xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerInput.h (revision 837b16251d4b2b6249ebcaa19bb319cbe82c6126)
1 /*
2  * Copyright 2003-2010 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Marcus Overhagen
7  */
8 #ifndef _MIXER_INPUT_H
9 #define _MIXER_INPUT_H
10 
11 
12 #include <MediaNode.h>
13 #include <RealtimeAlloc.h>
14 
15 #include "MixerCore.h"
16 #include "MixerDebug.h"
17 #include "MixerUtils.h"
18 
19 
20 class ByteSwap;
21 class Resampler;
22 
23 
24 class MixerInput {
25 public:
26 								MixerInput(MixerCore* core,
27 									const media_input& input,
28 									float mixFrameRate, int32 mixFrameCount);
29 								~MixerInput();
30 
31 			int32				ID();
32 			media_input&		MediaInput();
33 
34 			void				BufferReceived(BBuffer* buffer);
35 
36 			void				UpdateResamplingAlgorithm();
37 
38 	// The physical input channels
39 			int					GetInputChannelCount();
40 			int					GetInputChannelType(int channel);
41 			void				SetInputChannelGain(int channel, float gain);
42 			float				GetInputChannelGain(int channel);
43 
44 	// The destinations for each channel
45 			void				AddInputChannelDestination(int channel,
46 									int destinationType);
47 			void				RemoveInputChannelDestination(int channel,
48 									int destinationType);
49 			bool				HasInputChannelDestination(int channel,
50 									int destinationType);
51 			int 				GetInputChannelForDestination(
52 									int destinationType);
53 				// returns -1 if not found
54 
55 	// The virtual mixer channels that are generated from destinations
56 			int					GetMixerChannelCount();
57 			void				SetMixerChannelGain(int mixerChannel,
58 									float gain);
59 			float				GetMixerChannelGain(int mixerChannel);
60 			int					GetMixerChannelType(int mixerChannel);
61 
62 			void				SetEnabled(bool enabled);
63 			bool				IsEnabled();
64 
65 	// only for use by MixerCore
66 			bool				GetMixerChannelInfo(int mixerChannel,
67 									int64 framepos, bigtime_t time,
68 									const float** _buffer,
69 									uint32* _sampleOffset, int* _type,
70 									float* _gain);
71 
72 protected:
73 	friend class MixerCore;
74 
75 			void				SetMixBufferFormat(int32 framerate,
76 									int32 frames);
77 
78 private:
79 			void				_UpdateInputChannelDestinationMask();
80 			void				_UpdateInputChannelDestinations();
81 
82 	struct input_chan_info {
83 		float*					buffer_base;
84 		uint32					destination_mask;	// multiple or no bits sets
85 		float					gain;
86 	};
87 
88 	struct mixer_chan_info {
89 		float*					buffer_base;
90 		int						destination_type;
91 		float					destination_gain;
92 	};
93 
94 private:
95 			MixerCore*			fCore;
96 			media_input			fInput;
97 			ByteSwap*			fInputByteSwap;
98 			float				fChannelTypeGain[MAX_CHANNEL_TYPES];
99 			bool				fEnabled;
100 			input_chan_info*	fInputChannelInfo; // array
101 			int					fInputChannelCount;
102 			uint32				fInputChannelMask;
103 			mixer_chan_info*	fMixerChannelInfo; // array
104 			int					fMixerChannelCount;
105 			float*				fMixBuffer;
106 			int32				fMixBufferFrameRate;
107 			int					fMixBufferFrameCount;
108 			int32				fLastDataFrameWritten;
109 			bigtime_t			fLastDataAvailableTime;
110 			double				fFractionalFrames;
111 			Resampler**			fResampler; // array
112 			rtm_pool*			fRtmPool;
113 			bool				fUserOverridesChannelDestinations;
114 			int32				fDebugMixBufferFrames;
115 };
116 
117 
118 inline int
119 MixerInput::GetMixerChannelCount()
120 {
121 	return fMixerChannelCount;
122 }
123 
124 
125 inline bool
126 MixerInput::GetMixerChannelInfo(int mixerChannel, int64 framepos,
127 	bigtime_t time, const float** buffer, uint32* sampleOffset, int* type,
128 	float* gain)
129 {
130 	// this function should not be called if we don't have a mix buffer!
131 	ASSERT(fMixBuffer != NULL);
132 	ASSERT(mixerChannel >= 0 && mixerChannel < fMixerChannelCount);
133 	if (!fEnabled)
134 		return false;
135 
136 #if DEBUG
137 	if (time < (fLastDataAvailableTime - duration_for_frames(
138 			fMixBufferFrameRate, fMixBufferFrameCount))
139 		|| (time + duration_for_frames(fMixBufferFrameRate,
140 			fDebugMixBufferFrames)) >= fLastDataAvailableTime) {
141 		// Print this error for the first channel only.
142 		if (mixerChannel == 0) {
143 			ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld "
144 				"to %Ld, reading from %Ld to %Ld\n",
145 				fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate,
146 					fMixBufferFrameCount), fLastDataAvailableTime, time,
147 				time + duration_for_frames(fMixBufferFrameRate,
148 				fDebugMixBufferFrames));
149 		}
150 	}
151 #endif
152 
153 	if (time > fLastDataAvailableTime)
154 		return false;
155 
156 	int32 offset = framepos % fMixBufferFrameCount;
157 	if (mixerChannel == 0) {
158 		PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset,
159 			offset + fDebugMixBufferFrames - 1);
160 	}
161 	*buffer = reinterpret_cast<float*>(reinterpret_cast<char*>(
162 		fMixerChannelInfo[mixerChannel].buffer_base)
163 		+ (offset * sizeof(float) * fInputChannelCount));
164 	*sampleOffset = sizeof(float) * fInputChannelCount;
165 	*type = fMixerChannelInfo[mixerChannel].destination_type;
166 	*gain = fMixerChannelInfo[mixerChannel].destination_gain;
167 	return true;
168 }
169 
170 #endif	// _MIXER_INPUT_H
171