Cleanup of MixerOutput class, the channel type is now used instead of channel designation or channel_mask

Implemented output channel remapping controls.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3813 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-07-03 00:27:47 +00:00
parent 0c63c7d061
commit b6270d60b2
6 changed files with 169 additions and 98 deletions
@@ -843,24 +843,40 @@ AudioMixer::CreateBufferGroup()
// BControllable methods // BControllable methods
// //
#define PARAM_INPUT(a) (((a) << 16) + 0) #define DB_TO_GAIN(_db) (20.0 * log10(_db))
#define PARAM_FORMAT(a) (((a) << 16) + 1) #define GAIN_TO_DB(_gain) (pow(10.0, (_gain) / 20.0))
#define PARAM_MUTE(a) (((a) << 16) + 2) #define PERCENT_TO_GAIN(_db) ((_db) / 100.0)
#define PARAM_GAIN(a) (((a) << 16) + 3) #define GAIN_TO_PERCENT(_gain) ((_gain) * 100.0)
#define PARAM_OUTPUT(a) (((a) << 16) + 4)
#define PARAM(a) ((a) >> 16)
#define PARAM_IS_MUTE(a) (((a) & 0xffff) == 2)
#define PARAM_IS_GAIN(a) (((a) & 0xffff) == 3)
#define DB_TO_GAIN(_db) (20.0 * log10(_db))
#define GAIN_TO_DB(_gain) (pow(10.0, (_gain) / 20.0))
#define PARAM_SRC_ENABLE(id, chan, src) (((id) << 16) | ((chan) << 14) | ((src) << 8) | 1) // the id is encoded with 16 bits
#define PARAM_SRC_PERCENT(id, chan, src) (((id) << 16) | ((chan) << 14) | ((src) << 8) | 2) // then chan and src (or dst) are encoded with 6 bits
#define PARAM_DST_ENABLE(id, chan, dst) (((id) << 16) | ((chan) << 14) | ((dst) << 8) | 3) // the unique number with 4 bits
#define PARAM_DST_PERCENT(id, chan, dst) (((id) << 16) | ((chan) << 14) | ((dst) << 8) | 4) #define PARAM_SRC_ENABLE(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x1)
#define PARAM_SRC(id, chan) (((id) << 16) | ((chan) << 14) | 5) #define PARAM_SRC_GAIN(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x2)
#define PARAM_DST(id, chan) (((id) << 16) | ((chan) << 14) | 6) #define PARAM_DST_ENABLE(id, chan, dst) (((id) << 16) | ((chan) << 10) | ((dst) << 4) | 0x3)
#define PARAM_STR(id) (((id) << 16) | 7) #define PARAM_DST_GAIN(id, chan, dst) (((id) << 16) | ((chan) << 10) | ((dst) << 4) | 0x4)
#define PARAM_SRC_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x5)
#define PARAM_DST_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x6)
#define PARAM_MUTE(id) (((id) << 16) | 0x7)
#define PARAM_GAIN(id) (((id) << 16) | 0x8)
#define PARAM_STR1(id) (((id) << 16) | 0x9)
#define PARAM_STR2(id) (((id) << 16) | 0xa)
#define PARAM_STR3(id) (((id) << 16) | 0xb)
#define PARAM_STR4(id) (((id) << 16) | 0xc)
#define PARAM_STR5(id) (((id) << 16) | 0xd)
#define PARAM_STR6(id) (((id) << 16) | 0xe)
#define PARAM_STR7(id) (((id) << 16) | 0xf)
#define PARAM(id) ((id) >> 16)
#define PARAM_CHAN(id) (((id) >> 10) & 0x3f)
#define PARAM_SRC(id) (((id) >> 4) & 0x3f)
#define PARAM_DST(id) (((id) >> 4) & 0x3f)
#define PARAM_IS_SRC_ENABLE(id) (((id) & 0xf) == 0x1)
#define PARAM_IS_SRC_GAIN(id) (((id) & 0xf) == 0x2)
#define PARAM_IS_DST_ENABLE(id) (((id) & 0xf) == 0x3)
#define PARAM_IS_DST_GAIN(id) (((id) & 0xf) == 0x4)
#define PARAM_IS_MUTE(id) (((id) & 0xf) == 0x7)
#define PARAM_IS_GAIN(id) (((id) & 0xf) == 0x8)
status_t status_t
@@ -872,7 +888,7 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
fCore->Lock(); fCore->Lock();
if (param == 0) { if (param == 0) {
MixerOutput *output = fCore->Output(); MixerOutput *output = fCore->Output();
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !output) if (!output || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_SRC_ENABLE(id) && !PARAM_IS_SRC_GAIN(id)))
goto err; goto err;
if (PARAM_IS_MUTE(id)) { if (PARAM_IS_MUTE(id)) {
// output mute control // output mute control
@@ -889,6 +905,18 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
for (int chan = 0; chan < output->GetOutputChannelCount(); chan++) for (int chan = 0; chan < output->GetOutputChannelCount(); chan++)
static_cast<float *>(value)[chan] = DB_TO_GAIN(output->GetOutputChannelGain(chan)); static_cast<float *>(value)[chan] = DB_TO_GAIN(output->GetOutputChannelGain(chan));
} }
if (PARAM_IS_SRC_ENABLE(id)) {
if (*ioSize < sizeof(int32))
goto err;
*ioSize = sizeof(int32);
static_cast<int32 *>(value)[0] = output->HasOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id));
}
if (PARAM_IS_SRC_GAIN(id)) {
if (*ioSize < sizeof(float))
goto err;
*ioSize = sizeof(float);
static_cast<float *>(value)[0] = GAIN_TO_PERCENT(output->GetOutputChannelSourceGain(PARAM_CHAN(id), PARAM_SRC(id)));
}
} else { } else {
MixerInput *input; MixerInput *input;
for (int i = 0; (input = fCore->Input(i)); i++) for (int i = 0; (input = fCore->Input(i)); i++)
@@ -929,7 +957,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
fCore->Lock(); fCore->Lock();
if (param == 0) { if (param == 0) {
MixerOutput *output = fCore->Output(); MixerOutput *output = fCore->Output();
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !output) if (!output || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_SRC_ENABLE(id) && !PARAM_IS_SRC_GAIN(id)))
goto err; goto err;
if (PARAM_IS_MUTE(id)) { if (PARAM_IS_MUTE(id)) {
// output mute control // output mute control
@@ -944,6 +972,27 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
for (int chan = 0; chan < output->GetOutputChannelCount(); chan++) for (int chan = 0; chan < output->GetOutputChannelCount(); chan++)
output->SetOutputChannelGain(chan, GAIN_TO_DB(static_cast<const float *>(value)[chan])); output->SetOutputChannelGain(chan, GAIN_TO_DB(static_cast<const float *>(value)[chan]));
} }
if (PARAM_IS_SRC_ENABLE(id)) {
if (size != sizeof(int32))
goto err;
if (static_cast<const int32 *>(value)[0]) {
output->AddOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id), 0.0);
} else {
output->RemoveOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id));
}
// after adding/removing sources, reset gain to 0.0
float nullgain = 0.0;
BroadcastNewParameterValue(when, PARAM_SRC_GAIN(PARAM(id), PARAM_CHAN(id), PARAM_SRC(id)), &nullgain, sizeof(nullgain));
}
if (PARAM_IS_SRC_GAIN(id)) {
if (size != sizeof(float))
goto err;
if (!output->SetOutputChannelSourceGain(PARAM_CHAN(id), PARAM_SRC(id), PERCENT_TO_GAIN(static_cast<const float *>(value)[0]))) {
// gain setting failed, reset to 0.0
float nullgain = 0.0;
BroadcastNewParameterValue(when, PARAM_SRC_GAIN(PARAM(id), PARAM_CHAN(id), PARAM_SRC(id)), &nullgain, sizeof(nullgain));
}
}
} else { } else {
MixerInput *input; MixerInput *input;
for (int i = 0; (input = fCore->Input(i)); i++) for (int i = 0; (input = fCore->Input(i)); i++)
@@ -990,75 +1039,76 @@ AudioMixer::UpdateParameterWeb()
out = fCore->Output(); out = fCore->Output();
group = top->MakeGroup(""); group = top->MakeGroup("");
group->MakeNullParameter(PARAM_INPUT(0), B_MEDIA_RAW_AUDIO, "Master Output", B_WEB_BUFFER_INPUT); group->MakeNullParameter(PARAM_STR1(0), B_MEDIA_RAW_AUDIO, "Master Output", B_WEB_BUFFER_INPUT);
if (!out) { if (!out) {
group->MakeNullParameter(PARAM_FORMAT(0), B_MEDIA_RAW_AUDIO, "not connected", B_GENERIC); group->MakeNullParameter(PARAM_STR2(0), B_MEDIA_RAW_AUDIO, "not connected", B_GENERIC);
} else { } else {
group->MakeNullParameter(PARAM_FORMAT(0), B_MEDIA_RAW_AUDIO, StringForFormat(buf, out), B_GENERIC); group->MakeNullParameter(PARAM_STR2(0), B_MEDIA_RAW_AUDIO, StringForFormat(buf, out), B_GENERIC);
group->MakeDiscreteParameter(PARAM_MUTE(0), B_MEDIA_RAW_AUDIO, "Mute", B_MUTE); group->MakeDiscreteParameter(PARAM_MUTE(0), B_MEDIA_RAW_AUDIO, "Mute", B_MUTE);
group->MakeContinuousParameter(PARAM_GAIN(0), B_MEDIA_RAW_AUDIO, "Gain", B_MASTER_GAIN, "dB", -60.0, 18.0, 0.5) group->MakeContinuousParameter(PARAM_GAIN(0), B_MEDIA_RAW_AUDIO, "Gain", B_MASTER_GAIN, "dB", -60.0, 18.0, 0.5)
->SetChannelCount(out->GetOutputChannelCount()); ->SetChannelCount(out->GetOutputChannelCount());
group->MakeNullParameter(PARAM_OUTPUT(0), B_MEDIA_RAW_AUDIO, "To Output", B_WEB_BUFFER_OUTPUT); group->MakeNullParameter(PARAM_STR3(0), B_MEDIA_RAW_AUDIO, "To Output", B_WEB_BUFFER_OUTPUT);
} }
for (int i = 0; (in = fCore->Input(i)); i++) { for (int i = 0; (in = fCore->Input(i)); i++) {
group = top->MakeGroup(""); group = top->MakeGroup("");
group->MakeNullParameter(PARAM_INPUT(in->ID()), B_MEDIA_RAW_AUDIO, in->MediaInput().name, B_WEB_BUFFER_INPUT); group->MakeNullParameter(PARAM_STR1(in->ID()), B_MEDIA_RAW_AUDIO, in->MediaInput().name, B_WEB_BUFFER_INPUT);
group->MakeNullParameter(PARAM_FORMAT(in->ID()), B_MEDIA_RAW_AUDIO, StringForFormat(buf, in), B_GENERIC); group->MakeNullParameter(PARAM_STR2(in->ID()), B_MEDIA_RAW_AUDIO, StringForFormat(buf, in), B_GENERIC);
group->MakeDiscreteParameter(PARAM_MUTE(in->ID()), B_MEDIA_RAW_AUDIO, "Mute", B_MUTE); group->MakeDiscreteParameter(PARAM_MUTE(in->ID()), B_MEDIA_RAW_AUDIO, "Mute", B_MUTE);
group->MakeContinuousParameter(PARAM_GAIN(in->ID()), B_MEDIA_RAW_AUDIO, "Gain", B_GAIN, "dB", -60.0, 18.0, 0.5) group->MakeContinuousParameter(PARAM_GAIN(in->ID()), B_MEDIA_RAW_AUDIO, "Gain", B_GAIN, "dB", -60.0, 18.0, 0.5)
->SetChannelCount(in->GetInputChannelCount()); ->SetChannelCount(in->GetInputChannelCount());
group->MakeNullParameter(PARAM_OUTPUT(in->ID()), B_MEDIA_RAW_AUDIO, "To Master", B_WEB_BUFFER_OUTPUT); group->MakeNullParameter(PARAM_STR3(in->ID()), B_MEDIA_RAW_AUDIO, "To Master", B_WEB_BUFFER_OUTPUT);
} }
top = web->MakeGroup("Output Mapping"); // top level group top = web->MakeGroup("Output Mapping"); // top level group
outputchannels = top->MakeGroup(""); outputchannels = top->MakeGroup("");
outputchannels->MakeNullParameter(10001, B_MEDIA_RAW_AUDIO, "Output Channel Sources", B_GENERIC); outputchannels->MakeNullParameter(PARAM_STR4(0), B_MEDIA_RAW_AUDIO, "Output Channel Sources", B_GENERIC);
group = outputchannels->MakeGroup(""); group = outputchannels->MakeGroup("");
group->MakeNullParameter(10002, B_MEDIA_RAW_AUDIO, "Master Output", B_GENERIC); group->MakeNullParameter(PARAM_STR5(0), B_MEDIA_RAW_AUDIO, "Master Output", B_GENERIC);
group = group->MakeGroup(""); group = group->MakeGroup("");
if (!out) { if (!out) {
group->MakeNullParameter(PARAM_FORMAT(0), B_MEDIA_RAW_AUDIO, "not connected", B_GENERIC); group->MakeNullParameter(PARAM_STR6(0), B_MEDIA_RAW_AUDIO, "not connected", B_GENERIC);
} else { } else {
for (int chan = 0; chan < out->GetOutputChannelCount(); chan++) { for (int chan = 0; chan < out->GetOutputChannelCount(); chan++) {
subgroup = group->MakeGroup(""); subgroup = group->MakeGroup("");
subgroup->MakeNullParameter(PARAM_SRC(0, chan), B_MEDIA_RAW_AUDIO, subgroup->MakeNullParameter(PARAM_SRC_STR(0, chan), B_MEDIA_RAW_AUDIO,
StringForChannelType(buf, out->GetOutputChannelType(chan)), B_GENERIC); StringForChannelType(buf, out->GetOutputChannelType(chan)), B_GENERIC);
for (int src = 0; src < MAX_CHANNEL_TYPES; src++) { for (int src = 0; src < MAX_CHANNEL_TYPES; src++) {
subsubgroup = subgroup->MakeGroup(""); subsubgroup = subgroup->MakeGroup("");
subsubgroup->MakeDiscreteParameter(PARAM_SRC_ENABLE(0, chan, src), B_MEDIA_RAW_AUDIO, "", B_ENABLE); subsubgroup->MakeDiscreteParameter(PARAM_SRC_ENABLE(0, chan, src), B_MEDIA_RAW_AUDIO, "", B_ENABLE);
subsubgroup->MakeContinuousParameter(PARAM_SRC_PERCENT(0, chan, src), B_MEDIA_RAW_AUDIO, subsubgroup->MakeContinuousParameter(PARAM_SRC_GAIN(0, chan, src), B_MEDIA_RAW_AUDIO,
StringForChannelType(buf, src), B_GAIN, "%", 0.0, 100.0, 1.0); StringForChannelType(buf, src), B_GAIN, "%", 0.0, 100.0, 1.0);
} }
} }
} }
#if 0
top = web->MakeGroup("Input Mapping"); // top level group top = web->MakeGroup("Input Mapping"); // top level group
inputchannels = top->MakeGroup(""); inputchannels = top->MakeGroup("");
inputchannels->MakeNullParameter(10003, B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC); inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC);
// for (int i = 0; (in = fCore->Input(i)); i++) { // 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 if ((in = fCore->Input(1)) || (in = fCore->Input(0))) { // XXX limited to input 1 or 0 to aviod BSlider problems
group = inputchannels->MakeGroup(""); group = inputchannels->MakeGroup("");
group->MakeNullParameter(PARAM_STR(in->ID()), B_MEDIA_RAW_AUDIO, in->MediaInput().name, B_GENERIC); group->MakeNullParameter(PARAM_STR4(in->ID()), B_MEDIA_RAW_AUDIO, in->MediaInput().name, B_GENERIC);
group = group->MakeGroup(""); group = group->MakeGroup("");
for (int chan = 0; chan < in->GetInputChannelCount(); chan++) { for (int chan = 0; chan < in->GetInputChannelCount(); chan++) {
subgroup = group->MakeGroup(""); subgroup = group->MakeGroup("");
subgroup->MakeNullParameter(PARAM_DST(in->ID(), chan), B_MEDIA_RAW_AUDIO, subgroup->MakeNullParameter(PARAM_DST_STR(in->ID(), chan), B_MEDIA_RAW_AUDIO,
StringForChannelType(buf, in->GetInputChannelType(chan)), B_GENERIC); StringForChannelType(buf, in->GetInputChannelType(chan)), B_GENERIC);
for (int dst = 0; dst < MAX_CHANNEL_TYPES; dst++) { for (int dst = 0; dst < MAX_CHANNEL_TYPES; dst++) {
subsubgroup = subgroup->MakeGroup(""); subsubgroup = subgroup->MakeGroup("");
subsubgroup->MakeDiscreteParameter(PARAM_DST_ENABLE(in->ID(), chan, dst), B_MEDIA_RAW_AUDIO, "", B_ENABLE); subsubgroup->MakeDiscreteParameter(PARAM_DST_ENABLE(in->ID(), chan, dst), B_MEDIA_RAW_AUDIO, "", B_ENABLE);
subsubgroup->MakeContinuousParameter(PARAM_DST_PERCENT(in->ID(), chan, dst), B_MEDIA_RAW_AUDIO, subsubgroup->MakeContinuousParameter(PARAM_DST_GAIN(in->ID(), chan, dst), B_MEDIA_RAW_AUDIO,
StringForChannelType(buf, dst), B_GAIN, "%", 0.0, 100.0, 1.0); StringForChannelType(buf, dst), B_GAIN, "%", 0.0, 100.0, 1.0);
} }
} }
} }
#endif
fCore->Unlock(); fCore->Unlock();
@@ -492,7 +492,7 @@ MixerCore::MixThread()
for (int i = 0; i < sourcecount; i++) { for (int i = 0; i < sourcecount; i++) {
int type; int type;
float gain; float gain;
fOutput->GetMixerChannelInfo(chan, i, &type, &gain); fOutput->GetOutputChannelSourceInfoAt(chan, i, &type, &gain);
if (type < 0 || type >= MAX_CHANNEL_TYPES) if (type < 0 || type >= MAX_CHANNEL_TYPES)
continue; continue;
int count = InputChanInfos[type].CountItems(); int count = InputChanInfos[type].CountItems();
@@ -70,11 +70,11 @@ MixerOutput::UpdateOutputChannels()
fOutputChannelCount = fOutput.format.u.raw_audio.channel_count; fOutputChannelCount = fOutput.format.u.raw_audio.channel_count;
fOutputChannelInfo = new output_chan_info[fOutputChannelCount]; fOutputChannelInfo = new output_chan_info[fOutputChannelCount];
for (int i = 0; i < fOutputChannelCount; i++) { for (int i = 0; i < fOutputChannelCount; i++) {
fOutputChannelInfo[i].designation = GetChannelMask(i, fOutput.format.u.raw_audio.channel_mask); fOutputChannelInfo[i].channel_type = GetChannelType(i, fOutput.format.u.raw_audio.channel_mask);
fOutputChannelInfo[i].gain = 1.0; fOutputChannelInfo[i].channel_gain = 1.0;
fOutputChannelInfo[i].source_count = 1; fOutputChannelInfo[i].source_count = 1;
fOutputChannelInfo[i].source_gain[0] = 1.0; fOutputChannelInfo[i].source_gain[0] = 1.0;
fOutputChannelInfo[i].source_type[0] = ChannelMaskToChannelType(fOutputChannelInfo[i].designation); fOutputChannelInfo[i].source_type[0] = fOutputChannelInfo[i].channel_type;
} }
AssignDefaultSources(); AssignDefaultSources();
@@ -82,8 +82,8 @@ MixerOutput::UpdateOutputChannels()
if (oldInfo != 0 && oldCount != 0) { if (oldInfo != 0 && oldCount != 0) {
for (int i = 0; i < fOutputChannelCount; i++) { for (int i = 0; i < fOutputChannelCount; i++) {
for (int j = 0; j < oldCount; j++) { for (int j = 0; j < oldCount; j++) {
if (fOutputChannelInfo[i].designation == oldInfo[j].designation) { if (fOutputChannelInfo[i].channel_type == oldInfo[j].channel_type) {
fOutputChannelInfo[i].gain == oldInfo[j].gain; fOutputChannelInfo[i].channel_gain == oldInfo[j].channel_gain;
fOutputChannelInfo[i].source_count == oldInfo[j].source_count; fOutputChannelInfo[i].source_count == oldInfo[j].source_count;
for (int k = 0; k < fOutputChannelInfo[i].source_count; k++) { for (int k = 0; k < fOutputChannelInfo[i].source_count; k++) {
fOutputChannelInfo[i].source_gain[k] == oldInfo[j].source_gain[k]; fOutputChannelInfo[i].source_gain[k] == oldInfo[j].source_gain[k];
@@ -217,7 +217,7 @@ MixerOutput::AssignDefaultSources()
for (int i = 0; i < fOutputChannelCount; i++) { for (int i = 0; i < fOutputChannelCount; i++) {
for (int j = 0; j < fOutputChannelInfo[i].source_count; j++) { for (int j = 0; j < fOutputChannelInfo[i].source_count; j++) {
TRACE("AssignDefaultSources: output channel %d, source %d: des 0x%08X (type %2d), gain %.3f\n", i, j, ChannelTypeToChannelMask(fOutputChannelInfo[i].source_type[j]), fOutputChannelInfo[i].source_type[j], fOutputChannelInfo[i].source_gain[j]); TRACE("AssignDefaultSources: output channel %d, source index %d: source_type %2d, source_gain %.3f\n", i, j, fOutputChannelInfo[i].source_type[j], fOutputChannelInfo[i].source_gain[j]);
} }
} }
} }
@@ -227,7 +227,7 @@ MixerOutput::GetOutputChannelType(int channel)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return 0; return 0;
return ChannelMaskToChannelType(fOutputChannelInfo[channel].designation); return fOutputChannelInfo[channel].channel_type;
} }
void void
@@ -236,17 +236,16 @@ MixerOutput::SetOutputChannelGain(int channel, float gain)
TRACE("SetOutputChannelGain chan %d, gain %.5f\n", channel, gain); TRACE("SetOutputChannelGain chan %d, gain %.5f\n", channel, gain);
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return;
fOutputChannelInfo[channel].gain = gain; fOutputChannelInfo[channel].channel_gain = gain;
} }
void void
MixerOutput::AddOutputChannelSource(int channel, uint32 source_designation, float source_gain) MixerOutput::AddOutputChannelSource(int channel, int source_type, float source_gain)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return;
if (fOutputChannelInfo[channel].source_count == MAX_SOURCES) if (fOutputChannelInfo[channel].source_count == MAX_SOURCE_ENTRIES)
return; return;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) if (fOutputChannelInfo[channel].source_type[i] == source_type)
return; return;
@@ -257,11 +256,10 @@ MixerOutput::AddOutputChannelSource(int channel, uint32 source_designation, floa
} }
void void
MixerOutput::RemoveOutputChannelSource(int channel, uint32 source_designation) MixerOutput::RemoveOutputChannelSource(int channel, int source_type)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
fOutputChannelInfo[channel].source_type[i] = fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count - 1]; fOutputChannelInfo[channel].source_type[i] = fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count - 1];
@@ -272,47 +270,44 @@ MixerOutput::RemoveOutputChannelSource(int channel, uint32 source_designation)
} }
} }
void bool
MixerOutput::SetOutputChannelSourceGain(int channel, uint32 source_designation, float source_gain) MixerOutput::SetOutputChannelSourceGain(int channel, int source_type, float source_gain)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return false;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
fOutputChannelInfo[channel].source_gain[i] = source_gain; fOutputChannelInfo[channel].source_gain[i] = source_gain;
return; return true;
} }
} }
return false;
} }
float float
MixerOutput::GetOutputChannelSourceGain(int channel, uint32 source_designation) MixerOutput::GetOutputChannelSourceGain(int channel, int source_type)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return 1.0; return 0.0;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
return fOutputChannelInfo[channel].source_gain[i]; return fOutputChannelInfo[channel].source_gain[i];
} }
} }
return 1.0; return 0.0;
} }
void bool
MixerOutput::GetOutputChannelSourceAt(int channel, int index, uint32 *source_designation, float *source_gain) MixerOutput::HasOutputChannelSource(int channel, int source_type)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return false;
if (index >= fOutputChannelInfo[channel].source_count) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
// ERROR if (fOutputChannelInfo[channel].source_type[i] == source_type) {
*source_gain = 1.0; return true;
*source_designation = 0; }
return;
} }
*source_gain = fOutputChannelInfo[channel].source_gain[index]; return false;
*source_designation = ChannelTypeToChannelMask(fOutputChannelInfo[channel].source_type[index]);
} }
void void
@@ -3,11 +3,15 @@
#include "debug.h" #include "debug.h"
#include "ByteSwap.h" #include "ByteSwap.h"
#include "MixerCore.h"
#include <Buffer.h> #include <Buffer.h>
#define MAX_SOURCES 20 /* The data storage for channel sources is optimized
* for fast data retrieval by the MixerCore, which
class MixerCore; * will call GetOutputChannelSourceInfoAt() and
* iterate through the first source_count array entries
* for source_gain[] and source_type[]
*/
class MixerOutput class MixerOutput
{ {
@@ -19,24 +23,31 @@ public:
void ChangeFormat(const media_multi_audio_format &format); void ChangeFormat(const media_multi_audio_format &format);
uint32 GetOutputChannelCount(); // The physical output channels
uint32 GetOutputChannelType(int channel); uint32 GetOutputChannelCount();
void SetOutputChannelGain(int channel, float gain); uint32 GetOutputChannelType(int channel);
float GetOutputChannelGain(int channel); void SetOutputChannelGain(int channel, float gain);
float GetOutputChannelGain(int channel);
uint32 GetOutputChannelSourceCount(int channel); // The Sources for each channel
void AddOutputChannelSource(int channel, uint32 source_designation, float source_gain); void AddOutputChannelSource(int channel, int source_type, float source_gain);
void RemoveOutputChannelSource(int channel, uint32 source_designation); void RemoveOutputChannelSource(int channel, int source_type);
void SetOutputChannelSourceGain(int channel, uint32 source_designation, float source_gain); bool SetOutputChannelSourceGain(int channel, int source_type, float source_gain);
float GetOutputChannelSourceGain(int channel, uint32 source_designation); float GetOutputChannelSourceGain(int channel, int source_type);
void GetOutputChannelSourceAt(int channel, int index, uint32 *source_designation, float *source_gain); bool HasOutputChannelSource(int channel, int source_type);
void SetMuted(bool yesno); // The Output can be muted
bool IsMuted(); void SetMuted(bool yesno);
bool IsMuted();
// only for use by MixerCore // Only for use by MixerCore:
void GetMixerChannelInfo(int channel, int index, int *type, float *gain);
void AdjustByteOrder(BBuffer *buffer); // For iteration of a channel's sources
uint32 GetOutputChannelSourceCount(int channel);
void GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain);
// To swap byteorder in a buffer is that is needed
void AdjustByteOrder(BBuffer *buffer);
private: private:
void UpdateByteOrderSwap(); void UpdateByteOrderSwap();
@@ -44,12 +55,20 @@ private:
void AssignDefaultSources(); void AssignDefaultSources();
private: private:
/* An entry in the source array is not the same as the
* channel type, but the number should be the same
*/
enum {
MAX_SOURCE_ENTRIES = MAX_CHANNEL_TYPES
};
struct output_chan_info { struct output_chan_info {
uint32 designation; // only one bit set int channel_type;
float gain; float channel_gain;
int source_count; int source_count;
float source_gain[MAX_SOURCES]; float source_gain[MAX_SOURCE_ENTRIES];
int source_type[MAX_SOURCES]; int source_type[MAX_SOURCE_ENTRIES];
}; };
MixerCore *fCore; MixerCore *fCore;
@@ -71,7 +90,7 @@ inline float MixerOutput::GetOutputChannelGain(int channel)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return 1.0; return 1.0;
return fOutputChannelInfo[channel].gain; return fOutputChannelInfo[channel].channel_gain;
} }
inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel) inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel)
@@ -81,12 +100,12 @@ inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel)
return fOutputChannelInfo[channel].source_count; return fOutputChannelInfo[channel].source_count;
} }
inline void MixerOutput::GetMixerChannelInfo(int channel, int index, int *type, float *gain) inline void MixerOutput::GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain)
{ {
ASSERT(channel >= 0 && channel < fOutputChannelCount); ASSERT(channel >= 0 && channel < fOutputChannelCount);
ASSERT(index >= 0 && index < fOutputChannelInfo[channel].source_count); ASSERT(index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
*type = fOutputChannelInfo[channel].source_type[index]; *source_type = fOutputChannelInfo[channel].source_type[source_index];
*gain = fOutputChannelInfo[channel].source_gain[index]; *source_gain = fOutputChannelInfo[channel].source_gain[source_index];
} }
inline void MixerOutput::AdjustByteOrder(BBuffer *buffer) inline void MixerOutput::AdjustByteOrder(BBuffer *buffer)
@@ -158,6 +158,12 @@ uint32 ChannelTypeToChannelMask(int type)
return 1 << type; return 1 << type;
} }
int
GetChannelType(int channel, uint32 all_channel_masks)
{
return ChannelMaskToChannelType(GetChannelMask(channel, all_channel_masks));
}
bool bool
HasKawamba() HasKawamba()
{ {
@@ -15,6 +15,7 @@ void fix_multiaudio_format(media_multi_audio_format *format);
int count_nonzero_bits(uint32 value); int count_nonzero_bits(uint32 value);
uint32 GetChannelMask(int channel, uint32 all_channel_masks); uint32 GetChannelMask(int channel, uint32 all_channel_masks);
int GetChannelType(int channel, uint32 all_channel_masks);
bool HasKawamba(); bool HasKawamba();