1 #ifndef _MIXER_CORE_H 2 #define _MIXER_CORE_H 3 4 #include <Locker.h> 5 #include "MixerSettings.h" 6 7 class AudioMixer; 8 class MixerInput; 9 class MixerOutput; 10 class Resampler; 11 12 // The number of "enum media_multi_channels" types from MediaDefs.h 13 // XXX should be 18, but limited to 12 here 14 #define MAX_CHANNEL_TYPES 12 15 // XXX using a dedicated mono channel, this should be channel type 31 16 // but for now we redefine type 12 17 #define B_CHANNEL_MONO B_CHANNEL_TOP_CENTER 18 19 class MixerCore 20 { 21 public: 22 MixerCore(AudioMixer *node); 23 ~MixerCore(); 24 25 MixerSettings *Settings(); 26 27 // To avoid calling Settings()->AttenuateOutput() for every outgoing 28 // buffer, this setting is cached in fOutputGain and must be set by 29 // the audio mixer node using SetOutputAttenuation() 30 void SetOutputAttenuation(float gain); 31 32 MixerInput * AddInput(const media_input &input); 33 MixerOutput * AddOutput(const media_output &output); 34 35 bool RemoveInput(int32 inputID); 36 bool RemoveOutput(); 37 38 int32 CreateInputID(); 39 40 MixerInput *Input(int index); // index = 0 to count-1, NOT inputID 41 MixerOutput *Output(); 42 43 void Lock(); 44 bool LockWithTimeout(bigtime_t timeout); 45 bool LockFromMixThread(); 46 void Unlock(); 47 48 void BufferReceived(BBuffer *buffer, bigtime_t lateness); 49 50 void InputFormatChanged(int32 inputID, const media_multi_audio_format &format); 51 void OutputFormatChanged(const media_multi_audio_format &format); 52 53 void SetOutputBufferGroup(BBufferGroup *group); 54 void SetTimingInfo(BTimeSource *ts, bigtime_t downstream_latency); 55 void EnableOutput(bool enabled); 56 bool Start(); 57 bool Stop(); 58 59 void StartMixThread(); 60 void StopMixThread(); 61 62 uint32 OutputChannelCount(); 63 64 private: 65 void ApplyOutputFormat(); 66 static int32 _mix_thread_(void *arg); 67 void MixThread(); 68 69 private: 70 BLocker *fLocker; 71 72 BList *fInputs; 73 MixerOutput *fOutput; 74 int32 fNextInputID; 75 bool fRunning; // true = the mix thread is running 76 bool fStarted; // true = mix thread should be started of it is not running 77 bool fOutputEnabled; // true = mix thread should be started of it is not running 78 79 Resampler **fResampler; // array 80 81 float *fMixBuffer; 82 int32 fMixBufferFrameRate; 83 int32 fMixBufferFrameCount; 84 int32 fMixBufferChannelCount; 85 int32 *fMixBufferChannelTypes; //array 86 bool fDoubleRateMixing; 87 bigtime_t fDownstreamLatency; 88 89 friend class MixerInput; // XXX debug only 90 91 MixerSettings *fSettings; 92 AudioMixer *fNode; 93 BBufferGroup *fBufferGroup; 94 BTimeSource *fTimeSource; 95 thread_id fMixThread; 96 sem_id fMixThreadWaitSem; 97 98 float fOutputGain; 99 }; 100 101 102 inline void MixerCore::Lock() 103 { 104 fLocker->Lock(); 105 } 106 107 inline bool MixerCore::LockWithTimeout(bigtime_t timeout) 108 { 109 return B_OK == fLocker->LockWithTimeout(timeout); 110 } 111 112 inline void MixerCore::Unlock() 113 { 114 fLocker->Unlock(); 115 } 116 117 inline bool MixerCore::LockFromMixThread() 118 { 119 for (;;) { 120 if (LockWithTimeout(10000)) 121 return true; 122 // XXX accessing fMixThreadWaitSem is still a race condition :( 123 if (B_WOULD_BLOCK != acquire_sem_etc(fMixThreadWaitSem, 1, B_RELATIVE_TIMEOUT, 0)) 124 return false; 125 } 126 } 127 128 #endif 129