* Resolved TODO and implemented updating resampling implementation on the fly.

* Reordered some methods in the source to align with declaration order.
 * Applied naming conventions for private methods.
 * Switched asterix style in MixerInput.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38488 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2010-09-01 09:09:10 +00:00
parent e9ec3d5a49
commit b006bbe130
5 changed files with 198 additions and 151 deletions
@@ -1475,7 +1475,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when, const void *value,
if (size != sizeof(int32)) if (size != sizeof(int32))
goto err; goto err;
fCore->Settings()->SetResamplingAlgorithm(static_cast<const int32 *>(value)[0]); fCore->Settings()->SetResamplingAlgorithm(static_cast<const int32 *>(value)[0]);
// XXX tell the core to change the algorithm fCore->UpdateResamplingAlgorithm();
break; break;
case 80: // Refuse output format changes case 80: // Refuse output format changes
if (size != sizeof(int32)) if (size != sizeof(int32))
@@ -120,6 +120,21 @@ MixerCore::Settings()
} }
void
MixerCore::UpdateResamplingAlgorithm()
{
ASSERT_LOCKED();
_UpdateResamplers(fOutput->MediaOutput().format.u.raw_audio);
for (int32 i = fInputs->CountItems() - 1; i >= 0; i--) {
MixerInput* input
= reinterpret_cast<MixerInput*>(fInputs->ItemAtFast(i));
input->UpdateResamplingAlgorithm();
}
}
void void
MixerCore::SetOutputAttenuation(float gain) MixerCore::SetOutputAttenuation(float gain)
{ {
@@ -133,7 +148,7 @@ MixerCore::AddInput(const media_input& input)
{ {
ASSERT_LOCKED(); ASSERT_LOCKED();
MixerInput* in = new MixerInput(this, input, fMixBufferFrameRate, MixerInput* in = new MixerInput(this, input, fMixBufferFrameRate,
fMixBufferFrameCount, Settings()->ResamplingAlgorithm()); fMixBufferFrameCount);
fInputs->AddItem(in); fInputs->AddItem(in);
return in; return in;
} }
@@ -149,7 +164,7 @@ MixerCore::AddOutput(const media_output& output)
} }
fOutput = new MixerOutput(this, output); fOutput = new MixerOutput(this, output);
// the output format might have been adjusted inside MixerOutput // the output format might have been adjusted inside MixerOutput
ApplyOutputFormat(); _ApplyOutputFormat();
ASSERT(!fRunning); ASSERT(!fRunning);
if (fStarted && fOutputEnabled) if (fStarted && fOutputEnabled)
@@ -252,76 +267,13 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
Stop(); Stop();
fOutput->ChangeFormat(format); fOutput->ChangeFormat(format);
ApplyOutputFormat(); _ApplyOutputFormat();
if (was_started) if (was_started)
Start(); Start();
} }
void
MixerCore::ApplyOutputFormat()
{
ASSERT_LOCKED();
media_multi_audio_format format = fOutput->MediaOutput().format.u.raw_audio;
if (fMixBuffer != NULL)
rtm_free(fMixBuffer);
delete fMixBufferChannelTypes;
fMixBufferFrameRate = (int32)(0.5 + format.frame_rate);
fMixBufferFrameCount = frames_per_buffer(format);
if (fDoubleRateMixing) {
fMixBufferFrameRate *= 2;
fMixBufferFrameCount *= 2;
}
fMixBufferChannelCount = format.channel_count;
ASSERT(fMixBufferChannelCount == fOutput->GetOutputChannelCount());
fMixBufferChannelTypes = new int32 [format.channel_count];
for (int i = 0; i < fMixBufferChannelCount; i++) {
fMixBufferChannelTypes[i]
= ChannelMaskToChannelType(GetChannelMask(i, format.channel_mask));
}
fMixBuffer = (float*)rtm_alloc(NULL, sizeof(float) * fMixBufferFrameCount
* fMixBufferChannelCount);
ASSERT(fMixBuffer != NULL);
if (fResampler != NULL) {
for (int i = 0; i < fMixBufferChannelCount; i++)
delete fResampler[i];
delete[] fResampler;
}
fResampler = new Resampler*[fMixBufferChannelCount];
for (int i = 0; i < fMixBufferChannelCount; i++) {
switch (Settings()->ResamplingAlgorithm()) {
case 2:
fResampler[i] = new Interpolate(
media_raw_audio_format::B_AUDIO_FLOAT, format.format);
break;
default:
fResampler[i] = new Resampler(
media_raw_audio_format::B_AUDIO_FLOAT, format.format);
}
}
TRACE("MixerCore::OutputFormatChanged:\n");
TRACE(" fMixBufferFrameRate %ld\n", fMixBufferFrameRate);
TRACE(" fMixBufferFrameCount %ld\n", fMixBufferFrameCount);
TRACE(" fMixBufferChannelCount %ld\n", fMixBufferChannelCount);
for (int i = 0; i < fMixBufferChannelCount; i++)
TRACE(" fMixBufferChannelTypes[%i] %ld\n", i, fMixBufferChannelTypes[i]);
MixerInput *input;
for (int i = 0; (input = Input(i)); i++)
input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount);
}
void void
MixerCore::SetOutputBufferGroup(BBufferGroup *group) MixerCore::SetOutputBufferGroup(BBufferGroup *group)
{ {
@@ -411,8 +363,8 @@ MixerCore::StartMixThread()
ASSERT(fOutput); ASSERT(fOutput);
fRunning = true; fRunning = true;
fMixThreadWaitSem = create_sem(0, "mix thread wait"); fMixThreadWaitSem = create_sem(0, "mix thread wait");
fMixThread = spawn_thread(MixThreadEntry, "Yeah baby, very shagadelic", 120, fMixThread = spawn_thread(_MixThreadEntry, "Yeah baby, very shagadelic",
this); 120, this);
resume_thread(fMixThread); resume_thread(fMixThread);
} }
@@ -434,16 +386,92 @@ MixerCore::StopMixThread()
} }
int32 // #pragma mark - private
MixerCore::MixThreadEntry(void* arg)
void
MixerCore::_UpdateResamplers(const media_multi_audio_format& format)
{ {
static_cast<MixerCore*>(arg)->MixThread(); ASSERT_LOCKED();
if (fResampler != NULL) {
for (int i = 0; i < fMixBufferChannelCount; i++)
delete fResampler[i];
delete[] fResampler;
}
fResampler = new Resampler*[fMixBufferChannelCount];
for (int i = 0; i < fMixBufferChannelCount; i++) {
switch (Settings()->ResamplingAlgorithm()) {
case 2:
fResampler[i] = new Interpolate(
media_raw_audio_format::B_AUDIO_FLOAT, format.format);
break;
default:
fResampler[i] = new Resampler(
media_raw_audio_format::B_AUDIO_FLOAT, format.format);
}
}
}
void
MixerCore::_ApplyOutputFormat()
{
ASSERT_LOCKED();
const media_multi_audio_format& format
= fOutput->MediaOutput().format.u.raw_audio;
if (fMixBuffer != NULL)
rtm_free(fMixBuffer);
delete fMixBufferChannelTypes;
fMixBufferFrameRate = (int32)(0.5 + format.frame_rate);
fMixBufferFrameCount = frames_per_buffer(format);
if (fDoubleRateMixing) {
fMixBufferFrameRate *= 2;
fMixBufferFrameCount *= 2;
}
fMixBufferChannelCount = format.channel_count;
ASSERT(fMixBufferChannelCount == fOutput->GetOutputChannelCount());
fMixBufferChannelTypes = new int32 [format.channel_count];
for (int i = 0; i < fMixBufferChannelCount; i++) {
fMixBufferChannelTypes[i]
= ChannelMaskToChannelType(GetChannelMask(i, format.channel_mask));
}
fMixBuffer = (float*)rtm_alloc(NULL, sizeof(float) * fMixBufferFrameCount
* fMixBufferChannelCount);
ASSERT(fMixBuffer != NULL);
_UpdateResamplers(format);
TRACE("MixerCore::OutputFormatChanged:\n");
TRACE(" fMixBufferFrameRate %ld\n", fMixBufferFrameRate);
TRACE(" fMixBufferFrameCount %ld\n", fMixBufferFrameCount);
TRACE(" fMixBufferChannelCount %ld\n", fMixBufferChannelCount);
for (int i = 0; i < fMixBufferChannelCount; i++)
TRACE(" fMixBufferChannelTypes[%i] %ld\n", i, fMixBufferChannelTypes[i]);
MixerInput *input;
for (int i = 0; (input = Input(i)); i++)
input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount);
}
int32
MixerCore::_MixThreadEntry(void* arg)
{
static_cast<MixerCore*>(arg)->_MixThread();
return 0; return 0;
} }
void void
MixerCore::MixThread() MixerCore::_MixThread()
{ {
// The broken BeOS R5 multiaudio node starts with time 0, // The broken BeOS R5 multiaudio node starts with time 0,
// then publishes negative times for about 50ms, publishes 0 // then publishes negative times for about 50ms, publishes 0
@@ -453,7 +481,7 @@ MixerCore::MixThread()
bigtime_t start = fTimeSource->Now(); bigtime_t start = fTimeSource->Now();
Unlock(); Unlock();
while (start <= 0) { while (start <= 0) {
TRACE("MixerCore: delaying MixThread start, timesource is at %Ld\n", TRACE("MixerCore: delaying _MixThread start, timesource is at %Ld\n",
start); start);
snooze(5000); snooze(5000);
if (!LockFromMixThread()) if (!LockFromMixThread())
@@ -471,7 +499,7 @@ MixerCore::MixThread()
bigtime_t bufferRequestTimeout = buffer_duration( bigtime_t bufferRequestTimeout = buffer_duration(
fOutput->MediaOutput().format.u.raw_audio) / 2; fOutput->MediaOutput().format.u.raw_audio) / 2;
TRACE("MixerCore: starting MixThread at %Ld with latency %Ld and " TRACE("MixerCore: starting _MixThread at %Ld with latency %Ld and "
"downstream latency %Ld, bufferRequestTimeout %Ld\n", start, latency, "downstream latency %Ld, bufferRequestTimeout %Ld\n", start, latency,
fDownstreamLatency, bufferRequestTimeout); fDownstreamLatency, bufferRequestTimeout);
@@ -483,7 +511,7 @@ MixerCore::MixThread()
bigtime_t timeBase = duration_for_frames(fMixBufferFrameRate, frameBase); bigtime_t timeBase = duration_for_frames(fMixBufferFrameRate, frameBase);
Unlock(); Unlock();
TRACE("MixerCore: starting MixThread, start %Ld, timeBase %Ld, " TRACE("MixerCore: starting _MixThread, start %Ld, timeBase %Ld, "
"frameBase %Ld\n", start, timeBase, frameBase); "frameBase %Ld\n", start, timeBase, frameBase);
ASSERT(fMixBufferFrameCount > 0); ASSERT(fMixBufferFrameCount > 0);
@@ -603,13 +631,13 @@ MixerCore::MixThread()
memset(fMixBuffer, 0, memset(fMixBuffer, 0,
fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float)); fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float));
for (int channel = 0; channel < fMixBufferChannelCount; channel++) { for (int channel = 0; channel < fMixBufferChannelCount; channel++) {
PRINT(5, "MixThread: channel %d has %d sources\n", channel, PRINT(5, "_MixThread: channel %d has %d sources\n", channel,
mixChanInfos[channel].CountItems()); mixChanInfos[channel].CountItems());
int count = mixChanInfos[channel].CountItems(); int count = mixChanInfos[channel].CountItems();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
chan_info* info = mixChanInfos[channel].ItemAt(i); chan_info* info = mixChanInfos[channel].ItemAt(i);
PRINT(5, "MixThread: base %p, sample-offset %2d, gain %.3f\n", PRINT(5, "_MixThread: base %p, sample-offset %2d, gain %.3f\n",
info->base, info->sample_offset, info->gain); info->base, info->sample_offset, info->gain);
// This looks slightly ugly, but the current GCC will generate // This looks slightly ugly, but the current GCC will generate
// the fastest code this way. // the fastest code this way.
@@ -36,6 +36,7 @@ public:
virtual ~MixerCore(); virtual ~MixerCore();
MixerSettings* Settings(); MixerSettings* Settings();
void UpdateResamplingAlgorithm();
// To avoid calling Settings()->AttenuateOutput() for every outgoing // To avoid calling Settings()->AttenuateOutput() for every outgoing
// buffer, this setting is cached in fOutputGain and must be set by // buffer, this setting is cached in fOutputGain and must be set by
@@ -77,9 +78,11 @@ public:
uint32 OutputChannelCount(); uint32 OutputChannelCount();
private: private:
void ApplyOutputFormat(); void _UpdateResamplers(
static int32 MixThreadEntry(void* arg); const media_multi_audio_format& format);
void MixThread(); void _ApplyOutputFormat();
static int32 _MixThreadEntry(void* arg);
void _MixThread();
private: private:
BLocker* fLocker; BLocker* fLocker;
@@ -20,26 +20,26 @@
#include "Resampler.h" #include "Resampler.h"
MixerInput::MixerInput(MixerCore *core, const media_input &input, MixerInput::MixerInput(MixerCore* core, const media_input& input,
float mixFrameRate, int32 mixFrameCount, int resamplingAlgorithm) float mixFrameRate, int32 mixFrameCount)
: :
fCore(core), fCore(core),
fInput(input), fInput(input),
fInputByteSwap(0), fInputByteSwap(NULL),
fEnabled(true), fEnabled(true),
fInputChannelInfo(0), fInputChannelInfo(NULL),
fInputChannelCount(0), fInputChannelCount(0),
fInputChannelMask(0), fInputChannelMask(0),
fMixerChannelInfo(0), fMixerChannelInfo(0),
fMixerChannelCount(0), fMixerChannelCount(0),
fMixBuffer(0), fMixBuffer(NULL),
fMixBufferFrameRate(0), fMixBufferFrameRate(0),
fMixBufferFrameCount(0), fMixBufferFrameCount(0),
fLastDataFrameWritten(-1), fLastDataFrameWritten(-1),
fLastDataAvailableTime(-1), fLastDataAvailableTime(-1),
fFractionalFrames(0.0), fFractionalFrames(0.0),
fResampler(0), fResampler(NULL),
fRtmPool(0), fRtmPool(NULL),
fUserOverridesChannelDestinations(false) fUserOverridesChannelDestinations(false)
{ {
fix_multiaudio_format(&fInput.format.u.raw_audio); fix_multiaudio_format(&fInput.format.u.raw_audio);
@@ -72,28 +72,14 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input,
fInputChannelInfo[i].buffer_base = 0; fInputChannelInfo[i].buffer_base = 0;
// will be set by SetMixBufferFormat() // will be set by SetMixBufferFormat()
fInputChannelInfo[i].destination_mask = 0; fInputChannelInfo[i].destination_mask = 0;
// will be set by UpdateInputChannelDestinationMask() // will be set by _UpdateInputChannelDestinationMask()
fInputChannelInfo[i].gain = 1.0; fInputChannelInfo[i].gain = 1.0;
} }
// create resamplers UpdateResamplingAlgorithm();
fResampler = new Resampler * [fInputChannelCount];
for (int i = 0; i < fInputChannelCount; i++) {
switch (resamplingAlgorithm) {
case 2:
fResampler[i] = new Interpolate(
fInput.format.u.raw_audio.format,
media_raw_audio_format::B_AUDIO_FLOAT);
break;
default:
fResampler[i] = new Resampler(
fInput.format.u.raw_audio.format,
media_raw_audio_format::B_AUDIO_FLOAT);
}
}
// fMixerChannelInfo and fMixerChannelCount will be initialized by // fMixerChannelInfo and fMixerChannelCount will be initialized by
// UpdateInputChannelDestinations() // _UpdateInputChannelDestinations()
SetMixBufferFormat((int32)mixFrameRate, mixFrameCount); SetMixBufferFormat((int32)mixFrameRate, mixFrameCount);
} }
@@ -104,21 +90,37 @@ MixerInput::~MixerInput()
rtm_free(fMixBuffer); rtm_free(fMixBuffer);
if (fRtmPool) if (fRtmPool)
rtm_delete_pool(fRtmPool); rtm_delete_pool(fRtmPool);
delete [] fInputChannelInfo; delete[] fInputChannelInfo;
delete [] fMixerChannelInfo; delete[] fMixerChannelInfo;
// delete resamplers // delete resamplers
for (int i = 0; i < fInputChannelCount; i++) if (fResampler != NULL) {
delete fResampler[i]; for (int i = 0; i < fInputChannelCount; i++)
delete [] fResampler; delete fResampler[i];
delete[] fResampler;
}
delete fInputByteSwap; delete fInputByteSwap;
} }
void int32
MixerInput::BufferReceived(BBuffer *buffer) MixerInput::ID()
{ {
void *data; return fInput.destination.id;
}
media_input&
MixerInput::MediaInput()
{
return fInput;
}
void
MixerInput::BufferReceived(BBuffer* buffer)
{
void* data;
size_t size; size_t size;
bigtime_t start; bigtime_t start;
bigtime_t buffer_duration; bigtime_t buffer_duration;
@@ -255,19 +257,19 @@ MixerInput::BufferReceived(BBuffer *buffer)
for (int i = 0; i < fInputChannelCount; i++) { for (int i = 0; i < fInputChannelCount; i++) {
fResampler[i]->Resample( fResampler[i]->Resample(
reinterpret_cast<char *>(data) reinterpret_cast<char*>(data)
+ i * bytes_per_sample(fInput.format.u.raw_audio), + i * bytes_per_sample(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio), in_frames1, bytes_per_frame(fInput.format.u.raw_audio), in_frames1,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) reinterpret_cast<char*>(fInputChannelInfo[i].buffer_base)
+ offset, fInputChannelCount * sizeof(float), out_frames1, + offset, fInputChannelCount * sizeof(float), out_frames1,
fInputChannelInfo[i].gain); fInputChannelInfo[i].gain);
fResampler[i]->Resample( fResampler[i]->Resample(
reinterpret_cast<char *>(data) reinterpret_cast<char*>(data)
+ i * bytes_per_sample(fInput.format.u.raw_audio) + i * bytes_per_sample(fInput.format.u.raw_audio)
+ in_frames1 * bytes_per_frame(fInput.format.u.raw_audio), + in_frames1 * bytes_per_frame(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio), in_frames2, bytes_per_frame(fInput.format.u.raw_audio), in_frames2,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base), reinterpret_cast<char*>(fInputChannelInfo[i].buffer_base),
fInputChannelCount * sizeof(float), out_frames2, fInputChannelCount * sizeof(float), out_frames2,
fInputChannelInfo[i].gain); fInputChannelInfo[i].gain);
@@ -290,10 +292,10 @@ MixerInput::BufferReceived(BBuffer *buffer)
offset *= sizeof(float) * fInputChannelCount; offset *= sizeof(float) * fInputChannelCount;
for (int i = 0; i < fInputChannelCount; i++) { for (int i = 0; i < fInputChannelCount; i++) {
fResampler[i]->Resample( fResampler[i]->Resample(
reinterpret_cast<char *>(data) reinterpret_cast<char*>(data)
+ i * bytes_per_sample(fInput.format.u.raw_audio), + i * bytes_per_sample(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio), in_frames, bytes_per_frame(fInput.format.u.raw_audio), in_frames,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) reinterpret_cast<char*>(fInputChannelInfo[i].buffer_base)
+ offset, fInputChannelCount * sizeof(float), + offset, fInputChannelCount * sizeof(float),
out_frames, fInputChannelInfo[i].gain); out_frames, fInputChannelInfo[i].gain);
} }
@@ -302,17 +304,29 @@ MixerInput::BufferReceived(BBuffer *buffer)
} }
media_input & void
MixerInput::MediaInput() MixerInput::UpdateResamplingAlgorithm()
{ {
return fInput; if (fResampler != NULL) {
} for (int i = 0; i < fInputChannelCount; i++)
delete fResampler[i];
delete[] fResampler;
int32 }
MixerInput::ID() // create resamplers
{ fResampler = new Resampler*[fInputChannelCount];
return fInput.destination.id; for (int i = 0; i < fInputChannelCount; i++) {
switch (fCore->Settings()->ResamplingAlgorithm()) {
case 2:
fResampler[i] = new Interpolate(
fInput.format.u.raw_audio.format,
media_raw_audio_format::B_AUDIO_FLOAT);
break;
default:
fResampler[i] = new Resampler(
fInput.format.u.raw_audio.format,
media_raw_audio_format::B_AUDIO_FLOAT);
}
}
} }
@@ -347,7 +361,7 @@ MixerInput::AddInputChannelDestination(int channel, int destination_type)
fInputChannelInfo[channel].destination_mask |= mask; fInputChannelInfo[channel].destination_mask |= mask;
fUserOverridesChannelDestinations = true; fUserOverridesChannelDestinations = true;
UpdateInputChannelDestinations(); _UpdateInputChannelDestinations();
} }
@@ -367,7 +381,7 @@ MixerInput::RemoveInputChannelDestination(int channel, int destination_type)
fInputChannelInfo[channel].destination_mask &= ~mask; fInputChannelInfo[channel].destination_mask &= ~mask;
fUserOverridesChannelDestinations = true; fUserOverridesChannelDestinations = true;
UpdateInputChannelDestinations(); _UpdateInputChannelDestinations();
} }
@@ -428,13 +442,13 @@ MixerInput::GetInputChannelGain(int channel)
void void
MixerInput::UpdateInputChannelDestinationMask() MixerInput::_UpdateInputChannelDestinationMask()
{ {
// is the user already messed with the assignmens, don't do anything. // is the user already messed with the assignmens, don't do anything.
if (fUserOverridesChannelDestinations) if (fUserOverridesChannelDestinations)
return; return;
TRACE("UpdateInputChannelDestinationMask: enter\n"); TRACE("_UpdateInputChannelDestinationMask: enter\n");
// first apply a 1:1 mapping // first apply a 1:1 mapping
for (int i = 0; i < fInputChannelCount; i++) { for (int i = 0; i < fInputChannelCount; i++) {
@@ -480,25 +494,25 @@ MixerInput::UpdateInputChannelDestinationMask()
} }
for (int i = 0; i < fInputChannelCount; i++) { for (int i = 0; i < fInputChannelCount; i++) {
TRACE("UpdateInputChannelDestinationMask: input channel %d, " TRACE("_UpdateInputChannelDestinationMask: input channel %d, "
"destination_mask 0x%08lX, base %p, gain %.3f\n", i, "destination_mask 0x%08lX, base %p, gain %.3f\n", i,
fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].destination_mask,
fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
} }
TRACE("UpdateInputChannelDestinationMask: leave\n"); TRACE("_UpdateInputChannelDestinationMask: leave\n");
} }
void void
MixerInput::UpdateInputChannelDestinations() MixerInput::_UpdateInputChannelDestinations()
{ {
int channel_count; int channel_count;
uint32 all_bits; uint32 all_bits;
uint32 mask; uint32 mask;
TRACE("UpdateInputChannelDestinations: enter\n"); TRACE("_UpdateInputChannelDestinations: enter\n");
for (int i = 0; i < fInputChannelCount; i++) { for (int i = 0; i < fInputChannelCount; i++) {
TRACE("UpdateInputChannelDestinations: input channel %d, " TRACE("_UpdateInputChannelDestinations: input channel %d, "
"destination_mask 0x%08lX, base %p, gain %.3f\n", i, "destination_mask 0x%08lX, base %p, gain %.3f\n", i,
fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].destination_mask,
fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain); fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
@@ -508,10 +522,10 @@ MixerInput::UpdateInputChannelDestinations()
for (int i = 0; i < fInputChannelCount; i++) for (int i = 0; i < fInputChannelCount; i++)
all_bits |= fInputChannelInfo[i].destination_mask; all_bits |= fInputChannelInfo[i].destination_mask;
TRACE("UpdateInputChannelDestinations: all_bits = %08lx\n", all_bits); TRACE("_UpdateInputChannelDestinations: all_bits = %08lx\n", all_bits);
channel_count = count_nonzero_bits(all_bits); channel_count = count_nonzero_bits(all_bits);
TRACE("UpdateInputChannelDestinations: %d input channels, %d mixer " TRACE("_UpdateInputChannelDestinations: %d input channels, %d mixer "
"channels (%d old)\n", fInputChannelCount, channel_count, "channels (%d old)\n", fInputChannelCount, channel_count,
fMixerChannelCount); fMixerChannelCount);
if (channel_count != fMixerChannelCount) { if (channel_count != fMixerChannelCount) {
@@ -551,13 +565,13 @@ MixerInput::UpdateInputChannelDestinations()
} }
for (int i = 0; i < fMixerChannelCount; i++) { for (int i = 0; i < fMixerChannelCount; i++) {
TRACE("UpdateInputChannelDestinations: mixer channel %d, type %2d, " TRACE("_UpdateInputChannelDestinations: mixer channel %d, type %2d, "
"base %p, gain %.3f\n", i, fMixerChannelInfo[i].destination_type, "base %p, gain %.3f\n", i, fMixerChannelInfo[i].destination_type,
fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].buffer_base,
fMixerChannelInfo[i].destination_gain); fMixerChannelInfo[i].destination_gain);
} }
TRACE("UpdateInputChannelDestinations: leave\n"); TRACE("_UpdateInputChannelDestinations: leave\n");
} }
@@ -668,8 +682,8 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
fInputChannelInfo[i].buffer_base = 0; fInputChannelInfo[i].buffer_base = 0;
fMixBufferFrameCount = 0; fMixBufferFrameCount = 0;
UpdateInputChannelDestinationMask(); _UpdateInputChannelDestinationMask();
UpdateInputChannelDestinations(); _UpdateInputChannelDestinations();
return; return;
} }
@@ -711,6 +725,6 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
for (int i = 0; i < fInputChannelCount; i++) for (int i = 0; i < fInputChannelCount; i++)
fInputChannelInfo[i].buffer_base = &fMixBuffer[i]; fInputChannelInfo[i].buffer_base = &fMixBuffer[i];
UpdateInputChannelDestinationMask(); _UpdateInputChannelDestinationMask();
UpdateInputChannelDestinations(); _UpdateInputChannelDestinations();
} }
@@ -25,14 +25,16 @@ class MixerInput {
public: public:
MixerInput(MixerCore* core, MixerInput(MixerCore* core,
const media_input& input, const media_input& input,
float mixFrameRate, int32 mixFrameCount, float mixFrameRate, int32 mixFrameCount);
int resamplingAlgorithm);
~MixerInput(); ~MixerInput();
int32 ID(); int32 ID();
void BufferReceived(BBuffer* buffer);
media_input& MediaInput(); media_input& MediaInput();
void BufferReceived(BBuffer* buffer);
void UpdateResamplingAlgorithm();
// The physical input channels // The physical input channels
int GetInputChannelCount(); int GetInputChannelCount();
int GetInputChannelType(int channel); int GetInputChannelType(int channel);
@@ -74,8 +76,8 @@ protected:
int32 frames); int32 frames);
private: private:
void UpdateInputChannelDestinationMask(); void _UpdateInputChannelDestinationMask();
void UpdateInputChannelDestinations(); void _UpdateInputChannelDestinations();
struct input_chan_info { struct input_chan_info {
float* buffer_base; float* buffer_base;