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