1 /* 2 * Copyright 2007 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _MIXER_INPUT_H 6 #define _MIXER_INPUT_H 7 8 #include "MixerCore.h" 9 #include "MixerDebug.h" 10 #include "MixerUtils.h" 11 12 #include <MediaNode.h> 13 #include <RealtimeAlloc.h> 14 15 class ByteSwap; 16 class Resampler; 17 18 class MixerInput 19 { 20 public: 21 MixerInput(MixerCore *core, 22 const media_input &input, 23 float mixFrameRate, 24 int32 mixFrameCount); 25 ~MixerInput(); 26 27 int32 ID(); 28 void BufferReceived(BBuffer *buffer); 29 media_input& MediaInput(); 30 31 // The physical input channels 32 int GetInputChannelCount(); 33 int GetInputChannelType(int channel); 34 void SetInputChannelGain(int channel, 35 float gain); 36 float GetInputChannelGain(int channel); 37 38 // The destinations for each channel 39 void AddInputChannelDestination( 40 int channel, 41 int destination_type); 42 void RemoveInputChannelDestination( 43 int channel, 44 int destination_type); 45 bool HasInputChannelDestination( 46 int channel, 47 int destination_type); 48 int GetInputChannelForDestination( 49 int destination_type); 50 // returns -1 if not found 51 52 // The virtual mixer channels that are generated from destinations 53 int GetMixerChannelCount(); 54 void SetMixerChannelGain(int mixer_channel, 55 float gain); 56 float GetMixerChannelGain(int mixer_channel); 57 int GetMixerChannelType(int mixer_channel); 58 59 void SetEnabled(bool yesno); 60 bool IsEnabled(); 61 62 // only for use by MixerCore 63 bool GetMixerChannelInfo(int mixer_channel, 64 int64 framepos, 65 bigtime_t time, 66 const float **buffer, 67 uint32 *sample_offset, 68 int *type, 69 float *gain); 70 71 protected: 72 friend class MixerCore; 73 void SetMixBufferFormat(int32 framerate, 74 int32 frames); 75 76 private: 77 void UpdateInputChannelDestinationMask(); 78 void UpdateInputChannelDestinations(); 79 80 struct input_chan_info { 81 float *buffer_base; 82 uint32 destination_mask; // multiple or no bits sets 83 float gain; 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 debugMixBufferFrames; 112 }; 113 114 inline int 115 MixerInput::GetMixerChannelCount() 116 { 117 return fMixerChannelCount; 118 } 119 120 inline bool 121 MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos, 122 bigtime_t time, const float **buffer, 123 uint32 *sample_offset, int *type, float *gain) 124 { 125 // this function should not be called if we don't have a mix buffer! 126 ASSERT(fMixBuffer); 127 ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount); 128 if (!fEnabled) 129 return false; 130 131 #if 1 132 if (time < (fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount)) 133 || (time + duration_for_frames(fMixBufferFrameRate, debugMixBufferFrames)) >= fLastDataAvailableTime) 134 ERROR("MixerInput::GetMixerChannelInfo: reading wrong data, have %Ld to %Ld, reading from %Ld to %Ld\n", 135 fLastDataAvailableTime - duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount), fLastDataAvailableTime, time, time + duration_for_frames(fMixBufferFrameRate, debugMixBufferFrames)); 136 #endif 137 138 if (time > fLastDataAvailableTime) 139 return false; 140 141 int32 offset = framepos % fMixBufferFrameCount; 142 if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1); 143 *buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount)); 144 *sample_offset = sizeof(float) * fInputChannelCount; 145 *type = fMixerChannelInfo[mixer_channel].destination_type; 146 *gain = fMixerChannelInfo[mixer_channel].destination_gain; 147 return true; 148 } 149 #endif 150