xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerCore.h (revision 21258e2674226d6aa732321b6f8494841895af5f)
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_CORE_H
9 #define _MIXER_CORE_H
10 
11 
12 #include "MixerSettings.h"
13 
14 #include <Buffer.h>
15 #include <Locker.h>
16 #include <TimeSource.h>
17 
18 
19 class AudioMixer;
20 class BBufferGroup;
21 class MixerInput;
22 class MixerOutput;
23 class Resampler;
24 
25 
26 // The number of "enum media_multi_channels" types from MediaDefs.h
27 // XXX should be 18, but limited to 12 here
28 #define MAX_CHANNEL_TYPES	12
29 // XXX using a dedicated mono channel, this should be channel type 31
30 //     but for now we redefine type 12
31 #define B_CHANNEL_MONO		B_CHANNEL_TOP_CENTER
32 
33 #define MIXER_PROCESS_EVENT BTimedEventQueue::B_USER_EVENT+10
34 #define MIXER_SCHEDULE_EVENT BTimedEventQueue::B_USER_EVENT+11
35 
36 
37 class MixerCore {
38 public:
39 								MixerCore(AudioMixer* node);
40 	virtual						~MixerCore();
41 
42 			MixerSettings*		Settings();
43 			void				UpdateResamplingAlgorithm();
44 
45 	// To avoid calling Settings()->AttenuateOutput() for every outgoing
46 	// buffer, this setting is cached in fOutputGain and must be set by
47 	// the audio mixer node using SetOutputAttenuation()
48 			void				SetOutputAttenuation(float gain);
49 			MixerInput*			AddInput(const media_input& input);
50 			MixerOutput*		AddOutput(const media_output& output);
51 
52 			bool				RemoveInput(int32 inputID);
53 			bool				RemoveOutput();
54 			int32				CreateInputID();
55 
56 	// index = 0 to count-1, NOT inputID
57 			MixerInput*			Input(int index);
58 			MixerOutput*		Output();
59 
60 			bool				Lock();
61 			bool				LockWithTimeout(bigtime_t timeout);
62 			bool				IsLocked() const;
63 			void				Unlock();
64 
65 			void				Process();
66 			bigtime_t			PickEvent();
67 
68 			void				BufferReceived(BBuffer* buffer,
69 									bigtime_t lateness);
70 
71 			void				InputFormatChanged(int32 inputID,
72 									const media_multi_audio_format& format);
73 			void				OutputFormatChanged(
74 									const media_multi_audio_format& format);
75 
76 			void				SetOutputBufferGroup(BBufferGroup* group);
77 			void				SetTimingInfo(BTimeSource* timeSource,
78 									bigtime_t downstreamLatency);
79 			void				EnableOutput(bool enabled);
80 			bool				Start();
81 			bool				Stop();
82 
83 			void				StartMixThread();
84 			void				StopMixThread();
85 			uint32				OutputChannelCount();
86 
87 private:
88 			void				_UpdateResamplers(
89 									const media_multi_audio_format& format);
90 			void				_ApplyOutputFormat();
91 	static	int32				_MixThreadEntry(void* arg);
92 			void				_MixThread();
93 
94 private:
95 			BLocker*			fLocker;
96 			BList*				fInputs;
97 			MixerOutput*		fOutput;
98 			int32				fNextInputID;
99 			bool				fRunning;
100 									// true = the mix thread is running
101 
102 			bool				fStarted;
103 									// true = mix thread should be
104 									// started of it is not running
105 
106 			bool				fOutputEnabled;
107 									// true = mix thread should be
108 									// started of it is not running
109 
110 			Resampler**			fResampler; // array
111 			float*				fMixBuffer;
112 			int32				fMixBufferFrameRate;
113 			int32				fMixBufferFrameCount;
114 			int32				fMixBufferChannelCount;
115 			int32*				fMixBufferChannelTypes; //array
116 			bool				fDoubleRateMixing;
117 			bigtime_t			fDownstreamLatency;
118 			MixerSettings*		fSettings;
119 			AudioMixer*			fNode;
120 			BBufferGroup*		fBufferGroup;
121 			BTimeSource*		fTimeSource;
122 			thread_id			fMixThread;
123 			sem_id				fMixThreadWaitSem;
124 			bool				fHasEvent;
125 			bigtime_t			fEventTime;
126 			bigtime_t			fEventLatency;
127 			float				fOutputGain;
128 
129 	friend class MixerInput;
130 		// NOTE: debug only
131 };
132 
133 
134 inline bool
135 MixerCore::Lock()
136 {
137 	return fLocker->Lock();
138 }
139 
140 
141 inline bool
142 MixerCore::LockWithTimeout(bigtime_t timeout)
143 {
144 	return fLocker->LockWithTimeout(timeout) == B_OK;
145 }
146 
147 
148 inline bool
149 MixerCore::IsLocked() const
150 {
151 	return fLocker->IsLocked();
152 }
153 
154 
155 inline void
156 MixerCore::Unlock()
157 {
158 	fLocker->Unlock();
159 }
160 
161 
162 inline void
163 MixerCore::Process()
164 {
165 	release_sem(fMixThreadWaitSem);
166 }
167 
168 
169 inline bigtime_t
170 MixerCore::PickEvent()
171 {
172 	return fTimeSource->RealTimeFor(fEventTime, 0)
173 		- fEventLatency - fDownstreamLatency;
174 }
175 
176 
177 #endif // _MIXER_CORE_H
178