xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerOutput.h (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 #ifndef _MIXER_OUTPUT_H
2 #define _MIXER_OUTPUT_H
3 
4 #include <Buffer.h>
5 #include "MixerDebug.h"
6 #include "ByteSwap.h"
7 #include "MixerCore.h"
8 
9 /* The data storage for channel sources is optimized
10  * for fast data retrieval by the MixerCore, which
11  * will call GetOutputChannelSourceInfoAt() and
12  * iterate through the first source_count array entries
13  * for source_gain[] and source_type[] arrays, they are
14  * index by 0 to GetOutputChannelSourceCount() - 1.
15  * To allow gain change for not active sources,
16  * we use the source_gain_cache[] array that is indexed
17  * by source_type.
18  */
19 
20 class MixerOutput
21 {
22 public:
23 	MixerOutput(MixerCore *core, const media_output &output);
24 	~MixerOutput();
25 
26 	media_output & MediaOutput();
27 
28 	void ChangeFormat(const media_multi_audio_format &format);
29 
30 	// The physical output channels
31 	int		GetOutputChannelCount();
32 	int		GetOutputChannelType(int channel);
33 	void	SetOutputChannelGain(int channel, float gain);
34 	float	GetOutputChannelGain(int channel);
35 
36 	// The sources for each channel
37 	void	AddOutputChannelSource(int channel, int source_type);
38 	void	RemoveOutputChannelSource(int channel, int source_type);
39 	void	SetOutputChannelSourceGain(int channel, int source_type, float source_gain);
40 	float	GetOutputChannelSourceGain(int channel, int source_type);
41 	bool	HasOutputChannelSource(int channel, int source_type);
42 
43 	// The output can be muted
44 	void	SetMuted(bool yesno);
45 	bool	IsMuted();
46 
47 	// Only for use by MixerCore:
48 
49 	// For iteration of a channel's sources
50 	int		GetOutputChannelSourceCount(int channel);
51 	void	GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain);
52 
53 	// To swap byteorder in a buffer is that is needed
54 	void	AdjustByteOrder(BBuffer *buffer);
55 
56 private:
57 	void UpdateByteOrderSwap();
58 	void UpdateOutputChannels();
59 	void AssignDefaultSources();
60 
61 private:
62 
63 	/* An entry in the source array is not the same as the
64 	 * channel type, but the count should be the same
65 	 */
66 	 enum {
67 		MAX_SOURCE_ENTRIES = MAX_CHANNEL_TYPES
68 	};
69 
70 	struct output_chan_info {
71 		int		channel_type;
72 		float	channel_gain;
73 		int		source_count;
74 		float	source_gain[MAX_SOURCE_ENTRIES];
75 		int		source_type[MAX_SOURCE_ENTRIES];
76 		float	source_gain_cache[MAX_CHANNEL_TYPES];
77 	};
78 
79 	MixerCore 			*fCore;
80 	media_output 		fOutput;
81 
82 	int					fOutputChannelCount;
83 	output_chan_info 	*fOutputChannelInfo; //array
84 	ByteSwap			*fOutputByteSwap;
85 
86 	bool				fMuted;
87 };
88 
89 inline int MixerOutput::GetOutputChannelCount()
90 {
91 	return fOutputChannelCount;
92 }
93 
94 inline float MixerOutput::GetOutputChannelGain(int channel)
95 {
96 	if (channel < 0 || channel >= fOutputChannelCount)
97 		return 1.0;
98 	return fOutputChannelInfo[channel].channel_gain;
99 }
100 
101 inline int MixerOutput::GetOutputChannelSourceCount(int channel)
102 {
103 	ASSERT(channel >= 0 && channel < fOutputChannelCount);
104 	return fOutputChannelInfo[channel].source_count;
105 }
106 
107 inline void MixerOutput::GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain)
108 {
109 	ASSERT(channel >= 0 && channel < fOutputChannelCount);
110 	ASSERT(source_index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
111 	*source_type = fOutputChannelInfo[channel].source_type[source_index];
112 	*source_gain = fOutputChannelInfo[channel].source_gain[source_index];
113 }
114 
115 inline void MixerOutput::AdjustByteOrder(BBuffer *buffer)
116 {
117 	if (fOutputByteSwap)
118 		fOutputByteSwap->Swap(buffer->Data(), buffer->SizeUsed());
119 }
120 
121 inline bool MixerOutput::IsMuted()
122 {
123 	return fMuted;
124 }
125 
126 #endif
127