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_INPUT_H 9 #define _MIXER_INPUT_H 10 11 12 #include <MediaNode.h> 13 #include <RealtimeAlloc.h> 14 15 #include "MixerCore.h" 16 #include "MixerDebug.h" 17 #include "MixerUtils.h" 18 19 20 class ByteSwap; 21 class Resampler; 22 23 24 class MixerInput { 25 public: 26 MixerInput(MixerCore* core, 27 const media_input& input, 28 float mixFrameRate, int32 mixFrameCount); 29 ~MixerInput(); 30 31 int32 ID(); 32 media_input& MediaInput(); 33 34 void BufferReceived(BBuffer* buffer); 35 36 void UpdateResamplingAlgorithm(); 37 38 // The physical input channels 39 int GetInputChannelCount(); 40 int GetInputChannelType(int channel); 41 void SetInputChannelGain(int channel, float gain); 42 float GetInputChannelGain(int channel); 43 44 // The destinations for each channel 45 void AddInputChannelDestination(int channel, 46 int destinationType); 47 void RemoveInputChannelDestination(int channel, 48 int destinationType); 49 bool HasInputChannelDestination(int channel, 50 int destinationType); 51 int GetInputChannelForDestination( 52 int destinationType); 53 // returns -1 if not found 54 55 // The virtual mixer channels that are generated from destinations 56 int GetMixerChannelCount(); 57 void SetMixerChannelGain(int mixerChannel, 58 float gain); 59 float GetMixerChannelGain(int mixerChannel); 60 int GetMixerChannelType(int mixerChannel); 61 62 void SetEnabled(bool enabled); 63 bool IsEnabled(); 64 65 // only for use by MixerCore 66 bool GetMixerChannelInfo(int mixerChannel, 67 int64 framepos, bigtime_t time, 68 const float** _buffer, 69 uint32* _sampleOffset, int* _type, 70 float* _gain); 71 72 protected: 73 friend class MixerCore; 74 75 void SetMixBufferFormat(int32 framerate, 76 int32 frames); 77 78 private: 79 void _UpdateInputChannelDestinationMask(); 80 void _UpdateInputChannelDestinations(); 81 82 struct input_chan_info { 83 float* buffer_base; 84 uint32 destination_mask; // multiple or no bits sets 85 float gain; 86 }; 87 88 struct mixer_chan_info { 89 float* buffer_base; 90 int destination_type; 91 float destination_gain; 92 }; 93 94 private: 95 MixerCore* fCore; 96 media_input fInput; 97 ByteSwap* fInputByteSwap; 98 float fChannelTypeGain[MAX_CHANNEL_TYPES]; 99 bool fEnabled; 100 input_chan_info* fInputChannelInfo; // array 101 int fInputChannelCount; 102 uint32 fInputChannelMask; 103 mixer_chan_info* fMixerChannelInfo; // array 104 int fMixerChannelCount; 105 float* fMixBuffer; 106 int32 fMixBufferFrameRate; 107 int fMixBufferFrameCount; 108 int32 fLastDataFrameWritten; 109 bigtime_t fLastDataAvailableTime; 110 double fFractionalFrames; 111 Resampler** fResampler; // array 112 rtm_pool* fRtmPool; 113 bool fUserOverridesChannelDestinations; 114 int32 fDebugMixBufferFrames; 115 }; 116 117 118 inline int 119 MixerInput::GetMixerChannelCount() 120 { 121 return fMixerChannelCount; 122 } 123 124 125 inline bool 126 MixerInput::GetMixerChannelInfo(int mixerChannel, int64 framepos, 127 bigtime_t time, const float** buffer, uint32* sampleOffset, int* type, 128 float* gain) 129 { 130 // this function should not be called if we don't have a mix buffer! 131 ASSERT(fMixBuffer != NULL); 132 ASSERT(mixerChannel >= 0 && mixerChannel < fMixerChannelCount); 133 if (!fEnabled) 134 return false; 135 136 #if DEBUG 137 if (time < (fLastDataAvailableTime - duration_for_frames( 138 fMixBufferFrameRate, fMixBufferFrameCount)) 139 || (time + duration_for_frames(fMixBufferFrameRate, 140 fDebugMixBufferFrames)) >= fLastDataAvailableTime) { 141 // Print this error for the first channel only. 142 if (mixerChannel == 0) { 143 ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld " 144 "to %Ld, reading from %Ld to %Ld\n", 145 fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, 146 fMixBufferFrameCount), fLastDataAvailableTime, time, 147 time + duration_for_frames(fMixBufferFrameRate, 148 fDebugMixBufferFrames)); 149 } 150 } 151 #endif 152 153 if (time > fLastDataAvailableTime) 154 return false; 155 156 int32 offset = framepos % fMixBufferFrameCount; 157 if (mixerChannel == 0) { 158 PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, 159 offset + fDebugMixBufferFrames - 1); 160 } 161 *buffer = reinterpret_cast<float*>(reinterpret_cast<char*>( 162 fMixerChannelInfo[mixerChannel].buffer_base) 163 + (offset * sizeof(float) * fInputChannelCount)); 164 *sampleOffset = sizeof(float) * fInputChannelCount; 165 *type = fMixerChannelInfo[mixerChannel].destination_type; 166 *gain = fMixerChannelInfo[mixerChannel].destination_gain; 167 return true; 168 } 169 170 #endif // _MIXER_INPUT_H 171