1678c2017Sbeveloper #include <MediaNode.h> 2*2e9d6607Sbeveloper #include <Buffer.h> 3*2e9d6607Sbeveloper #include <RealtimeAlloc.h> 4678c2017Sbeveloper #include "MixerInput.h" 5678c2017Sbeveloper #include "MixerCore.h" 6e6c7c99fSbeveloper #include "MixerUtils.h" 7e6c7c99fSbeveloper #include "debug.h" 8678c2017Sbeveloper 9*2e9d6607Sbeveloper MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, bigtime_t mixStartTime) 10e6c7c99fSbeveloper : fCore(core), 11*2e9d6607Sbeveloper fInput(input), 12*2e9d6607Sbeveloper fInputChannelInfo(0), 13*2e9d6607Sbeveloper fInputChannelCount(0), 14*2e9d6607Sbeveloper fInputChannelMask(0), 15*2e9d6607Sbeveloper fMixerChannelInfo(0), 16*2e9d6607Sbeveloper fMixerChannelCount(0), 17*2e9d6607Sbeveloper fMixBuffer(0), 18*2e9d6607Sbeveloper fMixBufferSampleRate(0), 19*2e9d6607Sbeveloper fMixBufferFrames(0), 20*2e9d6607Sbeveloper fMixBufferStartTime(0), 21*2e9d6607Sbeveloper fUserOverridesChannelDesignations(false) 22678c2017Sbeveloper { 23e6c7c99fSbeveloper fix_multiaudio_format(&fInput.format.u.raw_audio); 24e6c7c99fSbeveloper PRINT_INPUT("MixerInput::MixerInput", fInput); 25e6c7c99fSbeveloper PRINT_CHANNEL_MASK(fInput.format); 26*2e9d6607Sbeveloper 27*2e9d6607Sbeveloper ASSERT(fInput.format.u.raw_audio.channel_count > 0); 28*2e9d6607Sbeveloper 29*2e9d6607Sbeveloper fInputChannelCount = fInput.format.u.raw_audio.channel_count; 30*2e9d6607Sbeveloper fInputChannelMask = fInput.format.u.raw_audio.channel_mask; 31*2e9d6607Sbeveloper fInputChannelInfo = new input_chan_info[fInputChannelCount]; 32*2e9d6607Sbeveloper 33*2e9d6607Sbeveloper // initialize fInputChannelInfo 34*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) { 35*2e9d6607Sbeveloper fInputChannelInfo[i].buffer_base = 0; // will be set by SetMixBufferFormat() 36*2e9d6607Sbeveloper fInputChannelInfo[i].designations = 0; // will be set by UpdateChannelDesignations() 37*2e9d6607Sbeveloper fInputChannelInfo[i].gain = 1.0; 38*2e9d6607Sbeveloper } 39*2e9d6607Sbeveloper 40*2e9d6607Sbeveloper // fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels() 41*2e9d6607Sbeveloper 42*2e9d6607Sbeveloper SetMixBufferFormat(mixSampleRate, mixFramesCount, mixStartTime); 43*2e9d6607Sbeveloper UpdateChannelDesignations(); 44*2e9d6607Sbeveloper UpdateMixerChannels(); 45*2e9d6607Sbeveloper 46*2e9d6607Sbeveloper 47*2e9d6607Sbeveloper // XXX a test: 48*2e9d6607Sbeveloper SetMixerChannelGain(0, 0.222); 49*2e9d6607Sbeveloper SetMixerChannelGain(1, 0.444); 50*2e9d6607Sbeveloper AddInputChannelDesignation(0, B_CHANNEL_REARRIGHT); 51*2e9d6607Sbeveloper SetMixerChannelGain(2, 0.666); 52*2e9d6607Sbeveloper AddInputChannelDesignation(1, B_CHANNEL_REARLEFT); 53678c2017Sbeveloper } 54678c2017Sbeveloper 55678c2017Sbeveloper MixerInput::~MixerInput() 56678c2017Sbeveloper { 57*2e9d6607Sbeveloper if (fMixBuffer) 58*2e9d6607Sbeveloper rtm_free(fMixBuffer); 59*2e9d6607Sbeveloper delete [] fInputChannelInfo; 60*2e9d6607Sbeveloper delete [] fMixerChannelInfo; 61678c2017Sbeveloper } 62678c2017Sbeveloper 63678c2017Sbeveloper void 64678c2017Sbeveloper MixerInput::BufferReceived(BBuffer *buffer) 65678c2017Sbeveloper { 66*2e9d6607Sbeveloper ASSERT(fMixBuffer); 67*2e9d6607Sbeveloper 68*2e9d6607Sbeveloper printf("mix buffer start %14Ld, buffer start %14Ld\n", fMixBufferStartTime, buffer->Header()->start_time); 69678c2017Sbeveloper } 707ee2c804Sbeveloper 717ee2c804Sbeveloper media_input & 727ee2c804Sbeveloper MixerInput::MediaInput() 737ee2c804Sbeveloper { 747ee2c804Sbeveloper return fInput; 757ee2c804Sbeveloper } 76e6c7c99fSbeveloper 77e6c7c99fSbeveloper int32 78e6c7c99fSbeveloper MixerInput::ID() 79e6c7c99fSbeveloper { 80e6c7c99fSbeveloper return fInput.destination.id; 81e6c7c99fSbeveloper } 82e6c7c99fSbeveloper 83*2e9d6607Sbeveloper void 84*2e9d6607Sbeveloper MixerInput::AddInputChannelDesignation(int channel, uint32 des) 85*2e9d6607Sbeveloper { 86*2e9d6607Sbeveloper ASSERT(count_nonzero_bits(des) == 1); 87e6c7c99fSbeveloper 88*2e9d6607Sbeveloper // test if the channel is valid 89*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 90*2e9d6607Sbeveloper return; 91*2e9d6607Sbeveloper 92*2e9d6607Sbeveloper // test if it is already set 93*2e9d6607Sbeveloper if (fInputChannelInfo[channel].designations & des) 94*2e9d6607Sbeveloper return; 95*2e9d6607Sbeveloper 96*2e9d6607Sbeveloper // remove it from all other channels that might have it 97*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 98*2e9d6607Sbeveloper fInputChannelInfo[i].designations &= ~des; 99*2e9d6607Sbeveloper 100*2e9d6607Sbeveloper // add it to specified channel 101*2e9d6607Sbeveloper fInputChannelInfo[channel].designations |= des; 102*2e9d6607Sbeveloper 103*2e9d6607Sbeveloper fUserOverridesChannelDesignations = true; 104*2e9d6607Sbeveloper UpdateMixerChannels(); 105*2e9d6607Sbeveloper } 106*2e9d6607Sbeveloper 107*2e9d6607Sbeveloper void 108*2e9d6607Sbeveloper MixerInput::RemoveInputChannelDesignation(int channel, uint32 des) 109*2e9d6607Sbeveloper { 110*2e9d6607Sbeveloper ASSERT(count_nonzero_bits(des) == 1); 111*2e9d6607Sbeveloper 112*2e9d6607Sbeveloper // test if the channel is valid 113*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 114*2e9d6607Sbeveloper return; 115*2e9d6607Sbeveloper 116*2e9d6607Sbeveloper // test if it is really set 117*2e9d6607Sbeveloper if ((fInputChannelInfo[channel].designations & des) == 0) 118*2e9d6607Sbeveloper return; 119*2e9d6607Sbeveloper 120*2e9d6607Sbeveloper // remove it from specified channel 121*2e9d6607Sbeveloper fInputChannelInfo[channel].designations &= ~des; 122*2e9d6607Sbeveloper 123*2e9d6607Sbeveloper fUserOverridesChannelDesignations = true; 124*2e9d6607Sbeveloper UpdateMixerChannels(); 125*2e9d6607Sbeveloper } 126*2e9d6607Sbeveloper 127*2e9d6607Sbeveloper uint32 128*2e9d6607Sbeveloper MixerInput::GetInputChannelDesignations(int channel) 129*2e9d6607Sbeveloper { 130*2e9d6607Sbeveloper // test if the channel is valid 131*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 132*2e9d6607Sbeveloper return 0; 133*2e9d6607Sbeveloper return fInputChannelInfo[channel].designations; 134*2e9d6607Sbeveloper } 135*2e9d6607Sbeveloper 136*2e9d6607Sbeveloper uint32 137*2e9d6607Sbeveloper MixerInput::GetInputChannelType(int channel) 138*2e9d6607Sbeveloper { 139*2e9d6607Sbeveloper // test if the channel is valid 140*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 141*2e9d6607Sbeveloper return 0; 142*2e9d6607Sbeveloper return GetChannelMask(channel, fInputChannelMask); 143*2e9d6607Sbeveloper } 144*2e9d6607Sbeveloper 145*2e9d6607Sbeveloper void 146*2e9d6607Sbeveloper MixerInput::SetInputChannelGain(int channel, float gain) 147*2e9d6607Sbeveloper { 148*2e9d6607Sbeveloper // test if the channel is valid 149*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 150*2e9d6607Sbeveloper return; 151*2e9d6607Sbeveloper if (gain < 0.0f) 152*2e9d6607Sbeveloper gain = 0.0f; 153*2e9d6607Sbeveloper 154*2e9d6607Sbeveloper fInputChannelInfo[channel].gain = gain; 155*2e9d6607Sbeveloper } 156*2e9d6607Sbeveloper 157*2e9d6607Sbeveloper float 158*2e9d6607Sbeveloper MixerInput::GetInputChannelGain(int channel) 159*2e9d6607Sbeveloper { 160*2e9d6607Sbeveloper // test if the channel is valid 161*2e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 162*2e9d6607Sbeveloper return 0.0f; 163*2e9d6607Sbeveloper return fInputChannelInfo[channel].gain; 164*2e9d6607Sbeveloper } 165*2e9d6607Sbeveloper 166*2e9d6607Sbeveloper void 167*2e9d6607Sbeveloper MixerInput::UpdateChannelDesignations() 168*2e9d6607Sbeveloper { 169*2e9d6607Sbeveloper // is the user already messed with the assignmens, don't do anything. 170*2e9d6607Sbeveloper if (fUserOverridesChannelDesignations) 171*2e9d6607Sbeveloper return; 172*2e9d6607Sbeveloper 173*2e9d6607Sbeveloper printf("UpdateChannelDesignations: enter\n"); 174*2e9d6607Sbeveloper 175*2e9d6607Sbeveloper if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) { 176*2e9d6607Sbeveloper // a left or right channel get's output as stereo on both 177*2e9d6607Sbeveloper fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; 178*2e9d6607Sbeveloper } else { 179*2e9d6607Sbeveloper // everything else get's mapped 1:1 180*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 181*2e9d6607Sbeveloper fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask); 182*2e9d6607Sbeveloper } 183*2e9d6607Sbeveloper 184*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 185*2e9d6607Sbeveloper printf("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); 186*2e9d6607Sbeveloper 187*2e9d6607Sbeveloper printf("UpdateChannelDesignations: enter\n"); 188*2e9d6607Sbeveloper } 189*2e9d6607Sbeveloper 190*2e9d6607Sbeveloper void 191*2e9d6607Sbeveloper MixerInput::UpdateMixerChannels() 192*2e9d6607Sbeveloper { 193*2e9d6607Sbeveloper uint32 channel_count; 194*2e9d6607Sbeveloper uint32 all_bits; 195*2e9d6607Sbeveloper uint32 mask; 196*2e9d6607Sbeveloper 197*2e9d6607Sbeveloper mixer_chan_info *old_mixer_channel_info; 198*2e9d6607Sbeveloper uint32 old_mixer_channel_count; 199*2e9d6607Sbeveloper 200*2e9d6607Sbeveloper ASSERT(fMixBuffer); 201*2e9d6607Sbeveloper 202*2e9d6607Sbeveloper printf("UpdateMixerChannels: enter\n"); 203*2e9d6607Sbeveloper 204*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 205*2e9d6607Sbeveloper printf("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); 206*2e9d6607Sbeveloper 207*2e9d6607Sbeveloper all_bits = 0; 208*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 209*2e9d6607Sbeveloper all_bits |= fInputChannelInfo[i].designations; 210*2e9d6607Sbeveloper 211*2e9d6607Sbeveloper printf("UpdateMixerChannels: all_bits = %08x\n", all_bits); 212*2e9d6607Sbeveloper 213*2e9d6607Sbeveloper channel_count = count_nonzero_bits(all_bits); 214*2e9d6607Sbeveloper 215*2e9d6607Sbeveloper printf("UpdateMixerChannels: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount); 216*2e9d6607Sbeveloper 217*2e9d6607Sbeveloper // If we resize the channel info array, we preserve the gain setting 218*2e9d6607Sbeveloper // by saving the old array until new assignments are finished, and 219*2e9d6607Sbeveloper // then applying the old gains. New gains are set to 1.0 220*2e9d6607Sbeveloper if (channel_count != fMixerChannelCount) { 221*2e9d6607Sbeveloper old_mixer_channel_info = fMixerChannelInfo; 222*2e9d6607Sbeveloper old_mixer_channel_count = fMixerChannelCount; 223*2e9d6607Sbeveloper fMixerChannelInfo = new mixer_chan_info[channel_count]; 224*2e9d6607Sbeveloper fMixerChannelCount = channel_count; 225*2e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) 226*2e9d6607Sbeveloper fMixerChannelInfo[i].gain = 1.0; 227*2e9d6607Sbeveloper } else { 228*2e9d6607Sbeveloper old_mixer_channel_info = 0; 229*2e9d6607Sbeveloper old_mixer_channel_count = 0; 230*2e9d6607Sbeveloper } 231*2e9d6607Sbeveloper 232*2e9d6607Sbeveloper // assign each mixer channel one type 233*2e9d6607Sbeveloper for (int i = 0, mask = 1; i < fMixerChannelCount; i++) { 234*2e9d6607Sbeveloper while (mask != 0 && (all_bits & mask) == 0) 235*2e9d6607Sbeveloper mask <<= 1; 236*2e9d6607Sbeveloper fMixerChannelInfo[i].designation = mask; 237*2e9d6607Sbeveloper mask <<= 1; 238*2e9d6607Sbeveloper } 239*2e9d6607Sbeveloper 240*2e9d6607Sbeveloper // assign buffer_base pointer for each mixer channel 241*2e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) { 242*2e9d6607Sbeveloper int j; 243*2e9d6607Sbeveloper for (j = 0; j < fInputChannelCount; j++) { 244*2e9d6607Sbeveloper if (fInputChannelInfo[j].designations & fMixerChannelInfo[i].designation) { 245*2e9d6607Sbeveloper fMixerChannelInfo[i].buffer_base = &fMixBuffer[j]; 246*2e9d6607Sbeveloper break; 247*2e9d6607Sbeveloper } 248*2e9d6607Sbeveloper } 249*2e9d6607Sbeveloper if (j == fInputChannelCount) { 250*2e9d6607Sbeveloper printf("buffer assignment failed for mixer chan %d\n", i); 251*2e9d6607Sbeveloper fMixerChannelInfo[i].buffer_base = fMixBuffer; 252*2e9d6607Sbeveloper } 253*2e9d6607Sbeveloper } 254*2e9d6607Sbeveloper 255*2e9d6607Sbeveloper // apply old gains, overriding the 1.0 defaults for the old channels 256*2e9d6607Sbeveloper if (old_mixer_channel_info != 0) { 257*2e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) { 258*2e9d6607Sbeveloper for (int j = 0; j < old_mixer_channel_count; j++) { 259*2e9d6607Sbeveloper if (fMixerChannelInfo[i].designation == old_mixer_channel_info[j].designation) { 260*2e9d6607Sbeveloper fMixerChannelInfo[i].gain = old_mixer_channel_info[j].gain; 261*2e9d6607Sbeveloper break; 262*2e9d6607Sbeveloper } 263*2e9d6607Sbeveloper } 264*2e9d6607Sbeveloper } 265*2e9d6607Sbeveloper // also delete the old info array 266*2e9d6607Sbeveloper delete [] old_mixer_channel_info; 267*2e9d6607Sbeveloper } 268*2e9d6607Sbeveloper 269*2e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) 270*2e9d6607Sbeveloper printf("UpdateMixerChannels: mixer channel %d, designation 0x%08X, base %p, gain %.3f\n", i, fMixerChannelInfo[i].designation, fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].gain); 271*2e9d6607Sbeveloper 272*2e9d6607Sbeveloper printf("UpdateMixerChannels: leave\n"); 273*2e9d6607Sbeveloper } 274*2e9d6607Sbeveloper 275*2e9d6607Sbeveloper uint32 276*2e9d6607Sbeveloper MixerInput::GetMixerChannelCount() 277*2e9d6607Sbeveloper { 278*2e9d6607Sbeveloper return fMixerChannelCount; 279*2e9d6607Sbeveloper } 280*2e9d6607Sbeveloper 281*2e9d6607Sbeveloper void 282*2e9d6607Sbeveloper MixerInput::GetMixerChannelInfo(int channel, const float **buffer, uint32 *sample_offset, uint32 *type, float *gain) 283*2e9d6607Sbeveloper { 284*2e9d6607Sbeveloper ASSERT(fMixBuffer); 285*2e9d6607Sbeveloper ASSERT(channel >= 0 && channel < fMixerChannelCount); 286*2e9d6607Sbeveloper *buffer = fMixerChannelInfo[channel].buffer_base; 287*2e9d6607Sbeveloper *sample_offset = sizeof(float) * fInputChannelCount; 288*2e9d6607Sbeveloper *type = fMixerChannelInfo[channel].designation; 289*2e9d6607Sbeveloper *gain = fMixerChannelInfo[channel].gain; 290*2e9d6607Sbeveloper } 291*2e9d6607Sbeveloper 292*2e9d6607Sbeveloper void 293*2e9d6607Sbeveloper MixerInput::SetMixerChannelGain(int channel, float gain) 294*2e9d6607Sbeveloper { 295*2e9d6607Sbeveloper if (channel < 0 || channel >= fMixerChannelCount) 296*2e9d6607Sbeveloper return; 297*2e9d6607Sbeveloper if (gain < 0.0f) 298*2e9d6607Sbeveloper gain = 0.0f; 299*2e9d6607Sbeveloper fMixerChannelInfo[channel].gain = gain; 300*2e9d6607Sbeveloper } 301*2e9d6607Sbeveloper 302*2e9d6607Sbeveloper float 303*2e9d6607Sbeveloper MixerInput::GetMixerChannelGain(int channel) 304*2e9d6607Sbeveloper { 305*2e9d6607Sbeveloper if (channel < 0 || channel >= fMixerChannelCount) 306*2e9d6607Sbeveloper return 1.0; 307*2e9d6607Sbeveloper return fMixerChannelInfo[channel].gain; 308*2e9d6607Sbeveloper } 309*2e9d6607Sbeveloper 310*2e9d6607Sbeveloper void 311*2e9d6607Sbeveloper MixerInput::SetMixBufferFormat(float samplerate, int32 frames, bigtime_t starttime) 312*2e9d6607Sbeveloper { 313*2e9d6607Sbeveloper fMixBufferSampleRate = samplerate; 314*2e9d6607Sbeveloper fMixBufferFrames = frames; 315*2e9d6607Sbeveloper fMixBufferStartTime = starttime; 316*2e9d6607Sbeveloper 317*2e9d6607Sbeveloper if (fMixBuffer) 318*2e9d6607Sbeveloper rtm_free(fMixBuffer); 319*2e9d6607Sbeveloper fMixBuffer = (float *)rtm_alloc(NULL, sizeof(float) * fInputChannelCount * fMixBufferFrames); 320*2e9d6607Sbeveloper 321*2e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 322*2e9d6607Sbeveloper fInputChannelInfo[i].buffer_base = &fMixBuffer[i * fMixBufferFrames]; 323*2e9d6607Sbeveloper } 324