Fixed some debug macros.
Cleanup of MixerInput class. Implemented output destination mapping controls. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3819 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3161d380ef
commit
9c3be6a557
@ -883,7 +883,7 @@ status_t
|
||||
AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
|
||||
void *value, size_t *ioSize)
|
||||
{
|
||||
TRACE("GetParameterValue: id %ld, ioSize %ld\n", id, *ioSize);
|
||||
TRACE("GetParameterValue: id 0x%08x, ioSize %ld\n", id, *ioSize);
|
||||
int param = PARAM(id);
|
||||
fCore->Lock();
|
||||
if (param == 0) {
|
||||
@ -922,7 +922,7 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
|
||||
for (int i = 0; (input = fCore->Input(i)); i++)
|
||||
if (input->ID() == param)
|
||||
break;
|
||||
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !input)
|
||||
if (!input || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_DST_ENABLE(id) && !PARAM_IS_DST_GAIN(id)))
|
||||
goto err;
|
||||
if (PARAM_IS_MUTE(id)) {
|
||||
// input mute control
|
||||
@ -939,6 +939,18 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
|
||||
for (int chan = 0; chan < input->GetInputChannelCount(); chan++)
|
||||
static_cast<float *>(value)[chan] = DB_TO_GAIN(input->GetInputChannelGain(chan));
|
||||
}
|
||||
if (PARAM_IS_DST_ENABLE(id)) {
|
||||
if (*ioSize < sizeof(int32))
|
||||
goto err;
|
||||
*ioSize = sizeof(int32);
|
||||
static_cast<int32 *>(value)[0] = input->HasInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
|
||||
}
|
||||
if (PARAM_IS_DST_GAIN(id)) {
|
||||
if (*ioSize < sizeof(float))
|
||||
goto err;
|
||||
*ioSize = sizeof(float);
|
||||
static_cast<float *>(value)[0] = GAIN_TO_PERCENT(input->GetInputChannelDestinationGain(PARAM_CHAN(id), PARAM_DST(id)));
|
||||
}
|
||||
}
|
||||
*last_change = TimeSource()->Now(); // XXX we could do better
|
||||
fCore->Unlock();
|
||||
@ -952,7 +964,7 @@ void
|
||||
AudioMixer::SetParameterValue(int32 id, bigtime_t when,
|
||||
const void *value, size_t size)
|
||||
{
|
||||
TRACE("SetParameterValue: id %ld, size %ld\n", id, size);
|
||||
TRACE("SetParameterValue: id 0x%08x, size %ld\n", id, size);
|
||||
int param = PARAM(id);
|
||||
fCore->Lock();
|
||||
if (param == 0) {
|
||||
@ -991,7 +1003,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
|
||||
for (int i = 0; (input = fCore->Input(i)); i++)
|
||||
if (input->ID() == param)
|
||||
break;
|
||||
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !input)
|
||||
if (!input || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_DST_ENABLE(id) && !PARAM_IS_DST_GAIN(id)))
|
||||
goto err;
|
||||
if (PARAM_IS_MUTE(id)) {
|
||||
// input mute control
|
||||
@ -1006,6 +1018,34 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
|
||||
for (int chan = 0; chan < input->GetInputChannelCount(); chan++)
|
||||
input->SetInputChannelGain(chan, GAIN_TO_DB(static_cast<const float *>(value)[chan]));
|
||||
}
|
||||
if (PARAM_IS_DST_ENABLE(id)) {
|
||||
if (size != sizeof(int32))
|
||||
goto err;
|
||||
if (static_cast<const int32 *>(value)[0]) {
|
||||
int oldchan = input->GetInputChannelForDestination(PARAM_DST(id));
|
||||
if (oldchan != -1) {
|
||||
input->RemoveInputChannelDestination(oldchan, PARAM_DST(id));
|
||||
int32 null = 0;
|
||||
BroadcastNewParameterValue(when, PARAM_DST_ENABLE(PARAM(id), oldchan, PARAM_DST(id)), &null, sizeof(null));
|
||||
}
|
||||
input->AddInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
|
||||
} else {
|
||||
input->RemoveInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
|
||||
}
|
||||
}
|
||||
if (PARAM_IS_DST_GAIN(id)) {
|
||||
if (size != sizeof(float))
|
||||
goto err;
|
||||
input->SetInputChannelDestinationGain(PARAM_CHAN(id), PARAM_DST(id), PERCENT_TO_GAIN(static_cast<const float *>(value)[0]));
|
||||
// We have an ugly display where each destination gain slider
|
||||
// is diplayed for each input channel.
|
||||
// Update all other sliders for this destination type
|
||||
for (int chan = 0; chan < input->GetInputChannelCount(); chan++) {
|
||||
if (PARAM_CHAN(id) == chan)
|
||||
continue;
|
||||
BroadcastNewParameterValue(when, PARAM_DST_GAIN(PARAM(id), chan, PARAM_DST(id)), const_cast<void *>(value), size);
|
||||
}
|
||||
}
|
||||
}
|
||||
BroadcastNewParameterValue(when, id, const_cast<void *>(value), size);
|
||||
err:
|
||||
@ -1077,10 +1117,10 @@ AudioMixer::UpdateParameterWeb()
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
top = web->MakeGroup("Input Mapping"); // top level group
|
||||
inputchannels = top->MakeGroup("");
|
||||
inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC);
|
||||
// inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC);
|
||||
inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations (PREVIEW; DISPLAYS ONLY ONE CONNECTED INPUT)", B_GENERIC);
|
||||
|
||||
// for (int i = 0; (in = fCore->Input(i)); i++) {
|
||||
if ((in = fCore->Input(1)) || (in = fCore->Input(0))) { // XXX limited to input 1 or 0 to aviod BSlider problems
|
||||
@ -1101,7 +1141,6 @@ AudioMixer::UpdateParameterWeb()
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fCore->Unlock();
|
||||
|
||||
|
@ -24,7 +24,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
|
||||
fLastDataAvailableTime(-1),
|
||||
fResampler(0),
|
||||
fRtmPool(0),
|
||||
fUserOverridesChannelDesignations(false)
|
||||
fUserOverridesChannelDestinations(false)
|
||||
{
|
||||
fix_multiaudio_format(&fInput.format.u.raw_audio);
|
||||
PRINT_INPUT("MixerInput::MixerInput", fInput);
|
||||
@ -32,6 +32,9 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
|
||||
|
||||
ASSERT(fInput.format.u.raw_audio.channel_count > 0);
|
||||
|
||||
for (int i = 0; i < MAX_CHANNEL_TYPES; i++)
|
||||
fChannelTypeGain[i] = 1.0f;
|
||||
|
||||
fInputChannelCount = fInput.format.u.raw_audio.channel_count;
|
||||
fInputChannelMask = fInput.format.u.raw_audio.channel_mask;
|
||||
fInputChannelInfo = new input_chan_info[fInputChannelCount];
|
||||
@ -48,7 +51,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
|
||||
// initialize fInputChannelInfo
|
||||
for (int i = 0; i < fInputChannelCount; i++) {
|
||||
fInputChannelInfo[i].buffer_base = 0; // will be set by SetMixBufferFormat()
|
||||
fInputChannelInfo[i].designations = 0; // will be set by UpdateChannelDesignations()
|
||||
fInputChannelInfo[i].destination_mask = 0; // will be set by UpdateInputChannelDestinationMask()
|
||||
fInputChannelInfo[i].gain = 1.0;
|
||||
}
|
||||
|
||||
@ -57,18 +60,9 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
fResampler[i] = new Resampler(fInput.format.u.raw_audio.format, media_raw_audio_format::B_AUDIO_FLOAT);
|
||||
|
||||
// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels()
|
||||
// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateInputChannelDestinations()
|
||||
|
||||
SetMixBufferFormat(mixFrameRate, mixFrameCount);
|
||||
|
||||
// XXX a test:
|
||||
/*
|
||||
SetMixerChannelGain(0, 0.222);
|
||||
SetMixerChannelGain(1, 0.444);
|
||||
AddInputChannelDesignation(0, B_CHANNEL_REARRIGHT);
|
||||
SetMixerChannelGain(2, 0.666);
|
||||
AddInputChannelDesignation(1, B_CHANNEL_REARLEFT);
|
||||
*/
|
||||
}
|
||||
|
||||
MixerInput::~MixerInput()
|
||||
@ -196,65 +190,81 @@ MixerInput::GetInputChannelCount()
|
||||
}
|
||||
|
||||
void
|
||||
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
|
||||
MixerInput::AddInputChannelDestination(int channel, int destination_type)
|
||||
{
|
||||
ASSERT(count_nonzero_bits(des) == 1);
|
||||
uint32 mask = ChannelTypeToChannelMask(destination_type);
|
||||
|
||||
// test if the channel is valid
|
||||
if (channel < 0 || channel >= fInputChannelCount)
|
||||
return;
|
||||
|
||||
// test if it is already set
|
||||
if (fInputChannelInfo[channel].designations & des)
|
||||
if (fInputChannelInfo[channel].destination_mask & mask)
|
||||
return;
|
||||
|
||||
// remove it from all other channels that might have it
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
fInputChannelInfo[i].designations &= ~des;
|
||||
|
||||
// add it to specified channel
|
||||
fInputChannelInfo[channel].designations |= des;
|
||||
// verify that no other channel has id
|
||||
if (-1 != GetInputChannelForDestination(destination_type)) {
|
||||
ERROR("MixerInput::AddInputChannelDestination: destination_type %d already assigned to channel %d\n", destination_type, GetInputChannelForDestination(destination_type));
|
||||
return;
|
||||
}
|
||||
|
||||
fUserOverridesChannelDesignations = true;
|
||||
UpdateMixerChannels();
|
||||
// add it to specified channel
|
||||
fInputChannelInfo[channel].destination_mask |= mask;
|
||||
|
||||
fUserOverridesChannelDestinations = true;
|
||||
UpdateInputChannelDestinations();
|
||||
}
|
||||
|
||||
void
|
||||
MixerInput::RemoveInputChannelDesignation(int channel, uint32 des)
|
||||
MixerInput::RemoveInputChannelDestination(int channel, int destination_type)
|
||||
{
|
||||
ASSERT(count_nonzero_bits(des) == 1);
|
||||
uint32 mask = ChannelTypeToChannelMask(destination_type);
|
||||
|
||||
// test if the channel is valid
|
||||
if (channel < 0 || channel >= fInputChannelCount)
|
||||
return;
|
||||
|
||||
// test if it is really set
|
||||
if ((fInputChannelInfo[channel].designations & des) == 0)
|
||||
if ((fInputChannelInfo[channel].destination_mask & mask) == 0)
|
||||
return;
|
||||
|
||||
// remove it from specified channel
|
||||
fInputChannelInfo[channel].designations &= ~des;
|
||||
fInputChannelInfo[channel].destination_mask &= ~mask;
|
||||
|
||||
fUserOverridesChannelDesignations = true;
|
||||
UpdateMixerChannels();
|
||||
fUserOverridesChannelDestinations = true;
|
||||
UpdateInputChannelDestinations();
|
||||
}
|
||||
|
||||
uint32
|
||||
MixerInput::GetInputChannelDesignations(int channel)
|
||||
bool
|
||||
MixerInput::HasInputChannelDestination(int channel, int destination_type)
|
||||
{
|
||||
// test if the channel is valid
|
||||
if (channel < 0 || channel >= fInputChannelCount)
|
||||
return 0;
|
||||
return fInputChannelInfo[channel].designations;
|
||||
return false;
|
||||
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
|
||||
return false;
|
||||
return fInputChannelInfo[channel].destination_mask & ChannelTypeToChannelMask(destination_type);
|
||||
}
|
||||
|
||||
uint32
|
||||
int
|
||||
MixerInput::GetInputChannelForDestination(int destination_type)
|
||||
{
|
||||
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
|
||||
return -1;
|
||||
uint32 mask = ChannelTypeToChannelMask(destination_type);
|
||||
for (int chan = 0; chan < fInputChannelCount; chan++) {
|
||||
if (fInputChannelInfo[chan].destination_mask & mask)
|
||||
return chan;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
MixerInput::GetInputChannelType(int channel)
|
||||
{
|
||||
// test if the channel is valid
|
||||
if (channel < 0 || channel >= fInputChannelCount)
|
||||
return 0;
|
||||
return GetChannelMask(channel, fInputChannelMask);
|
||||
return GetChannelType(channel, fInputChannelMask);
|
||||
}
|
||||
|
||||
void
|
||||
@ -279,17 +289,17 @@ MixerInput::GetInputChannelGain(int channel)
|
||||
}
|
||||
|
||||
void
|
||||
MixerInput::UpdateChannelDesignations()
|
||||
MixerInput::UpdateInputChannelDestinationMask()
|
||||
{
|
||||
// is the user already messed with the assignmens, don't do anything.
|
||||
if (fUserOverridesChannelDesignations)
|
||||
if (fUserOverridesChannelDestinations)
|
||||
return;
|
||||
|
||||
TRACE("UpdateChannelDesignations: enter\n");
|
||||
TRACE("UpdateInputChannelDestinationMask: enter\n");
|
||||
|
||||
// first apply a 1:1 mapping
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask);
|
||||
fInputChannelInfo[i].destination_mask = GetChannelMask(i, fInputChannelMask);
|
||||
|
||||
// specialize this, depending on the available physical output channels
|
||||
switch (fCore->OutputChannelCount()) {
|
||||
@ -299,80 +309,70 @@ MixerInput::UpdateChannelDesignations()
|
||||
|
||||
case 2:
|
||||
if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
|
||||
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
|
||||
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
|
||||
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
|
||||
}
|
||||
if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_LEFT)) {
|
||||
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
|
||||
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
|
||||
}
|
||||
if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_RIGHT)) {
|
||||
fInputChannelInfo[0].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
|
||||
fInputChannelInfo[0].destination_mask = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
|
||||
}
|
||||
if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_LEFT)) {
|
||||
fInputChannelInfo[1].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
|
||||
fInputChannelInfo[1].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
|
||||
}
|
||||
if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_RIGHT)) {
|
||||
fInputChannelInfo[1].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
|
||||
fInputChannelInfo[1].destination_mask = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
TRACE("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||
TRACE("UpdateInputChannelDestinationMask: input channel %d, destination_mask 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||
|
||||
TRACE("UpdateChannelDesignations: leave\n");
|
||||
TRACE("UpdateInputChannelDestinationMask: leave\n");
|
||||
}
|
||||
|
||||
void
|
||||
MixerInput::UpdateMixerChannels()
|
||||
MixerInput::UpdateInputChannelDestinations()
|
||||
{
|
||||
uint32 channel_count;
|
||||
uint32 all_bits;
|
||||
uint32 mask;
|
||||
|
||||
mixer_chan_info *old_mixer_channel_info;
|
||||
uint32 old_mixer_channel_count;
|
||||
|
||||
TRACE("UpdateMixerChannels: enter\n");
|
||||
TRACE("UpdateInputChannelDestinations: enter\n");
|
||||
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
TRACE("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||
TRACE("UpdateInputChannelDestinations: input channel %d, destination_mask 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||
|
||||
all_bits = 0;
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
all_bits |= fInputChannelInfo[i].designations;
|
||||
all_bits |= fInputChannelInfo[i].destination_mask;
|
||||
|
||||
TRACE("UpdateMixerChannels: all_bits = %08x\n", all_bits);
|
||||
TRACE("UpdateInputChannelDestinations: all_bits = %08x\n", all_bits);
|
||||
|
||||
channel_count = count_nonzero_bits(all_bits);
|
||||
|
||||
TRACE("UpdateMixerChannels: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount);
|
||||
TRACE("UpdateInputChannelDestinations: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount);
|
||||
|
||||
// If we resize the channel info array, we preserve the gain setting
|
||||
// by saving the old array until new assignments are finished, and
|
||||
// then applying the old gains. New gains are set to 1.0
|
||||
if (channel_count != fMixerChannelCount) {
|
||||
old_mixer_channel_info = fMixerChannelInfo;
|
||||
old_mixer_channel_count = fMixerChannelCount;
|
||||
delete [] fMixerChannelInfo;
|
||||
fMixerChannelInfo = new mixer_chan_info[channel_count];
|
||||
fMixerChannelCount = channel_count;
|
||||
for (int i = 0; i < fMixerChannelCount; i++)
|
||||
fMixerChannelInfo[i].gain = 1.0;
|
||||
} else {
|
||||
old_mixer_channel_info = 0;
|
||||
old_mixer_channel_count = 0;
|
||||
}
|
||||
|
||||
|
||||
// assign each mixer channel one type
|
||||
// and the gain from the fChannelTypeGain[]
|
||||
for (int i = 0, mask = 1; i < fMixerChannelCount; i++) {
|
||||
while (mask != 0 && (all_bits & mask) == 0)
|
||||
mask <<= 1;
|
||||
fMixerChannelInfo[i].type = ChannelMaskToChannelType(mask);
|
||||
fMixerChannelInfo[i].destination_type = ChannelMaskToChannelType(mask);
|
||||
fMixerChannelInfo[i].destination_gain = fChannelTypeGain[fMixerChannelInfo[i].destination_type];
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
@ -380,7 +380,7 @@ MixerInput::UpdateMixerChannels()
|
||||
for (int i = 0; i < fMixerChannelCount; i++) {
|
||||
int j;
|
||||
for (j = 0; j < fInputChannelCount; j++) {
|
||||
if (fInputChannelInfo[j].designations & ChannelTypeToChannelMask(fMixerChannelInfo[i].type)) {
|
||||
if (fInputChannelInfo[j].destination_mask & ChannelTypeToChannelMask(fMixerChannelInfo[i].destination_type)) {
|
||||
fMixerChannelInfo[i].buffer_base = fMixBuffer ? &fMixBuffer[j] : 0;
|
||||
break;
|
||||
}
|
||||
@ -390,50 +390,46 @@ MixerInput::UpdateMixerChannels()
|
||||
fMixerChannelInfo[i].buffer_base = fMixBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
// apply old gains, overriding the 1.0 defaults for the old channels
|
||||
if (old_mixer_channel_info != 0) {
|
||||
for (int i = 0; i < fMixerChannelCount; i++) {
|
||||
for (int j = 0; j < old_mixer_channel_count; j++) {
|
||||
if (fMixerChannelInfo[i].type == old_mixer_channel_info[j].type) {
|
||||
fMixerChannelInfo[i].gain = old_mixer_channel_info[j].gain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// also delete the old info array
|
||||
delete [] old_mixer_channel_info;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fMixerChannelCount; i++)
|
||||
TRACE("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);
|
||||
TRACE("UpdateInputChannelDestinations: mixer channel %d, type %2d, base %p, gain %.3f\n", i, fMixerChannelInfo[i].destination_type, fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].destination_gain);
|
||||
|
||||
TRACE("UpdateMixerChannels: leave\n");
|
||||
}
|
||||
|
||||
uint32
|
||||
MixerInput::GetMixerChannelCount()
|
||||
{
|
||||
return fMixerChannelCount;
|
||||
TRACE("UpdateInputChannelDestinations: leave\n");
|
||||
}
|
||||
|
||||
void
|
||||
MixerInput::SetMixerChannelGain(int channel, float gain)
|
||||
MixerInput::SetInputChannelDestinationGain(int channel, int destination_type, float gain)
|
||||
{
|
||||
TRACE("SetMixerChannelGain chan %d, gain %.5f\n", channel, gain);
|
||||
TRACE("SetInputChannelDestinationGain: channel %d, destination_type %d, gain %.4f\n", channel, destination_type, gain);
|
||||
// we don't need the channel, as each destination_type can only exist
|
||||
// once for each MixerInput, but we use it for parameter validation
|
||||
// and to have a interface similar to MixerOutput
|
||||
if (channel < 0 || channel >= fMixerChannelCount)
|
||||
return;
|
||||
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
|
||||
return;
|
||||
if (gain < 0.0f)
|
||||
gain = 0.0f;
|
||||
fMixerChannelInfo[channel].gain = gain;
|
||||
fChannelTypeGain[destination_type] = gain;
|
||||
for (int i = 0; i < fMixerChannelCount; i++) {
|
||||
if (fMixerChannelInfo[i].destination_type == destination_type) {
|
||||
fMixerChannelInfo[i].destination_gain = gain;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
MixerInput::GetMixerChannelGain(int channel)
|
||||
MixerInput::GetInputChannelDestinationGain(int channel, int destination_type)
|
||||
{
|
||||
// we don't need the channel, as each destination_type can only exist
|
||||
// once for each MixerInput, but we use it for parameter validation
|
||||
// and to have a interface similar to MixerOutput
|
||||
if (channel < 0 || channel >= fMixerChannelCount)
|
||||
return 1.0;
|
||||
return fMixerChannelInfo[channel].gain;
|
||||
return 0.0f;
|
||||
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
|
||||
return 0.0f;
|
||||
return fChannelTypeGain[destination_type];
|
||||
}
|
||||
|
||||
void
|
||||
@ -466,8 +462,8 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
|
||||
fInputChannelInfo[i].buffer_base = 0;
|
||||
fMixBufferFrameCount = 0;
|
||||
|
||||
UpdateChannelDesignations();
|
||||
UpdateMixerChannels();
|
||||
UpdateInputChannelDestinationMask();
|
||||
UpdateInputChannelDestinations();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -502,6 +498,6 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
|
||||
for (int i = 0; i < fInputChannelCount; i++)
|
||||
fInputChannelInfo[i].buffer_base = &fMixBuffer[i];
|
||||
|
||||
UpdateChannelDesignations();
|
||||
UpdateMixerChannels();
|
||||
UpdateInputChannelDestinationMask();
|
||||
UpdateInputChannelDestinations();
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include <RealtimeAlloc.h>
|
||||
#include <MediaNode.h>
|
||||
#include "MixerCore.h"
|
||||
#include "debug.h"
|
||||
|
||||
class MixerCore;
|
||||
class ByteSwap;
|
||||
class Resampler;
|
||||
|
||||
@ -20,44 +20,46 @@ public:
|
||||
void BufferReceived(BBuffer *buffer);
|
||||
|
||||
media_input & MediaInput();
|
||||
|
||||
uint32 GetMixerChannelCount();
|
||||
void SetMixerChannelGain(int channel, float gain);
|
||||
float GetMixerChannelGain(int channel);
|
||||
|
||||
uint32 GetInputChannelCount();
|
||||
void AddInputChannelDesignation(int channel, uint32 des);
|
||||
void RemoveInputChannelDesignation(int channel, uint32 des);
|
||||
uint32 GetInputChannelDesignations(int channel);
|
||||
uint32 GetInputChannelType(int channel);
|
||||
void SetInputChannelGain(int channel, float gain);
|
||||
float GetInputChannelGain(int channel);
|
||||
|
||||
// The physical input channels
|
||||
uint32 GetInputChannelCount();
|
||||
int GetInputChannelType(int channel);
|
||||
void SetInputChannelGain(int channel, float gain);
|
||||
float GetInputChannelGain(int channel);
|
||||
|
||||
// The destinations for each channel
|
||||
void AddInputChannelDestination(int channel, int destination_type);
|
||||
void RemoveInputChannelDestination(int channel, int destination_type);
|
||||
void SetInputChannelDestinationGain(int channel, int destination_type, float gain);
|
||||
float GetInputChannelDestinationGain(int channel, int destination_type);
|
||||
bool HasInputChannelDestination(int channel, int destination_type);
|
||||
int GetInputChannelForDestination(int destination_type); // returns -1 if not found
|
||||
|
||||
void SetEnabled(bool yesno);
|
||||
bool IsEnabled();
|
||||
|
||||
// only for use by MixerCore
|
||||
bool GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain);
|
||||
int GetMixerChannelType(int channel);
|
||||
uint32 GetMixerChannelCount();
|
||||
bool GetMixerChannelInfo(int mixer_channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain);
|
||||
|
||||
protected:
|
||||
friend class MixerCore;
|
||||
void SetMixBufferFormat(int32 framerate, int32 frames);
|
||||
|
||||
private:
|
||||
void UpdateChannelDesignations();
|
||||
void UpdateMixerChannels();
|
||||
void UpdateInputChannelDestinationMask();
|
||||
void UpdateInputChannelDestinations();
|
||||
|
||||
private:
|
||||
struct input_chan_info {
|
||||
float *buffer_base;
|
||||
uint32 designations; // multiple or no bits sets
|
||||
uint32 destination_mask; // multiple or no bits sets
|
||||
float gain;
|
||||
};
|
||||
struct mixer_chan_info {
|
||||
float *buffer_base;
|
||||
int type;
|
||||
float gain;
|
||||
int destination_type;
|
||||
float destination_gain;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -65,6 +67,8 @@ private:
|
||||
media_input fInput;
|
||||
ByteSwap *fInputByteSwap;
|
||||
|
||||
float fChannelTypeGain[MAX_CHANNEL_TYPES];
|
||||
|
||||
bool fEnabled;
|
||||
|
||||
input_chan_info *fInputChannelInfo; // array
|
||||
@ -84,34 +88,32 @@ private:
|
||||
Resampler **fResampler; // array
|
||||
rtm_pool *fRtmPool;
|
||||
|
||||
bool fUserOverridesChannelDesignations;
|
||||
bool fUserOverridesChannelDestinations;
|
||||
|
||||
int32 debugMixBufferFrames;
|
||||
};
|
||||
|
||||
inline uint32
|
||||
MixerInput::GetMixerChannelCount()
|
||||
{
|
||||
return fMixerChannelCount;
|
||||
}
|
||||
|
||||
inline bool
|
||||
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain)
|
||||
MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain)
|
||||
{
|
||||
ASSERT(fMixBuffer); // this function should not be called if we don't have a mix buffer!
|
||||
ASSERT(channel >= 0 && channel < fMixerChannelCount);
|
||||
ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount);
|
||||
if (time > fLastDataAvailableTime || !fEnabled)
|
||||
return false;
|
||||
|
||||
int32 offset = framepos % fMixBufferFrameCount;
|
||||
if (channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
|
||||
*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
|
||||
if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
|
||||
*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
|
||||
*sample_offset = sizeof(float) * fInputChannelCount;
|
||||
*type = fMixerChannelInfo[channel].type;
|
||||
*gain = fMixerChannelInfo[channel].gain;
|
||||
*type = fMixerChannelInfo[mixer_channel].destination_type;
|
||||
*gain = fMixerChannelInfo[mixer_channel].destination_gain;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int
|
||||
MixerInput::GetMixerChannelType(int channel)
|
||||
{
|
||||
ASSERT(fMixBuffer); // this function should not be called if we don't have a mix buffer!
|
||||
ASSERT(channel >= 0 && channel < fMixerChannelCount);
|
||||
return fMixerChannelInfo[channel].type;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -104,7 +104,7 @@ MixerOutput::UpdateOutputChannels()
|
||||
delete [] oldInfo;
|
||||
}
|
||||
for (int i = 0; i < fOutputChannelCount; i++)
|
||||
TRACE("UpdateOutputChannels: output channel %d, des 0x%08X (type %2d), gain %.3f\n", i, fOutputChannelInfo[i].designation, ChannelMaskToChannelType(fOutputChannelInfo[i].designation), fOutputChannelInfo[i].gain);
|
||||
TRACE("UpdateOutputChannels: output channel %d, type %2d, gain %.3f\n", i, fOutputChannelInfo[i].channel_type, fOutputChannelInfo[i].channel_gain);
|
||||
}
|
||||
|
||||
void
|
||||
@ -229,7 +229,7 @@ MixerOutput::AssignDefaultSources()
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
int
|
||||
MixerOutput::GetOutputChannelType(int channel)
|
||||
{
|
||||
if (channel < 0 || channel >= fOutputChannelCount)
|
||||
|
@ -29,18 +29,18 @@ public:
|
||||
|
||||
// The physical output channels
|
||||
uint32 GetOutputChannelCount();
|
||||
uint32 GetOutputChannelType(int channel);
|
||||
int GetOutputChannelType(int channel);
|
||||
void SetOutputChannelGain(int channel, float gain);
|
||||
float GetOutputChannelGain(int channel);
|
||||
|
||||
// The Sources for each channel
|
||||
// The sources for each channel
|
||||
void AddOutputChannelSource(int channel, int source_type);
|
||||
void RemoveOutputChannelSource(int channel, int source_type);
|
||||
void SetOutputChannelSourceGain(int channel, int source_type, float source_gain);
|
||||
float GetOutputChannelSourceGain(int channel, int source_type);
|
||||
bool HasOutputChannelSource(int channel, int source_type);
|
||||
|
||||
// The Output can be muted
|
||||
// The output can be muted
|
||||
void SetMuted(bool yesno);
|
||||
bool IsMuted();
|
||||
|
||||
@ -61,7 +61,7 @@ private:
|
||||
private:
|
||||
|
||||
/* An entry in the source array is not the same as the
|
||||
* channel type, but the number should be the same
|
||||
* channel type, but the count should be the same
|
||||
*/
|
||||
enum {
|
||||
MAX_SOURCE_ENTRIES = MAX_CHANNEL_TYPES
|
||||
@ -100,15 +100,14 @@ inline float MixerOutput::GetOutputChannelGain(int channel)
|
||||
|
||||
inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel)
|
||||
{
|
||||
if (channel < 0 || channel >= fOutputChannelCount)
|
||||
return 0;
|
||||
ASSERT(channel >= 0 && channel < fOutputChannelCount);
|
||||
return fOutputChannelInfo[channel].source_count;
|
||||
}
|
||||
|
||||
inline void MixerOutput::GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain)
|
||||
{
|
||||
ASSERT(channel >= 0 && channel < fOutputChannelCount);
|
||||
ASSERT(index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
|
||||
ASSERT(source_index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
|
||||
*source_type = fOutputChannelInfo[channel].source_type[source_index];
|
||||
*source_gain = fOutputChannelInfo[channel].source_gain[source_index];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user