1 /* 2 * Copyright 2003-2009 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 void BufferReceived(BBuffer* buffer); 33 media_input& MediaInput(); 34 35 // The physical input channels 36 int GetInputChannelCount(); 37 int GetInputChannelType(int channel); 38 void SetInputChannelGain(int channel, float gain); 39 float GetInputChannelGain(int channel); 40 41 // The destinations for each channel 42 void AddInputChannelDestination(int channel, 43 int destinationType); 44 void RemoveInputChannelDestination(int channel, 45 int destinationType); 46 bool HasInputChannelDestination(int channel, 47 int destinationType); 48 int GetInputChannelForDestination( 49 int destinationType); 50 // returns -1 if not found 51 52 // The virtual mixer channels that are generated from destinations 53 int GetMixerChannelCount(); 54 void SetMixerChannelGain(int mixerChannel, 55 float gain); 56 float GetMixerChannelGain(int mixerChannel); 57 int GetMixerChannelType(int mixerChannel); 58 59 void SetEnabled(bool enabled); 60 bool IsEnabled(); 61 62 // only for use by MixerCore 63 bool GetMixerChannelInfo(int mixerChannel, 64 int64 framepos, bigtime_t time, 65 const float** _buffer, 66 uint32* _sampleOffset, int* _type, 67 float* _gain); 68 69 protected: 70 friend class MixerCore; 71 72 void SetMixBufferFormat(int32 framerate, 73 int32 frames); 74 75 private: 76 void UpdateInputChannelDestinationMask(); 77 void UpdateInputChannelDestinations(); 78 79 struct input_chan_info { 80 float* buffer_base; 81 uint32 destination_mask; // multiple or no bits sets 82 float gain; 83 }; 84 85 struct mixer_chan_info { 86 float* buffer_base; 87 int destination_type; 88 float destination_gain; 89 }; 90 91 private: 92 MixerCore* fCore; 93 media_input fInput; 94 ByteSwap* fInputByteSwap; 95 float fChannelTypeGain[MAX_CHANNEL_TYPES]; 96 bool fEnabled; 97 input_chan_info* fInputChannelInfo; // array 98 int fInputChannelCount; 99 uint32 fInputChannelMask; 100 mixer_chan_info* fMixerChannelInfo; // array 101 int fMixerChannelCount; 102 float* fMixBuffer; 103 int32 fMixBufferFrameRate; 104 int fMixBufferFrameCount; 105 int32 fLastDataFrameWritten; 106 bigtime_t fLastDataAvailableTime; 107 double fFractionalFrames; 108 Resampler** fResampler; // array 109 rtm_pool* fRtmPool; 110 bool fUserOverridesChannelDestinations; 111 int32 fDebugMixBufferFrames; 112 }; 113 114 115 inline int 116 MixerInput::GetMixerChannelCount() 117 { 118 return fMixerChannelCount; 119 } 120 121 122 inline bool 123 MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos, 124 bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, 125 float *gain) 126 { 127 // this function should not be called if we don't have a mix buffer! 128 ASSERT(fMixBuffer); 129 ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount); 130 if (!fEnabled) 131 return false; 132 133 #if 1 134 if (time < (fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount)) 135 || (time + duration_for_frames(fMixBufferFrameRate, fDebugMixBufferFrames)) >= fLastDataAvailableTime) 136 ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld to %Ld, reading from %Ld to %Ld\n", 137 fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount), fLastDataAvailableTime, time, time + duration_for_frames(fMixBufferFrameRate, fDebugMixBufferFrames)); 138 #endif 139 140 if (time > fLastDataAvailableTime) 141 return false; 142 143 int32 offset = framepos % fMixBufferFrameCount; 144 if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + fDebugMixBufferFrames - 1); 145 *buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount)); 146 *sample_offset = sizeof(float) * fInputChannelCount; 147 *type = fMixerChannelInfo[mixer_channel].destination_type; 148 *gain = fMixerChannelInfo[mixer_channel].destination_gain; 149 return true; 150 } 151 152 #endif // _MIXER_INPUT_H 153