xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerInput.h (revision b289aaf66bbf6e173aa90fa194fc256965f1b34d)
1 /*
2  * Copyright 2003-2009 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 			void				BufferReceived(BBuffer* buffer);
33 			media_input&		MediaInput();
34 
35 	// The physical input channels
36 			int					GetInputChannelCount();
37 			int					GetInputChannelType(int channel);
38 			void				SetInputChannelGain(int channel, float gain);
39 			float				GetInputChannelGain(int channel);
40 
41 	// The destinations for each channel
42 			void				AddInputChannelDestination(int channel,
43 									int destinationType);
44 			void				RemoveInputChannelDestination(int channel,
45 									int destinationType);
46 			bool				HasInputChannelDestination(int channel,
47 									int destinationType);
48 			int 				GetInputChannelForDestination(
49 									int destinationType);
50 				// returns -1 if not found
51 
52 	// The virtual mixer channels that are generated from destinations
53 			int					GetMixerChannelCount();
54 			void				SetMixerChannelGain(int mixerChannel,
55 									float gain);
56 			float				GetMixerChannelGain(int mixerChannel);
57 			int					GetMixerChannelType(int mixerChannel);
58 
59 			void				SetEnabled(bool enabled);
60 			bool				IsEnabled();
61 
62 	// only for use by MixerCore
63 			bool				GetMixerChannelInfo(int mixerChannel,
64 									int64 framepos, bigtime_t time,
65 									const float** _buffer,
66 									uint32* _sampleOffset, int* _type,
67 									float* _gain);
68 
69 protected:
70 	friend class MixerCore;
71 
72 			void				SetMixBufferFormat(int32 framerate,
73 									int32 frames);
74 
75 private:
76 			void				UpdateInputChannelDestinationMask();
77 			void				UpdateInputChannelDestinations();
78 
79 	struct input_chan_info {
80 		float*					buffer_base;
81 		uint32					destination_mask;	// multiple or no bits sets
82 		float					gain;
83 	};
84 
85 	struct mixer_chan_info {
86 		float*					buffer_base;
87 		int						destination_type;
88 		float					destination_gain;
89 	};
90 
91 private:
92 			MixerCore*			fCore;
93 			media_input			fInput;
94 			ByteSwap*			fInputByteSwap;
95 			float				fChannelTypeGain[MAX_CHANNEL_TYPES];
96 			bool				fEnabled;
97 			input_chan_info*	fInputChannelInfo; // array
98 			int					fInputChannelCount;
99 			uint32				fInputChannelMask;
100 			mixer_chan_info*	fMixerChannelInfo; // array
101 			int					fMixerChannelCount;
102 			float*				fMixBuffer;
103 			int32				fMixBufferFrameRate;
104 			int					fMixBufferFrameCount;
105 			int32				fLastDataFrameWritten;
106 			bigtime_t			fLastDataAvailableTime;
107 			double				fFractionalFrames;
108 			Resampler**			fResampler; // array
109 			rtm_pool*			fRtmPool;
110 			bool				fUserOverridesChannelDestinations;
111 			int32				fDebugMixBufferFrames;
112 };
113 
114 
115 inline int
116 MixerInput::GetMixerChannelCount()
117 {
118 	return fMixerChannelCount;
119 }
120 
121 
122 inline bool
123 MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos,
124 	bigtime_t time, const float **buffer, uint32 *sample_offset, int *type,
125 	float *gain)
126 {
127 	// this function should not be called if we don't have a mix buffer!
128 	ASSERT(fMixBuffer);
129 	ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount);
130 	if (!fEnabled)
131 		return false;
132 
133 #if 1
134 	if (time < (fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount))
135 		|| (time + duration_for_frames(fMixBufferFrameRate, fDebugMixBufferFrames)) >= fLastDataAvailableTime)
136 		ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld to %Ld, reading from %Ld to %Ld\n",
137 				fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount), fLastDataAvailableTime, time, time + duration_for_frames(fMixBufferFrameRate, fDebugMixBufferFrames));
138 #endif
139 
140 	if (time > fLastDataAvailableTime)
141 		return false;
142 
143 	int32 offset = framepos % fMixBufferFrameCount;
144 	if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + fDebugMixBufferFrames - 1);
145 	*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
146 	*sample_offset = sizeof(float) * fInputChannelCount;
147 	*type = fMixerChannelInfo[mixer_channel].destination_type;
148 	*gain = fMixerChannelInfo[mixer_channel].destination_gain;
149 	return true;
150 }
151 
152 #endif	// _MIXER_INPUT_H
153