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
19class AudioMixer;
20class BBufferGroup;
21class MixerInput;
22class MixerOutput;
23class 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
33class MixerCore {
34public:
35								MixerCore(AudioMixer* node);
36	virtual						~MixerCore();
37
38			MixerSettings*		Settings();
39			void				UpdateResamplingAlgorithm();
40
41	// To avoid calling Settings()->AttenuateOutput() for every outgoing
42	// buffer, this setting is cached in fOutputGain and must be set by
43	// the audio mixer node using SetOutputAttenuation()
44			void				SetOutputAttenuation(float gain);
45			MixerInput*			AddInput(const media_input& input);
46			MixerOutput*		AddOutput(const media_output& output);
47
48			bool				RemoveInput(int32 inputID);
49			bool				RemoveOutput();
50			int32				CreateInputID();
51
52	// index = 0 to count-1, NOT inputID
53			MixerInput*			Input(int index);
54			MixerOutput*		Output();
55
56			void				Lock();
57			bool				LockWithTimeout(bigtime_t timeout);
58			bool				LockFromMixThread();
59			void				Unlock();
60
61			void				BufferReceived(BBuffer* buffer,
62									bigtime_t lateness);
63
64			void				InputFormatChanged(int32 inputID,
65									const media_multi_audio_format& format);
66			void				OutputFormatChanged(
67									const media_multi_audio_format& format);
68
69			void				SetOutputBufferGroup(BBufferGroup* group);
70			void				SetTimingInfo(BTimeSource* timeSource,
71									bigtime_t downstreamLatency);
72			void				EnableOutput(bool enabled);
73			bool				Start();
74			bool				Stop();
75
76			void				StartMixThread();
77			void				StopMixThread();
78			uint32				OutputChannelCount();
79
80private:
81			void				_UpdateResamplers(
82									const media_multi_audio_format& format);
83			void				_ApplyOutputFormat();
84	static	int32				_MixThreadEntry(void* arg);
85			void				_MixThread();
86
87private:
88			BLocker*			fLocker;
89			BList*				fInputs;
90			MixerOutput*		fOutput;
91			int32				fNextInputID;
92			bool				fRunning;
93									// true = the mix thread is running
94
95			bool				fStarted;
96									// true = mix thread should be
97									// started of it is not running
98
99			bool				fOutputEnabled;
100									// true = mix thread should be
101									// started of it is not running
102
103			Resampler**			fResampler; // array
104			float*				fMixBuffer;
105			int32				fMixBufferFrameRate;
106			int32				fMixBufferFrameCount;
107			int32				fMixBufferChannelCount;
108			int32*				fMixBufferChannelTypes; //array
109			bool				fDoubleRateMixing;
110			bigtime_t			fDownstreamLatency;
111			MixerSettings*		fSettings;
112			AudioMixer*			fNode;
113			BBufferGroup*		fBufferGroup;
114			BTimeSource*		fTimeSource;
115			thread_id			fMixThread;
116			sem_id				fMixThreadWaitSem;
117			float				fOutputGain;
118
119	friend class MixerInput;
120		// NOTE: debug only
121};
122
123
124inline void
125MixerCore::Lock()
126{
127	fLocker->Lock();
128}
129
130
131inline bool
132MixerCore::LockWithTimeout(bigtime_t timeout)
133{
134	return fLocker->LockWithTimeout(timeout) == B_OK;
135}
136
137
138inline void
139MixerCore::Unlock()
140{
141	fLocker->Unlock();
142}
143
144
145inline bool
146MixerCore::LockFromMixThread()
147{
148	for (;;) {
149		if (LockWithTimeout(10000))
150			return true;
151		// XXX accessing fMixThreadWaitSem is still a race condition :(
152		if (acquire_sem_etc(fMixThreadWaitSem, 1, B_RELATIVE_TIMEOUT, 0)
153				!= B_WOULD_BLOCK) {
154			return false;
155		}
156	}
157}
158
159
160#endif // _MIXER_CORE_H
161