1678c2017Sbeveloper #include <MediaNode.h> 22e9d6607Sbeveloper #include <Buffer.h> 32e9d6607Sbeveloper #include <RealtimeAlloc.h> 47b0daf5cSbeveloper #include <string.h> 5678c2017Sbeveloper #include "MixerInput.h" 6678c2017Sbeveloper #include "MixerCore.h" 7e6c7c99fSbeveloper #include "MixerUtils.h" 87b0daf5cSbeveloper #include "Resampler.h" 988777023Sbeveloper #include "ByteSwap.h" 10e6c7c99fSbeveloper #include "debug.h" 11678c2017Sbeveloper 127b0daf5cSbeveloper template<class t> const t & max(const t &t1, const t &t2) { return (t1 > t2) ? t1 : t2; } 137b0daf5cSbeveloper 1416cecbdeSbeveloper MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrameRate, int32 mixFrameCount, bigtime_t mixStartTime) 15e6c7c99fSbeveloper : fCore(core), 162e9d6607Sbeveloper fInput(input), 1788777023Sbeveloper fInputByteSwap(0), 182e9d6607Sbeveloper fInputChannelInfo(0), 192e9d6607Sbeveloper fInputChannelCount(0), 202e9d6607Sbeveloper fInputChannelMask(0), 212e9d6607Sbeveloper fMixerChannelInfo(0), 222e9d6607Sbeveloper fMixerChannelCount(0), 232e9d6607Sbeveloper fMixBuffer(0), 247b0daf5cSbeveloper fMixBufferFrameRate(0), 257b0daf5cSbeveloper fMixBufferFrameCount(0), 262e9d6607Sbeveloper fMixBufferStartTime(0), 277b0daf5cSbeveloper fResampler(0), 282e9d6607Sbeveloper fUserOverridesChannelDesignations(false) 29678c2017Sbeveloper { 30e6c7c99fSbeveloper fix_multiaudio_format(&fInput.format.u.raw_audio); 31e6c7c99fSbeveloper PRINT_INPUT("MixerInput::MixerInput", fInput); 32e6c7c99fSbeveloper PRINT_CHANNEL_MASK(fInput.format); 332e9d6607Sbeveloper 342e9d6607Sbeveloper ASSERT(fInput.format.u.raw_audio.channel_count > 0); 352e9d6607Sbeveloper 362e9d6607Sbeveloper fInputChannelCount = fInput.format.u.raw_audio.channel_count; 372e9d6607Sbeveloper fInputChannelMask = fInput.format.u.raw_audio.channel_mask; 382e9d6607Sbeveloper fInputChannelInfo = new input_chan_info[fInputChannelCount]; 392e9d6607Sbeveloper 4088777023Sbeveloper // perhaps we need byte swapping 4188777023Sbeveloper if (fInput.format.u.raw_audio.byte_order != B_MEDIA_HOST_ENDIAN) { 4288777023Sbeveloper if ( fInput.format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_FLOAT 4388777023Sbeveloper || fInput.format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_INT 4488777023Sbeveloper || fInput.format.u.raw_audio.format == media_raw_audio_format::B_AUDIO_SHORT) { 4588777023Sbeveloper fInputByteSwap = new ByteSwap(fInput.format.u.raw_audio.format); 4688777023Sbeveloper } 4788777023Sbeveloper } 4888777023Sbeveloper 492e9d6607Sbeveloper // initialize fInputChannelInfo 502e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) { 512e9d6607Sbeveloper fInputChannelInfo[i].buffer_base = 0; // will be set by SetMixBufferFormat() 522e9d6607Sbeveloper fInputChannelInfo[i].designations = 0; // will be set by UpdateChannelDesignations() 532e9d6607Sbeveloper fInputChannelInfo[i].gain = 1.0; 542e9d6607Sbeveloper } 552e9d6607Sbeveloper 567b0daf5cSbeveloper // create resamplers 577b0daf5cSbeveloper fResampler = new Resampler * [fInputChannelCount]; 587b0daf5cSbeveloper for (int i = 0; i < fInputChannelCount; i++) 597b0daf5cSbeveloper fResampler[i] = new Resampler(fInput.format.u.raw_audio.format, media_raw_audio_format::B_AUDIO_FLOAT); 607b0daf5cSbeveloper 612e9d6607Sbeveloper // fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels() 622e9d6607Sbeveloper 6316cecbdeSbeveloper SetMixBufferFormat(mixFrameRate, mixFrameCount, mixStartTime); 642e9d6607Sbeveloper UpdateChannelDesignations(); 652e9d6607Sbeveloper UpdateMixerChannels(); 662e9d6607Sbeveloper 672e9d6607Sbeveloper 682e9d6607Sbeveloper // XXX a test: 692e9d6607Sbeveloper SetMixerChannelGain(0, 0.222); 702e9d6607Sbeveloper SetMixerChannelGain(1, 0.444); 712e9d6607Sbeveloper AddInputChannelDesignation(0, B_CHANNEL_REARRIGHT); 722e9d6607Sbeveloper SetMixerChannelGain(2, 0.666); 732e9d6607Sbeveloper AddInputChannelDesignation(1, B_CHANNEL_REARLEFT); 74678c2017Sbeveloper } 75678c2017Sbeveloper 76678c2017Sbeveloper MixerInput::~MixerInput() 77678c2017Sbeveloper { 782e9d6607Sbeveloper if (fMixBuffer) 792e9d6607Sbeveloper rtm_free(fMixBuffer); 802e9d6607Sbeveloper delete [] fInputChannelInfo; 812e9d6607Sbeveloper delete [] fMixerChannelInfo; 827b0daf5cSbeveloper 837b0daf5cSbeveloper // delete resamplers 847b0daf5cSbeveloper for (int i = 0; i < fInputChannelCount; i++) 857b0daf5cSbeveloper delete fResampler[i]; 867b0daf5cSbeveloper delete [] fResampler; 87678c2017Sbeveloper } 88678c2017Sbeveloper 89678c2017Sbeveloper void 90678c2017Sbeveloper MixerInput::BufferReceived(BBuffer *buffer) 91678c2017Sbeveloper { 9288777023Sbeveloper void *data; 9388777023Sbeveloper size_t size; 9488777023Sbeveloper bigtime_t start; 9588777023Sbeveloper 962e9d6607Sbeveloper ASSERT(fMixBuffer); 972e9d6607Sbeveloper 9888777023Sbeveloper data = buffer->Data(); 9988777023Sbeveloper size = buffer->SizeUsed(); 10088777023Sbeveloper start = buffer->Header()->start_time; 10188777023Sbeveloper 10288777023Sbeveloper // swap the byte order of this buffer, if necessary 10388777023Sbeveloper if (fInputByteSwap) 10488777023Sbeveloper fInputByteSwap->Swap(data, size); 10588777023Sbeveloper 1067b0daf5cSbeveloper int32 offset = frames_for_duration(fMixBufferFrameRate, start - fMixBufferStartTime) % fMixBufferFrameCount; 10788777023Sbeveloper 108*8df36cddSbeveloper // printf("MixerInput::BufferReceived: mix buffer start %14Ld, buffer start %14Ld, offset %6d\n", fMixBufferStartTime, start, offset); 1097b0daf5cSbeveloper 1107b0daf5cSbeveloper int in_frames = frames_per_buffer(fInput.format.u.raw_audio); // XXX use size 1117b0daf5cSbeveloper int out_frames = (int)((in_frames * fMixBufferFrameRate) / fInput.format.u.raw_audio.frame_rate); // XXX losing fractions 1127b0daf5cSbeveloper 113*8df36cddSbeveloper //printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); 114*8df36cddSbeveloper 1157b0daf5cSbeveloper if (offset + out_frames > fMixBufferFrameCount) { 1167b0daf5cSbeveloper 1177b0daf5cSbeveloper int out_frames1 = fMixBufferFrameCount - offset; 1187b0daf5cSbeveloper int out_frames2 = out_frames - out_frames1; 1197b0daf5cSbeveloper int in_frames1 = (out_frames1 * in_frames) / out_frames; 1207b0daf5cSbeveloper int in_frames2 = in_frames - in_frames1; 1217b0daf5cSbeveloper 122*8df36cddSbeveloper printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld and %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames1, 0, out_frames2); 123*8df36cddSbeveloper 124*8df36cddSbeveloper // printf(" in_frames %5d, out_frames %5d, in_frames1 %5d, out_frames1 %5d, in_frames2 %5d, out_frames2 %5d\n", 125*8df36cddSbeveloper // in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2); 1267b0daf5cSbeveloper 1277b0daf5cSbeveloper for (int i = 0; i < fInputChannelCount; i++) { 12878563dcaSbeveloper fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio), 12978563dcaSbeveloper bytes_per_frame(fInput.format.u.raw_audio), 1307b0daf5cSbeveloper in_frames1, 1317b0daf5cSbeveloper reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount), 1327b0daf5cSbeveloper fInputChannelCount * sizeof(float), 1337b0daf5cSbeveloper out_frames1, 1347b0daf5cSbeveloper fInputChannelInfo[i].gain); 1357b0daf5cSbeveloper 13678563dcaSbeveloper fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio), 13778563dcaSbeveloper bytes_per_frame(fInput.format.u.raw_audio), 1387b0daf5cSbeveloper in_frames2, 1397b0daf5cSbeveloper reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base), 1407b0daf5cSbeveloper fInputChannelCount * sizeof(float), 1417b0daf5cSbeveloper out_frames2, 1427b0daf5cSbeveloper fInputChannelInfo[i].gain); 1437b0daf5cSbeveloper } 1447b0daf5cSbeveloper } else { 1457b0daf5cSbeveloper 146*8df36cddSbeveloper // printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames); 147*8df36cddSbeveloper printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); 1487b0daf5cSbeveloper 1497b0daf5cSbeveloper for (int i = 0; i < fInputChannelCount; i++) { 15078563dcaSbeveloper fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio), 15178563dcaSbeveloper bytes_per_frame(fInput.format.u.raw_audio), 1527b0daf5cSbeveloper in_frames, 1537b0daf5cSbeveloper reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount), 1547b0daf5cSbeveloper fInputChannelCount * sizeof(float), 1557b0daf5cSbeveloper out_frames, 1567b0daf5cSbeveloper fInputChannelInfo[i].gain); 1577b0daf5cSbeveloper } 1587b0daf5cSbeveloper } 159678c2017Sbeveloper } 1607ee2c804Sbeveloper 1617ee2c804Sbeveloper media_input & 1627ee2c804Sbeveloper MixerInput::MediaInput() 1637ee2c804Sbeveloper { 1647ee2c804Sbeveloper return fInput; 1657ee2c804Sbeveloper } 166e6c7c99fSbeveloper 167e6c7c99fSbeveloper int32 168e6c7c99fSbeveloper MixerInput::ID() 169e6c7c99fSbeveloper { 170e6c7c99fSbeveloper return fInput.destination.id; 171e6c7c99fSbeveloper } 172e6c7c99fSbeveloper 1732e9d6607Sbeveloper void 1742e9d6607Sbeveloper MixerInput::AddInputChannelDesignation(int channel, uint32 des) 1752e9d6607Sbeveloper { 1762e9d6607Sbeveloper ASSERT(count_nonzero_bits(des) == 1); 177e6c7c99fSbeveloper 1782e9d6607Sbeveloper // test if the channel is valid 1792e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 1802e9d6607Sbeveloper return; 1812e9d6607Sbeveloper 1822e9d6607Sbeveloper // test if it is already set 1832e9d6607Sbeveloper if (fInputChannelInfo[channel].designations & des) 1842e9d6607Sbeveloper return; 1852e9d6607Sbeveloper 1862e9d6607Sbeveloper // remove it from all other channels that might have it 1872e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 1882e9d6607Sbeveloper fInputChannelInfo[i].designations &= ~des; 1892e9d6607Sbeveloper 1902e9d6607Sbeveloper // add it to specified channel 1912e9d6607Sbeveloper fInputChannelInfo[channel].designations |= des; 1922e9d6607Sbeveloper 1932e9d6607Sbeveloper fUserOverridesChannelDesignations = true; 1942e9d6607Sbeveloper UpdateMixerChannels(); 1952e9d6607Sbeveloper } 1962e9d6607Sbeveloper 1972e9d6607Sbeveloper void 1982e9d6607Sbeveloper MixerInput::RemoveInputChannelDesignation(int channel, uint32 des) 1992e9d6607Sbeveloper { 2002e9d6607Sbeveloper ASSERT(count_nonzero_bits(des) == 1); 2012e9d6607Sbeveloper 2022e9d6607Sbeveloper // test if the channel is valid 2032e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 2042e9d6607Sbeveloper return; 2052e9d6607Sbeveloper 2062e9d6607Sbeveloper // test if it is really set 2072e9d6607Sbeveloper if ((fInputChannelInfo[channel].designations & des) == 0) 2082e9d6607Sbeveloper return; 2092e9d6607Sbeveloper 2102e9d6607Sbeveloper // remove it from specified channel 2112e9d6607Sbeveloper fInputChannelInfo[channel].designations &= ~des; 2122e9d6607Sbeveloper 2132e9d6607Sbeveloper fUserOverridesChannelDesignations = true; 2142e9d6607Sbeveloper UpdateMixerChannels(); 2152e9d6607Sbeveloper } 2162e9d6607Sbeveloper 2172e9d6607Sbeveloper uint32 2182e9d6607Sbeveloper MixerInput::GetInputChannelDesignations(int channel) 2192e9d6607Sbeveloper { 2202e9d6607Sbeveloper // test if the channel is valid 2212e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 2222e9d6607Sbeveloper return 0; 2232e9d6607Sbeveloper return fInputChannelInfo[channel].designations; 2242e9d6607Sbeveloper } 2252e9d6607Sbeveloper 2262e9d6607Sbeveloper uint32 2272e9d6607Sbeveloper MixerInput::GetInputChannelType(int channel) 2282e9d6607Sbeveloper { 2292e9d6607Sbeveloper // test if the channel is valid 2302e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 2312e9d6607Sbeveloper return 0; 2322e9d6607Sbeveloper return GetChannelMask(channel, fInputChannelMask); 2332e9d6607Sbeveloper } 2342e9d6607Sbeveloper 2352e9d6607Sbeveloper void 2362e9d6607Sbeveloper MixerInput::SetInputChannelGain(int channel, float gain) 2372e9d6607Sbeveloper { 2382e9d6607Sbeveloper // test if the channel is valid 2392e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 2402e9d6607Sbeveloper return; 2412e9d6607Sbeveloper if (gain < 0.0f) 2422e9d6607Sbeveloper gain = 0.0f; 2432e9d6607Sbeveloper 2442e9d6607Sbeveloper fInputChannelInfo[channel].gain = gain; 2452e9d6607Sbeveloper } 2462e9d6607Sbeveloper 2472e9d6607Sbeveloper float 2482e9d6607Sbeveloper MixerInput::GetInputChannelGain(int channel) 2492e9d6607Sbeveloper { 2502e9d6607Sbeveloper // test if the channel is valid 2512e9d6607Sbeveloper if (channel < 0 || channel >= fInputChannelCount) 2522e9d6607Sbeveloper return 0.0f; 2532e9d6607Sbeveloper return fInputChannelInfo[channel].gain; 2542e9d6607Sbeveloper } 2552e9d6607Sbeveloper 2562e9d6607Sbeveloper void 2572e9d6607Sbeveloper MixerInput::UpdateChannelDesignations() 2582e9d6607Sbeveloper { 2592e9d6607Sbeveloper // is the user already messed with the assignmens, don't do anything. 2602e9d6607Sbeveloper if (fUserOverridesChannelDesignations) 2612e9d6607Sbeveloper return; 2622e9d6607Sbeveloper 2632e9d6607Sbeveloper printf("UpdateChannelDesignations: enter\n"); 2642e9d6607Sbeveloper 2652e9d6607Sbeveloper if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) { 2662e9d6607Sbeveloper // a left or right channel get's output as stereo on both 2672e9d6607Sbeveloper fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; 2682e9d6607Sbeveloper } else { 2692e9d6607Sbeveloper // everything else get's mapped 1:1 2702e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 2712e9d6607Sbeveloper fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask); 2722e9d6607Sbeveloper } 2732e9d6607Sbeveloper 2742e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 2752e9d6607Sbeveloper printf("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); 2762e9d6607Sbeveloper 2772e9d6607Sbeveloper printf("UpdateChannelDesignations: enter\n"); 2782e9d6607Sbeveloper } 2792e9d6607Sbeveloper 2802e9d6607Sbeveloper void 2812e9d6607Sbeveloper MixerInput::UpdateMixerChannels() 2822e9d6607Sbeveloper { 2832e9d6607Sbeveloper uint32 channel_count; 2842e9d6607Sbeveloper uint32 all_bits; 2852e9d6607Sbeveloper uint32 mask; 2862e9d6607Sbeveloper 2872e9d6607Sbeveloper mixer_chan_info *old_mixer_channel_info; 2882e9d6607Sbeveloper uint32 old_mixer_channel_count; 2892e9d6607Sbeveloper 2902e9d6607Sbeveloper ASSERT(fMixBuffer); 2912e9d6607Sbeveloper 2922e9d6607Sbeveloper printf("UpdateMixerChannels: enter\n"); 2932e9d6607Sbeveloper 2942e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 2952e9d6607Sbeveloper printf("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); 2962e9d6607Sbeveloper 2972e9d6607Sbeveloper all_bits = 0; 2982e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 2992e9d6607Sbeveloper all_bits |= fInputChannelInfo[i].designations; 3002e9d6607Sbeveloper 3012e9d6607Sbeveloper printf("UpdateMixerChannels: all_bits = %08x\n", all_bits); 3022e9d6607Sbeveloper 3032e9d6607Sbeveloper channel_count = count_nonzero_bits(all_bits); 3042e9d6607Sbeveloper 3052e9d6607Sbeveloper printf("UpdateMixerChannels: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount); 3062e9d6607Sbeveloper 3072e9d6607Sbeveloper // If we resize the channel info array, we preserve the gain setting 3082e9d6607Sbeveloper // by saving the old array until new assignments are finished, and 3092e9d6607Sbeveloper // then applying the old gains. New gains are set to 1.0 3102e9d6607Sbeveloper if (channel_count != fMixerChannelCount) { 3112e9d6607Sbeveloper old_mixer_channel_info = fMixerChannelInfo; 3122e9d6607Sbeveloper old_mixer_channel_count = fMixerChannelCount; 3132e9d6607Sbeveloper fMixerChannelInfo = new mixer_chan_info[channel_count]; 3142e9d6607Sbeveloper fMixerChannelCount = channel_count; 3152e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) 3162e9d6607Sbeveloper fMixerChannelInfo[i].gain = 1.0; 3172e9d6607Sbeveloper } else { 3182e9d6607Sbeveloper old_mixer_channel_info = 0; 3192e9d6607Sbeveloper old_mixer_channel_count = 0; 3202e9d6607Sbeveloper } 3212e9d6607Sbeveloper 3222e9d6607Sbeveloper // assign each mixer channel one type 3232e9d6607Sbeveloper for (int i = 0, mask = 1; i < fMixerChannelCount; i++) { 3242e9d6607Sbeveloper while (mask != 0 && (all_bits & mask) == 0) 3252e9d6607Sbeveloper mask <<= 1; 326a4b8db85Sbeveloper fMixerChannelInfo[i].type = ChannelMaskToChannelType(mask); 3272e9d6607Sbeveloper mask <<= 1; 3282e9d6607Sbeveloper } 3292e9d6607Sbeveloper 3302e9d6607Sbeveloper // assign buffer_base pointer for each mixer channel 3312e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) { 3322e9d6607Sbeveloper int j; 3332e9d6607Sbeveloper for (j = 0; j < fInputChannelCount; j++) { 334a4b8db85Sbeveloper if (fInputChannelInfo[j].designations & ChannelTypeToChannelMask(fMixerChannelInfo[i].type)) { 3352e9d6607Sbeveloper fMixerChannelInfo[i].buffer_base = &fMixBuffer[j]; 3362e9d6607Sbeveloper break; 3372e9d6607Sbeveloper } 3382e9d6607Sbeveloper } 3392e9d6607Sbeveloper if (j == fInputChannelCount) { 3402e9d6607Sbeveloper printf("buffer assignment failed for mixer chan %d\n", i); 3412e9d6607Sbeveloper fMixerChannelInfo[i].buffer_base = fMixBuffer; 3422e9d6607Sbeveloper } 3432e9d6607Sbeveloper } 3442e9d6607Sbeveloper 3452e9d6607Sbeveloper // apply old gains, overriding the 1.0 defaults for the old channels 3462e9d6607Sbeveloper if (old_mixer_channel_info != 0) { 3472e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) { 3482e9d6607Sbeveloper for (int j = 0; j < old_mixer_channel_count; j++) { 349a4b8db85Sbeveloper if (fMixerChannelInfo[i].type == old_mixer_channel_info[j].type) { 3502e9d6607Sbeveloper fMixerChannelInfo[i].gain = old_mixer_channel_info[j].gain; 3512e9d6607Sbeveloper break; 3522e9d6607Sbeveloper } 3532e9d6607Sbeveloper } 3542e9d6607Sbeveloper } 3552e9d6607Sbeveloper // also delete the old info array 3562e9d6607Sbeveloper delete [] old_mixer_channel_info; 3572e9d6607Sbeveloper } 3582e9d6607Sbeveloper 3592e9d6607Sbeveloper for (int i = 0; i < fMixerChannelCount; i++) 360a4b8db85Sbeveloper printf("UpdateMixerChannels: mixer channel %d, type %2d, des 0x%08X, base %p, gain %.3f\n", i, fMixerChannelInfo[i].type, ChannelTypeToChannelMask(fMixerChannelInfo[i].type), fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].gain); 3612e9d6607Sbeveloper 3622e9d6607Sbeveloper printf("UpdateMixerChannels: leave\n"); 3632e9d6607Sbeveloper } 3642e9d6607Sbeveloper 3652e9d6607Sbeveloper uint32 3662e9d6607Sbeveloper MixerInput::GetMixerChannelCount() 3672e9d6607Sbeveloper { 3682e9d6607Sbeveloper return fMixerChannelCount; 3692e9d6607Sbeveloper } 3702e9d6607Sbeveloper 3712e9d6607Sbeveloper void 3727b0daf5cSbeveloper MixerInput::GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain) 3732e9d6607Sbeveloper { 3742e9d6607Sbeveloper ASSERT(fMixBuffer); 3752e9d6607Sbeveloper ASSERT(channel >= 0 && channel < fMixerChannelCount); 3767b0daf5cSbeveloper int32 offset = framepos % fMixBufferFrameCount; 377*8df36cddSbeveloper printf("GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames); 3787b0daf5cSbeveloper *buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount)); 3792e9d6607Sbeveloper *sample_offset = sizeof(float) * fInputChannelCount; 380a4b8db85Sbeveloper *type = fMixerChannelInfo[channel].type; 3812e9d6607Sbeveloper *gain = fMixerChannelInfo[channel].gain; 3822e9d6607Sbeveloper } 3832e9d6607Sbeveloper 3842e9d6607Sbeveloper void 3852e9d6607Sbeveloper MixerInput::SetMixerChannelGain(int channel, float gain) 3862e9d6607Sbeveloper { 3872e9d6607Sbeveloper if (channel < 0 || channel >= fMixerChannelCount) 3882e9d6607Sbeveloper return; 3892e9d6607Sbeveloper if (gain < 0.0f) 3902e9d6607Sbeveloper gain = 0.0f; 3912e9d6607Sbeveloper fMixerChannelInfo[channel].gain = gain; 3922e9d6607Sbeveloper } 3932e9d6607Sbeveloper 3942e9d6607Sbeveloper float 3952e9d6607Sbeveloper MixerInput::GetMixerChannelGain(int channel) 3962e9d6607Sbeveloper { 3972e9d6607Sbeveloper if (channel < 0 || channel >= fMixerChannelCount) 3982e9d6607Sbeveloper return 1.0; 3992e9d6607Sbeveloper return fMixerChannelInfo[channel].gain; 4002e9d6607Sbeveloper } 4012e9d6607Sbeveloper 4022e9d6607Sbeveloper void 4037b0daf5cSbeveloper MixerInput::SetMixBufferFormat(int32 framerate, int32 frames, bigtime_t starttime) 4042e9d6607Sbeveloper { 4057b0daf5cSbeveloper fMixBufferFrameRate = framerate; 4062e9d6607Sbeveloper fMixBufferStartTime = starttime; 407*8df36cddSbeveloper debugMixBufferFrames = frames; 4082e9d6607Sbeveloper 4097b0daf5cSbeveloper printf("MixerInput::SetMixBufferFormat: framerate %ld, frames %ld, starttime %Ld\n", framerate, frames, starttime); 4107b0daf5cSbeveloper 4117b0daf5cSbeveloper // make fMixBufferFrameCount an integral multiple of frames, 4127b0daf5cSbeveloper // but at least 3 times duration of our input buffer 4137b0daf5cSbeveloper // and at least 2 times duration of the output buffer 4147b0daf5cSbeveloper bigtime_t inputBufferLength = duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)); 4157b0daf5cSbeveloper bigtime_t outputBufferLength = duration_for_frames(framerate, frames); 4167b0daf5cSbeveloper bigtime_t mixerBufferLength = max_c(3 * inputBufferLength, 2 * outputBufferLength); 4177b0daf5cSbeveloper int temp = frames_for_duration(framerate, mixerBufferLength); 4187b0daf5cSbeveloper fMixBufferFrameCount = ((temp / frames) + 1) * frames; 4197b0daf5cSbeveloper 4207b0daf5cSbeveloper printf(" inputBufferLength %10Ld\n", inputBufferLength); 4217b0daf5cSbeveloper printf(" outputBufferLength %10Ld\n", outputBufferLength); 4227b0daf5cSbeveloper printf(" mixerBufferLength %10Ld\n", mixerBufferLength); 4237b0daf5cSbeveloper printf(" fMixBufferFrameCount %10ld\n", fMixBufferFrameCount); 4247b0daf5cSbeveloper 4252e9d6607Sbeveloper if (fMixBuffer) 4262e9d6607Sbeveloper rtm_free(fMixBuffer); 4277b0daf5cSbeveloper int size = sizeof(float) * fInputChannelCount * fMixBufferFrameCount; 4287b0daf5cSbeveloper fMixBuffer = (float *)rtm_alloc(NULL, size); 4297b0daf5cSbeveloper ASSERT(fMixBuffer); 4307b0daf5cSbeveloper 4317b0daf5cSbeveloper memset(fMixBuffer, 0, size); 4322e9d6607Sbeveloper 4332e9d6607Sbeveloper for (int i = 0; i < fInputChannelCount; i++) 4347b0daf5cSbeveloper fInputChannelInfo[i].buffer_base = &fMixBuffer[i]; 4352e9d6607Sbeveloper } 436