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 33#define MIXER_PROCESS_EVENT BTimedEventQueue::B_USER_EVENT+10 34#define MIXER_SCHEDULE_EVENT BTimedEventQueue::B_USER_EVENT+11 35 36 37class MixerCore { 38public: 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 87private: 88 void _UpdateResamplers( 89 const media_multi_audio_format& format); 90 void _ApplyOutputFormat(); 91 static int32 _MixThreadEntry(void* arg); 92 void _MixThread(); 93 94private: 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 134inline bool 135MixerCore::Lock() 136{ 137 return fLocker->Lock(); 138} 139 140 141inline bool 142MixerCore::LockWithTimeout(bigtime_t timeout) 143{ 144 return fLocker->LockWithTimeout(timeout) == B_OK; 145} 146 147 148inline bool 149MixerCore::IsLocked() const 150{ 151 return fLocker->IsLocked(); 152} 153 154 155inline void 156MixerCore::Unlock() 157{ 158 fLocker->Unlock(); 159} 160 161 162inline void 163MixerCore::Process() 164{ 165 release_sem(fMixThreadWaitSem); 166} 167 168 169inline bigtime_t 170MixerCore::PickEvent() 171{ 172 return fTimeSource->RealTimeFor(fEventTime, 0) 173 - fEventLatency - fDownstreamLatency; 174} 175 176 177#endif // _MIXER_CORE_H 178