xref: /haiku/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp (revision 7b0daf5ccadfdb073a738f291a2f4a74b29c46f0)
1678c2017Sbeveloper #include <MediaNode.h>
22e9d6607Sbeveloper #include <Buffer.h>
32e9d6607Sbeveloper #include <RealtimeAlloc.h>
4*7b0daf5cSbeveloper #include <string.h>
5678c2017Sbeveloper #include "MixerInput.h"
6678c2017Sbeveloper #include "MixerCore.h"
7e6c7c99fSbeveloper #include "MixerUtils.h"
8*7b0daf5cSbeveloper #include "Resampler.h"
988777023Sbeveloper #include "ByteSwap.h"
10e6c7c99fSbeveloper #include "debug.h"
11678c2017Sbeveloper 
12*7b0daf5cSbeveloper template<class t> const t & max(const t &t1, const t &t2) { return (t1 > t2) ?  t1 : t2; }
13*7b0daf5cSbeveloper 
142e9d6607Sbeveloper MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, 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),
24*7b0daf5cSbeveloper 	fMixBufferFrameRate(0),
25*7b0daf5cSbeveloper 	fMixBufferFrameCount(0),
262e9d6607Sbeveloper 	fMixBufferStartTime(0),
27*7b0daf5cSbeveloper 	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 
56*7b0daf5cSbeveloper 	// create resamplers
57*7b0daf5cSbeveloper 	fResampler = new Resampler * [fInputChannelCount];
58*7b0daf5cSbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
59*7b0daf5cSbeveloper 		fResampler[i] = new Resampler(fInput.format.u.raw_audio.format, media_raw_audio_format::B_AUDIO_FLOAT);
60*7b0daf5cSbeveloper 
612e9d6607Sbeveloper 	// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels()
622e9d6607Sbeveloper 
632e9d6607Sbeveloper 	SetMixBufferFormat(mixSampleRate, mixFramesCount, 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;
82*7b0daf5cSbeveloper 
83*7b0daf5cSbeveloper 	// delete resamplers
84*7b0daf5cSbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
85*7b0daf5cSbeveloper 		delete fResampler[i];
86*7b0daf5cSbeveloper 	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 
106*7b0daf5cSbeveloper 	int32 offset = frames_for_duration(fMixBufferFrameRate, start - fMixBufferStartTime) % fMixBufferFrameCount;
10788777023Sbeveloper 
108*7b0daf5cSbeveloper 	printf("MixerInput::BufferReceived:  mix buffer start %14Ld, buffer start %14Ld, offset %6d\n", fMixBufferStartTime, start, offset);
109*7b0daf5cSbeveloper 
110*7b0daf5cSbeveloper 	int in_frames = frames_per_buffer(fInput.format.u.raw_audio); // XXX use size
111*7b0daf5cSbeveloper 	int out_frames = (int)((in_frames * fMixBufferFrameRate) / fInput.format.u.raw_audio.frame_rate); // XXX losing fractions
112*7b0daf5cSbeveloper 
113*7b0daf5cSbeveloper 	if (offset + out_frames > fMixBufferFrameCount) {
114*7b0daf5cSbeveloper 
115*7b0daf5cSbeveloper 		int out_frames1 = fMixBufferFrameCount - offset;
116*7b0daf5cSbeveloper 		int out_frames2 = out_frames - out_frames1;
117*7b0daf5cSbeveloper 		int in_frames1 = (out_frames1 * in_frames) / out_frames;
118*7b0daf5cSbeveloper 		int in_frames2 = in_frames - in_frames1;
119*7b0daf5cSbeveloper 
120*7b0daf5cSbeveloper 		printf("  in_frames %5d, out_frames %5d, in_frames1 %5d, out_frames1 %5d, in_frames2 %5d, out_frames2 %5d\n",
121*7b0daf5cSbeveloper 			   in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2);
122*7b0daf5cSbeveloper 
123*7b0daf5cSbeveloper 		for (int i = 0; i < fInputChannelCount; i++) {
124*7b0daf5cSbeveloper 			fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
125*7b0daf5cSbeveloper 									fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
126*7b0daf5cSbeveloper 									in_frames1,
127*7b0daf5cSbeveloper 									reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
128*7b0daf5cSbeveloper 									fInputChannelCount * sizeof(float),
129*7b0daf5cSbeveloper 									out_frames1,
130*7b0daf5cSbeveloper 									fInputChannelInfo[i].gain);
131*7b0daf5cSbeveloper 
132*7b0daf5cSbeveloper 			fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
133*7b0daf5cSbeveloper 									fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
134*7b0daf5cSbeveloper 									in_frames2,
135*7b0daf5cSbeveloper 									reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base),
136*7b0daf5cSbeveloper 									fInputChannelCount * sizeof(float),
137*7b0daf5cSbeveloper 									out_frames2,
138*7b0daf5cSbeveloper 									fInputChannelInfo[i].gain);
139*7b0daf5cSbeveloper 		}
140*7b0daf5cSbeveloper 	} else {
141*7b0daf5cSbeveloper 
142*7b0daf5cSbeveloper 		printf("  in_frames %5d, out_frames %5d\n", in_frames, out_frames);
143*7b0daf5cSbeveloper 
144*7b0daf5cSbeveloper 		for (int i = 0; i < fInputChannelCount; i++) {
145*7b0daf5cSbeveloper 			fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
146*7b0daf5cSbeveloper 									fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
147*7b0daf5cSbeveloper 									in_frames,
148*7b0daf5cSbeveloper 									reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
149*7b0daf5cSbeveloper 									fInputChannelCount * sizeof(float),
150*7b0daf5cSbeveloper 									out_frames,
151*7b0daf5cSbeveloper 									fInputChannelInfo[i].gain);
152*7b0daf5cSbeveloper 		}
153*7b0daf5cSbeveloper 	}
154678c2017Sbeveloper }
1557ee2c804Sbeveloper 
1567ee2c804Sbeveloper media_input &
1577ee2c804Sbeveloper MixerInput::MediaInput()
1587ee2c804Sbeveloper {
1597ee2c804Sbeveloper 	return fInput;
1607ee2c804Sbeveloper }
161e6c7c99fSbeveloper 
162e6c7c99fSbeveloper int32
163e6c7c99fSbeveloper MixerInput::ID()
164e6c7c99fSbeveloper {
165e6c7c99fSbeveloper 	return fInput.destination.id;
166e6c7c99fSbeveloper }
167e6c7c99fSbeveloper 
1682e9d6607Sbeveloper void
1692e9d6607Sbeveloper MixerInput::AddInputChannelDesignation(int channel, uint32 des)
1702e9d6607Sbeveloper {
1712e9d6607Sbeveloper 	ASSERT(count_nonzero_bits(des) == 1);
172e6c7c99fSbeveloper 
1732e9d6607Sbeveloper 	// test if the channel is valid
1742e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
1752e9d6607Sbeveloper 		return;
1762e9d6607Sbeveloper 
1772e9d6607Sbeveloper 	// test if it is already set
1782e9d6607Sbeveloper 	if (fInputChannelInfo[channel].designations & des)
1792e9d6607Sbeveloper 		return;
1802e9d6607Sbeveloper 
1812e9d6607Sbeveloper 	// remove it from all other channels that might have it
1822e9d6607Sbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
1832e9d6607Sbeveloper 		fInputChannelInfo[i].designations &= ~des;
1842e9d6607Sbeveloper 
1852e9d6607Sbeveloper 	// add it to specified channel
1862e9d6607Sbeveloper 	fInputChannelInfo[channel].designations |= des;
1872e9d6607Sbeveloper 
1882e9d6607Sbeveloper 	fUserOverridesChannelDesignations = true;
1892e9d6607Sbeveloper 	UpdateMixerChannels();
1902e9d6607Sbeveloper }
1912e9d6607Sbeveloper 
1922e9d6607Sbeveloper void
1932e9d6607Sbeveloper MixerInput::RemoveInputChannelDesignation(int channel, uint32 des)
1942e9d6607Sbeveloper {
1952e9d6607Sbeveloper 	ASSERT(count_nonzero_bits(des) == 1);
1962e9d6607Sbeveloper 
1972e9d6607Sbeveloper 	// test if the channel is valid
1982e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
1992e9d6607Sbeveloper 		return;
2002e9d6607Sbeveloper 
2012e9d6607Sbeveloper 	// test if it is really set
2022e9d6607Sbeveloper 	if ((fInputChannelInfo[channel].designations & des) == 0)
2032e9d6607Sbeveloper 		return;
2042e9d6607Sbeveloper 
2052e9d6607Sbeveloper 	// remove it from specified channel
2062e9d6607Sbeveloper 	fInputChannelInfo[channel].designations &= ~des;
2072e9d6607Sbeveloper 
2082e9d6607Sbeveloper 	fUserOverridesChannelDesignations = true;
2092e9d6607Sbeveloper 	UpdateMixerChannels();
2102e9d6607Sbeveloper }
2112e9d6607Sbeveloper 
2122e9d6607Sbeveloper uint32
2132e9d6607Sbeveloper MixerInput::GetInputChannelDesignations(int channel)
2142e9d6607Sbeveloper {
2152e9d6607Sbeveloper 	// test if the channel is valid
2162e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
2172e9d6607Sbeveloper 		return 0;
2182e9d6607Sbeveloper 	return fInputChannelInfo[channel].designations;
2192e9d6607Sbeveloper }
2202e9d6607Sbeveloper 
2212e9d6607Sbeveloper uint32
2222e9d6607Sbeveloper MixerInput::GetInputChannelType(int channel)
2232e9d6607Sbeveloper {
2242e9d6607Sbeveloper 	// test if the channel is valid
2252e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
2262e9d6607Sbeveloper 		return 0;
2272e9d6607Sbeveloper 	return GetChannelMask(channel, fInputChannelMask);
2282e9d6607Sbeveloper }
2292e9d6607Sbeveloper 
2302e9d6607Sbeveloper void
2312e9d6607Sbeveloper MixerInput::SetInputChannelGain(int channel, float gain)
2322e9d6607Sbeveloper {
2332e9d6607Sbeveloper 	// test if the channel is valid
2342e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
2352e9d6607Sbeveloper 		return;
2362e9d6607Sbeveloper 	if (gain < 0.0f)
2372e9d6607Sbeveloper 		gain = 0.0f;
2382e9d6607Sbeveloper 
2392e9d6607Sbeveloper 	fInputChannelInfo[channel].gain = gain;
2402e9d6607Sbeveloper }
2412e9d6607Sbeveloper 
2422e9d6607Sbeveloper float
2432e9d6607Sbeveloper MixerInput::GetInputChannelGain(int channel)
2442e9d6607Sbeveloper {
2452e9d6607Sbeveloper 	// test if the channel is valid
2462e9d6607Sbeveloper 	if (channel < 0 || channel >= fInputChannelCount)
2472e9d6607Sbeveloper 		return 0.0f;
2482e9d6607Sbeveloper 	return fInputChannelInfo[channel].gain;
2492e9d6607Sbeveloper }
2502e9d6607Sbeveloper 
2512e9d6607Sbeveloper void
2522e9d6607Sbeveloper MixerInput::UpdateChannelDesignations()
2532e9d6607Sbeveloper {
2542e9d6607Sbeveloper 	// is the user already messed with the assignmens, don't do anything.
2552e9d6607Sbeveloper 	if (fUserOverridesChannelDesignations)
2562e9d6607Sbeveloper 		return;
2572e9d6607Sbeveloper 
2582e9d6607Sbeveloper 	printf("UpdateChannelDesignations: enter\n");
2592e9d6607Sbeveloper 
2602e9d6607Sbeveloper 	if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
2612e9d6607Sbeveloper 		// a left or right channel get's output as stereo on both
2622e9d6607Sbeveloper 		fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
2632e9d6607Sbeveloper 	} else {
2642e9d6607Sbeveloper 		// everything else get's mapped 1:1
2652e9d6607Sbeveloper 		for (int i = 0; i < fInputChannelCount; i++)
2662e9d6607Sbeveloper 			fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask);
2672e9d6607Sbeveloper 	}
2682e9d6607Sbeveloper 
2692e9d6607Sbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
2702e9d6607Sbeveloper 		printf("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
2712e9d6607Sbeveloper 
2722e9d6607Sbeveloper 	printf("UpdateChannelDesignations: enter\n");
2732e9d6607Sbeveloper }
2742e9d6607Sbeveloper 
2752e9d6607Sbeveloper void
2762e9d6607Sbeveloper MixerInput::UpdateMixerChannels()
2772e9d6607Sbeveloper {
2782e9d6607Sbeveloper 	uint32 channel_count;
2792e9d6607Sbeveloper 	uint32 all_bits;
2802e9d6607Sbeveloper 	uint32 mask;
2812e9d6607Sbeveloper 
2822e9d6607Sbeveloper 	mixer_chan_info *old_mixer_channel_info;
2832e9d6607Sbeveloper 	uint32 old_mixer_channel_count;
2842e9d6607Sbeveloper 
2852e9d6607Sbeveloper 	ASSERT(fMixBuffer);
2862e9d6607Sbeveloper 
2872e9d6607Sbeveloper 	printf("UpdateMixerChannels: enter\n");
2882e9d6607Sbeveloper 
2892e9d6607Sbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
2902e9d6607Sbeveloper 		printf("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
2912e9d6607Sbeveloper 
2922e9d6607Sbeveloper 	all_bits = 0;
2932e9d6607Sbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
2942e9d6607Sbeveloper 		all_bits |= fInputChannelInfo[i].designations;
2952e9d6607Sbeveloper 
2962e9d6607Sbeveloper 	printf("UpdateMixerChannels: all_bits = %08x\n", all_bits);
2972e9d6607Sbeveloper 
2982e9d6607Sbeveloper 	channel_count = count_nonzero_bits(all_bits);
2992e9d6607Sbeveloper 
3002e9d6607Sbeveloper 	printf("UpdateMixerChannels: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount);
3012e9d6607Sbeveloper 
3022e9d6607Sbeveloper 	// If we resize the channel info array, we preserve the gain setting
3032e9d6607Sbeveloper 	// by saving the old array until new assignments are finished, and
3042e9d6607Sbeveloper 	// then applying the old gains. New gains are set to 1.0
3052e9d6607Sbeveloper 	if (channel_count != fMixerChannelCount) {
3062e9d6607Sbeveloper 		old_mixer_channel_info = fMixerChannelInfo;
3072e9d6607Sbeveloper 		old_mixer_channel_count = fMixerChannelCount;
3082e9d6607Sbeveloper 		fMixerChannelInfo = new mixer_chan_info[channel_count];
3092e9d6607Sbeveloper 		fMixerChannelCount = channel_count;
3102e9d6607Sbeveloper 		for (int i = 0; i < fMixerChannelCount; i++)
3112e9d6607Sbeveloper 			fMixerChannelInfo[i].gain = 1.0;
3122e9d6607Sbeveloper 	} else {
3132e9d6607Sbeveloper 		old_mixer_channel_info = 0;
3142e9d6607Sbeveloper 		old_mixer_channel_count = 0;
3152e9d6607Sbeveloper 	}
3162e9d6607Sbeveloper 
3172e9d6607Sbeveloper 	// assign each mixer channel one type
3182e9d6607Sbeveloper 	for (int i  = 0, mask = 1; i < fMixerChannelCount; i++) {
3192e9d6607Sbeveloper 		while (mask != 0 && (all_bits & mask) == 0)
3202e9d6607Sbeveloper 			mask <<= 1;
321a4b8db85Sbeveloper 		fMixerChannelInfo[i].type = ChannelMaskToChannelType(mask);
3222e9d6607Sbeveloper 		mask <<= 1;
3232e9d6607Sbeveloper 	}
3242e9d6607Sbeveloper 
3252e9d6607Sbeveloper 	// assign buffer_base pointer for each mixer channel
3262e9d6607Sbeveloper 	for (int i  = 0; i < fMixerChannelCount; i++) {
3272e9d6607Sbeveloper 		int j;
3282e9d6607Sbeveloper 		for (j = 0; j < fInputChannelCount; j++) {
329a4b8db85Sbeveloper 			if (fInputChannelInfo[j].designations & ChannelTypeToChannelMask(fMixerChannelInfo[i].type)) {
3302e9d6607Sbeveloper 				fMixerChannelInfo[i].buffer_base = &fMixBuffer[j];
3312e9d6607Sbeveloper 				break;
3322e9d6607Sbeveloper 			}
3332e9d6607Sbeveloper 		}
3342e9d6607Sbeveloper 		if (j == fInputChannelCount) {
3352e9d6607Sbeveloper 			printf("buffer assignment failed for mixer chan %d\n", i);
3362e9d6607Sbeveloper 			fMixerChannelInfo[i].buffer_base = fMixBuffer;
3372e9d6607Sbeveloper 		}
3382e9d6607Sbeveloper 	}
3392e9d6607Sbeveloper 
3402e9d6607Sbeveloper 	// apply old gains, overriding the 1.0 defaults for the old channels
3412e9d6607Sbeveloper 	if (old_mixer_channel_info != 0) {
3422e9d6607Sbeveloper 		for (int i  = 0; i < fMixerChannelCount; i++) {
3432e9d6607Sbeveloper 			for (int j = 0; j < old_mixer_channel_count; j++) {
344a4b8db85Sbeveloper 				if (fMixerChannelInfo[i].type == old_mixer_channel_info[j].type) {
3452e9d6607Sbeveloper 					fMixerChannelInfo[i].gain = old_mixer_channel_info[j].gain;
3462e9d6607Sbeveloper 					break;
3472e9d6607Sbeveloper 				}
3482e9d6607Sbeveloper 			}
3492e9d6607Sbeveloper 		}
3502e9d6607Sbeveloper 		// also delete the old info array
3512e9d6607Sbeveloper 		delete [] old_mixer_channel_info;
3522e9d6607Sbeveloper 	}
3532e9d6607Sbeveloper 
3542e9d6607Sbeveloper 	for (int i = 0; i < fMixerChannelCount; i++)
355a4b8db85Sbeveloper 		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);
3562e9d6607Sbeveloper 
3572e9d6607Sbeveloper 	printf("UpdateMixerChannels: leave\n");
3582e9d6607Sbeveloper }
3592e9d6607Sbeveloper 
3602e9d6607Sbeveloper uint32
3612e9d6607Sbeveloper MixerInput::GetMixerChannelCount()
3622e9d6607Sbeveloper {
3632e9d6607Sbeveloper 	return fMixerChannelCount;
3642e9d6607Sbeveloper }
3652e9d6607Sbeveloper 
3662e9d6607Sbeveloper void
367*7b0daf5cSbeveloper MixerInput::GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain)
3682e9d6607Sbeveloper {
3692e9d6607Sbeveloper 	ASSERT(fMixBuffer);
3702e9d6607Sbeveloper 	ASSERT(channel >= 0 && channel < fMixerChannelCount);
371*7b0daf5cSbeveloper 	int32 offset = framepos % fMixBufferFrameCount;
372*7b0daf5cSbeveloper 	*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
3732e9d6607Sbeveloper 	*sample_offset = sizeof(float) * fInputChannelCount;
374a4b8db85Sbeveloper 	*type = fMixerChannelInfo[channel].type;
3752e9d6607Sbeveloper 	*gain = fMixerChannelInfo[channel].gain;
3762e9d6607Sbeveloper }
3772e9d6607Sbeveloper 
3782e9d6607Sbeveloper void
3792e9d6607Sbeveloper MixerInput::SetMixerChannelGain(int channel, float gain)
3802e9d6607Sbeveloper {
3812e9d6607Sbeveloper 	if (channel < 0 || channel >= fMixerChannelCount)
3822e9d6607Sbeveloper 		return;
3832e9d6607Sbeveloper 	if (gain < 0.0f)
3842e9d6607Sbeveloper 		gain = 0.0f;
3852e9d6607Sbeveloper 	fMixerChannelInfo[channel].gain = gain;
3862e9d6607Sbeveloper }
3872e9d6607Sbeveloper 
3882e9d6607Sbeveloper float
3892e9d6607Sbeveloper MixerInput::GetMixerChannelGain(int channel)
3902e9d6607Sbeveloper {
3912e9d6607Sbeveloper 	if (channel < 0 || channel >= fMixerChannelCount)
3922e9d6607Sbeveloper 		return 1.0;
3932e9d6607Sbeveloper 	return fMixerChannelInfo[channel].gain;
3942e9d6607Sbeveloper }
3952e9d6607Sbeveloper 
3962e9d6607Sbeveloper void
397*7b0daf5cSbeveloper MixerInput::SetMixBufferFormat(int32 framerate, int32 frames, bigtime_t starttime)
3982e9d6607Sbeveloper {
399*7b0daf5cSbeveloper 	fMixBufferFrameRate = framerate;
4002e9d6607Sbeveloper 	fMixBufferStartTime = starttime;
4012e9d6607Sbeveloper 
402*7b0daf5cSbeveloper 	printf("MixerInput::SetMixBufferFormat: framerate %ld, frames %ld, starttime %Ld\n", framerate, frames, starttime);
403*7b0daf5cSbeveloper 
404*7b0daf5cSbeveloper 	// make fMixBufferFrameCount an integral multiple of frames,
405*7b0daf5cSbeveloper 	// but at least 3 times duration of our input buffer
406*7b0daf5cSbeveloper 	// and at least 2 times duration of the output buffer
407*7b0daf5cSbeveloper 	bigtime_t inputBufferLength  = duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio));
408*7b0daf5cSbeveloper 	bigtime_t outputBufferLength = duration_for_frames(framerate, frames);
409*7b0daf5cSbeveloper 	bigtime_t mixerBufferLength = max_c(3 * inputBufferLength, 2 * outputBufferLength);
410*7b0daf5cSbeveloper 	int temp = frames_for_duration(framerate, mixerBufferLength);
411*7b0daf5cSbeveloper 	fMixBufferFrameCount = ((temp / frames) + 1) * frames;
412*7b0daf5cSbeveloper 
413*7b0daf5cSbeveloper 	printf("  inputBufferLength  %10Ld\n", inputBufferLength);
414*7b0daf5cSbeveloper 	printf("  outputBufferLength %10Ld\n", outputBufferLength);
415*7b0daf5cSbeveloper 	printf("  mixerBufferLength  %10Ld\n", mixerBufferLength);
416*7b0daf5cSbeveloper 	printf("  fMixBufferFrameCount   %10ld\n", fMixBufferFrameCount);
417*7b0daf5cSbeveloper 
4182e9d6607Sbeveloper 	if (fMixBuffer)
4192e9d6607Sbeveloper 		rtm_free(fMixBuffer);
420*7b0daf5cSbeveloper 	int size = sizeof(float) * fInputChannelCount * fMixBufferFrameCount;
421*7b0daf5cSbeveloper 	fMixBuffer = (float *)rtm_alloc(NULL, size);
422*7b0daf5cSbeveloper 	ASSERT(fMixBuffer);
423*7b0daf5cSbeveloper 
424*7b0daf5cSbeveloper 	memset(fMixBuffer, 0, size);
4252e9d6607Sbeveloper 
4262e9d6607Sbeveloper 	for (int i = 0; i < fInputChannelCount; i++)
427*7b0daf5cSbeveloper 		fInputChannelInfo[i].buffer_base = &fMixBuffer[i];
4282e9d6607Sbeveloper }
429