diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp index 7fa011a495..4cc565a5d0 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -278,6 +278,13 @@ MixerCore::EnableOutput(bool enabled) StartMixThread(); } +uint32 +MixerCore::OutputChannelCount() +{ + return (fOutput) ? fOutput->GetOutputChannelCount() : 0; +} + + bool MixerCore::Start() { diff --git a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp index 619112b338..35a68bd039 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp @@ -287,13 +287,39 @@ MixerInput::UpdateChannelDesignations() printf("UpdateChannelDesignations: enter\n"); - if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) { - // a left or right channel get's output as stereo on both - fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; - } else { - // everything else get's mapped 1:1 - for (int i = 0; i < fInputChannelCount; i++) - fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask); + // first apply a 1:1 mapping + for (int i = 0; i < fInputChannelCount; i++) + fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask); + + // specialize this, depending on the available physical output channels + switch (fCore->OutputChannelCount()) { + case 0: + case 1: + break; + + case 2: + if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) { + fInputChannelInfo[0].designations = 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; + } + if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_LEFT)) { + fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT; + } + if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_RIGHT)) { + fInputChannelInfo[0].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT; + } + if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_LEFT)) { + fInputChannelInfo[1].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT; + } + if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_RIGHT)) { + fInputChannelInfo[1].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT; + } + break; } for (int i = 0; i < fInputChannelCount; i++) diff --git a/src/add-ons/media/media-add-ons/mixer/MixerOutput.cpp b/src/add-ons/media/media-add-ons/mixer/MixerOutput.cpp index e3f39eed78..2e7bb1b05a 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerOutput.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerOutput.cpp @@ -82,7 +82,118 @@ MixerOutput::UpdateOutputChannels() void MixerOutput::AssignDefaultSources() { - // XXX assign default sources + uint32 mask = fOutput.format.u.raw_audio.channel_mask; + uint32 count = fOutputChannelCount; + + // assign default sources for a few known setups, + // everything else is left unchanged (it already is 1:1) + + if (count == 1 && mask & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT)) { + // we have only one phycial output channel, and use it as a mix of + // left, right, rear-left, rear-right, center and sub + printf("AssignDefaultSources: 1 channel setup\n"); + fOutputChannelInfo[0].source_count = 6; + fOutputChannelInfo[0].source_gain[0] = 1.0; + fOutputChannelInfo[0].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_LEFT); + fOutputChannelInfo[0].source_gain[1] = 1.0; + fOutputChannelInfo[0].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_RIGHT); + fOutputChannelInfo[0].source_gain[2] = 0.8; + fOutputChannelInfo[0].source_type[2] = ChannelMaskToChannelType(B_CHANNEL_REARLEFT); + fOutputChannelInfo[0].source_gain[3] = 0.8; + fOutputChannelInfo[0].source_type[3] = ChannelMaskToChannelType(B_CHANNEL_REARRIGHT); + fOutputChannelInfo[0].source_gain[4] = 0.7; + fOutputChannelInfo[0].source_type[4] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[0].source_gain[5] = 0.6; + fOutputChannelInfo[0].source_type[5] = ChannelMaskToChannelType(B_CHANNEL_SUB); + } else if (count == 2 && mask == (B_CHANNEL_LEFT | B_CHANNEL_RIGHT)) { + // we have have two phycial output channels + printf("AssignDefaultSources: 2 channel setup\n"); + // left channel: + fOutputChannelInfo[0].source_count = 4; + fOutputChannelInfo[0].source_gain[0] = 1.0; + fOutputChannelInfo[0].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_LEFT); + fOutputChannelInfo[0].source_gain[1] = 0.8; + fOutputChannelInfo[0].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_REARLEFT); + fOutputChannelInfo[0].source_gain[2] = 0.7; + fOutputChannelInfo[0].source_type[2] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[0].source_gain[3] = 0.6; + fOutputChannelInfo[0].source_type[3] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // right channel: + fOutputChannelInfo[1].source_count = 4; + fOutputChannelInfo[1].source_gain[0] = 1.0; + fOutputChannelInfo[1].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_RIGHT); + fOutputChannelInfo[1].source_gain[1] = 0.8; + fOutputChannelInfo[1].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_REARRIGHT); + fOutputChannelInfo[1].source_gain[2] = 0.7; + fOutputChannelInfo[1].source_type[2] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[1].source_gain[3] = 0.6; + fOutputChannelInfo[1].source_type[3] = ChannelMaskToChannelType(B_CHANNEL_SUB); + } else if (count == 4 && mask == (B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT)) { + printf("AssignDefaultSources: 4 channel setup\n"); + // left channel: + fOutputChannelInfo[0].source_count = 3; + fOutputChannelInfo[0].source_gain[0] = 1.0; + fOutputChannelInfo[0].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_LEFT); + fOutputChannelInfo[0].source_gain[1] = 0.7; + fOutputChannelInfo[0].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[0].source_gain[2] = 0.6; + fOutputChannelInfo[0].source_type[2] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // right channel: + fOutputChannelInfo[1].source_count = 3; + fOutputChannelInfo[1].source_gain[0] = 1.0; + fOutputChannelInfo[1].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_RIGHT); + fOutputChannelInfo[1].source_gain[1] = 0.7; + fOutputChannelInfo[1].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[1].source_gain[2] = 0.6; + fOutputChannelInfo[1].source_type[2] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // rear-left channel: + fOutputChannelInfo[2].source_count = 2; + fOutputChannelInfo[2].source_gain[0] = 1.0; + fOutputChannelInfo[2].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_REARLEFT); + fOutputChannelInfo[2].source_gain[1] = 0.6; + fOutputChannelInfo[2].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // rear-right channel: + fOutputChannelInfo[3].source_count = 2; + fOutputChannelInfo[3].source_gain[0] = 1.0; + fOutputChannelInfo[3].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_REARRIGHT); + fOutputChannelInfo[3].source_gain[1] = 0.6; + fOutputChannelInfo[3].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + } else if (count == 5 && mask == (B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT | B_CHANNEL_CENTER)) { + printf("AssignDefaultSources: 5 channel setup\n"); + // left channel: + fOutputChannelInfo[0].source_count = 2; + fOutputChannelInfo[0].source_gain[0] = 1.0; + fOutputChannelInfo[0].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_LEFT); + fOutputChannelInfo[0].source_gain[1] = 0.6; + fOutputChannelInfo[0].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // right channel: + fOutputChannelInfo[1].source_count = 2; + fOutputChannelInfo[1].source_gain[0] = 1.0; + fOutputChannelInfo[1].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_RIGHT); + fOutputChannelInfo[1].source_gain[1] = 0.6; + fOutputChannelInfo[1].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // rear-left channel: + fOutputChannelInfo[2].source_count = 2; + fOutputChannelInfo[2].source_gain[0] = 1.0; + fOutputChannelInfo[2].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_REARLEFT); + fOutputChannelInfo[2].source_gain[1] = 0.6; + fOutputChannelInfo[2].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // rear-right channel: + fOutputChannelInfo[3].source_count = 2; + fOutputChannelInfo[3].source_gain[0] = 1.0; + fOutputChannelInfo[3].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_REARRIGHT); + fOutputChannelInfo[3].source_gain[1] = 0.6; + fOutputChannelInfo[3].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + // center channel: + fOutputChannelInfo[4].source_count = 2; + fOutputChannelInfo[4].source_gain[0] = 1.0; + fOutputChannelInfo[4].source_type[0] = ChannelMaskToChannelType(B_CHANNEL_CENTER); + fOutputChannelInfo[4].source_gain[1] = 0.5; + fOutputChannelInfo[4].source_type[1] = ChannelMaskToChannelType(B_CHANNEL_SUB); + } else { + printf("AssignDefaultSources: no default setup\n"); + } + for (int i = 0; i < fOutputChannelCount; i++) { for (int j = 0; j < fOutputChannelInfo[i].source_count; j++) { printf("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]);