xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerInput.h (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
1 /*
2  * Copyright 2007 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _MIXER_INPUT_H
6 #define _MIXER_INPUT_H
7 
8 #include "MixerCore.h"
9 #include "MixerDebug.h"
10 #include "MixerUtils.h"
11 
12 #include <MediaNode.h>
13 #include <RealtimeAlloc.h>
14 
15 class ByteSwap;
16 class Resampler;
17 
18 class MixerInput
19 {
20 	public:
21 										MixerInput(MixerCore *core,
22 													const media_input &input,
23 													float mixFrameRate,
24 													int32 mixFrameCount);
25 										~MixerInput();
26 
27 		int32							ID();
28 		void							BufferReceived(BBuffer *buffer);
29 		media_input&					MediaInput();
30 
31 		// The physical input channels
32 		int								GetInputChannelCount();
33 		int								GetInputChannelType(int channel);
34 		void							SetInputChannelGain(int channel,
35 															float gain);
36 		float							GetInputChannelGain(int channel);
37 
38 		// The destinations for each channel
39 		void								AddInputChannelDestination(
40 														int channel,
41 														int destination_type);
42 		void								RemoveInputChannelDestination(
43 														int channel,
44 														int destination_type);
45 		bool								HasInputChannelDestination(
46 														int channel,
47 														int destination_type);
48 		int 								GetInputChannelForDestination(
49 														int destination_type);
50 														// returns -1 if not found
51 
52 		// The virtual mixer channels that are generated from destinations
53 		int									GetMixerChannelCount();
54 		void								SetMixerChannelGain(int mixer_channel,
55 														float gain);
56 		float								GetMixerChannelGain(int mixer_channel);
57 		int									GetMixerChannelType(int mixer_channel);
58 
59 		void								SetEnabled(bool yesno);
60 		bool								IsEnabled();
61 
62 		// only for use by MixerCore
63 		bool								GetMixerChannelInfo(int mixer_channel,
64 																int64 framepos,
65 																bigtime_t time,
66 																const float **buffer,
67 																uint32 *sample_offset,
68 																int *type,
69 																float *gain);
70 
71 	protected:
72 		friend class MixerCore;
73 		void								SetMixBufferFormat(int32 framerate,
74 																int32 frames);
75 
76 	private:
77 		void								UpdateInputChannelDestinationMask();
78 		void								UpdateInputChannelDestinations();
79 
80 		struct input_chan_info {
81 			float			*buffer_base;
82 			uint32			destination_mask;	// multiple or no bits sets
83 			float			gain;
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								debugMixBufferFrames;
112 };
113 
114 inline int
115 MixerInput::GetMixerChannelCount()
116 {
117 	return fMixerChannelCount;
118 }
119 
120 inline bool
121 MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos,
122 								bigtime_t time, const float **buffer,
123 								uint32 *sample_offset, int *type, float *gain)
124 {
125 	// this function should not be called if we don't have a mix buffer!
126 	ASSERT(fMixBuffer);
127 	ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount);
128 	if (!fEnabled)
129 		return false;
130 
131 #if 1
132 	if (time < (fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount))
133 		|| (time + duration_for_frames(fMixBufferFrameRate, debugMixBufferFrames)) >= fLastDataAvailableTime)
134 		ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld to %Ld, reading from %Ld to %Ld\n",
135 				fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount), fLastDataAvailableTime, time, time + duration_for_frames(fMixBufferFrameRate, debugMixBufferFrames));
136 #endif
137 
138 	if (time > fLastDataAvailableTime)
139 		return false;
140 
141 	int32 offset = framepos % fMixBufferFrameCount;
142 	if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
143 	*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
144 	*sample_offset = sizeof(float) * fInputChannelCount;
145 	*type = fMixerChannelInfo[mixer_channel].destination_type;
146 	*gain = fMixerChannelInfo[mixer_channel].destination_gain;
147 	return true;
148 }
149 #endif
150