Adds digital audio output volume control for DMPS to bridge

This commit is contained in:
Alex Johnson
2022-06-14 10:13:02 -04:00
parent dfc0915fe0
commit 60b6cea697
3 changed files with 179 additions and 97 deletions

View File

@@ -17,6 +17,10 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MixerEqPresetRecall")]
public JoinDataComplete MixerEqPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Eq Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MasterVolumeMuteOn")] [JoinName("MasterVolumeMuteOn")]
public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });

View File

@@ -33,36 +33,44 @@ namespace PepperDash.Essentials.DM
: base(key, name) : base(key, name)
{ {
OutputCard = card; OutputCard = card;
OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange); OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
if (card is Card.Dmps3ProgramOutput) if (card is Card.Dmps3ProgramOutput)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3ProgramOutput).OutputMixer); var output = card as Card.Dmps3ProgramOutput;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(card, eDmpsLevelType.Master, output.OutputMixer, output.OutputEqualizer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2);
} }
else if (card is Card.Dmps3Aux1Output) else if (card is Card.Dmps3Aux1Output)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux1Output).OutputMixer); var output = card as Card.Dmps3Aux1Output;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(card, eDmpsLevelType.Master, output.OutputMixer, output.OutputEqualizer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2);
} }
else if (card is Card.Dmps3Aux2Output) else if (card is Card.Dmps3Aux2Output)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux2Output).OutputMixer); var output = card as Card.Dmps3Aux2Output;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(card, eDmpsLevelType.Master, output.OutputMixer, output.OutputEqualizer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1);
} }
else //Digital Outputs else if (card is Card.Dmps3DigitalMixOutput)
{ {
MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); var output = card as Card.Dmps3DigitalMixOutput;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, output.OutputMixer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); }
else if (card is Card.Dmps3HdmiOutput)
{
var output = card as Card.Dmps3HdmiOutput;
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, output.OutputMixer);
}
else if (card is Card.Dmps3DmOutput)
{
var output = card as Card.Dmps3DmOutput;
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, output.OutputMixer);
} }
} }
@@ -185,6 +193,11 @@ namespace PepperDash.Essentials.DM
{ {
trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset); trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset);
} }
var eq = MasterVolumeLevel as DmpsAudioOutputWithMixerAndEq;
if (eq != null)
{
trilist.SetUShortSigAction(joinMap.MixerEqPresetRecall.JoinNumber, eq.RecallEqPreset);
}
} }
if (SourceVolumeLevel != null) if (SourceVolumeLevel != null)
@@ -234,11 +247,27 @@ namespace PepperDash.Essentials.DM
} }
} }
public class DmpsAudioOutputWithMixerAndEq : DmpsAudioOutputWithMixer
{
private CrestronControlSystem.Dmps3OutputEqualizer Eq;
public DmpsAudioOutputWithMixerAndEq(Card.Dmps3OutputBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputMixer mixer, CrestronControlSystem.Dmps3OutputEqualizer eq)
: base(output, type, mixer)
{
Eq = eq;
}
public void RecallEqPreset(ushort preset)
{
Eq.PresetNumber.UShortValue = preset;
Eq.RecallPreset();
}
}
public class DmpsAudioOutputWithMixer : DmpsAudioOutput public class DmpsAudioOutputWithMixer : DmpsAudioOutput
{ {
CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer; IDmps3OutputMixer Mixer;
public DmpsAudioOutputWithMixer(Card.Dmps3OutputBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo mixer) public DmpsAudioOutputWithMixer(Card.Dmps3OutputBase output, eDmpsLevelType type, IDmps3OutputMixer mixer)
: base(output, type) : base(output, type)
{ {
Mixer = mixer; Mixer = mixer;
@@ -266,23 +295,47 @@ namespace PepperDash.Essentials.DM
public void RecallPreset(ushort preset) public void RecallPreset(ushort preset)
{ {
if (Mixer is CrestronControlSystem.Dmps3OutputMixer)
{
var presetMixer = Mixer as CrestronControlSystem.Dmps3OutputMixer;
Debug.Console(1, "DMPS Recalling Preset {0}", preset); Debug.Console(1, "DMPS Recalling Preset {0}", preset);
Mixer.PresetNumber.UShortValue = preset; presetMixer.PresetNumber.UShortValue = preset;
Mixer.RecallPreset(); presetMixer.RecallPreset();
//Recall startup volume for main volume level as DMPS3(non-4K) presets don't affect the main volume
RecallStartupVolume();
}
else if (Mixer is CrestronControlSystem.Dmps3AttachableOutputMixer)
{
var presetMixer = Mixer as CrestronControlSystem.Dmps3AttachableOutputMixer;
Debug.Console(1, "DMPS Recalling Preset {0}", preset);
presetMixer.PresetNumber.UShortValue = preset;
presetMixer.RecallPreset();
}
}
public void RecallStartupVolume()
{
ushort startupVol = Mixer.StartupVolumeFeedback.UShortValue;
//Reset startup vol due to bug on DMPS3 where getting the value from above method clears the startup volume
Mixer.StartupVolume.UShortValue = startupVol;
Debug.Console(1, "DMPS Recalling {0} Startup Volume {1}", Output.Name, startupVol);
SetVolume(startupVol);
MuteOff();
} }
} }
public class DmpsAudioOutput : IBasicVolumeWithFeedback public class DmpsAudioOutput : IBasicVolumeWithFeedback
{ {
Card.Dmps3OutputBase Output; private UShortInputSig Level;
eDmpsLevelType Type; protected Card.Dmps3OutputBase Output;
UShortInputSig Level;
private bool EnableVolumeSend; private bool EnableVolumeSend;
private ushort VolumeLevelInput; private ushort VolumeLevelInput;
protected short MinLevel { get; set; } protected short MinLevel { get; set; }
protected short MaxLevel { get; set; } protected short MaxLevel { get; set; }
public eDmpsLevelType Type { get; private set; }
public BoolFeedback MuteFeedback { get; private set; } public BoolFeedback MuteFeedback { get; private set; }
public IntFeedback VolumeLevelFeedback { get; private set; } public IntFeedback VolumeLevelFeedback { get; private set; }
public IntFeedback VolumeLevelScaledFeedback { get; private set; } public IntFeedback VolumeLevelScaledFeedback { get; private set; }
@@ -411,19 +464,28 @@ namespace PepperDash.Essentials.DM
public void SetVolumeScaled(ushort level) public void SetVolumeScaled(ushort level)
{ {
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString());
if (ushort.MaxValue + MinLevel != 0)
{
VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel);
if (EnableVolumeSend == true) if (EnableVolumeSend == true)
{ {
Level.UShortValue = VolumeLevelInput; Level.UShortValue = VolumeLevelInput;
} }
} }
}
public ushort ScaleVolumeFeedback(ushort level) public ushort ScaleVolumeFeedback(ushort level)
{ {
short signedLevel = (short)level; short signedLevel = (short)level;
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString()); Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString());
if (MaxLevel - MinLevel != 0)
{
return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel));
} }
else
return (ushort)MinLevel;
}
public void SendScaledVolume(bool pressRelease) public void SendScaledVolume(bool pressRelease)
{ {

View File

@@ -480,6 +480,8 @@ namespace PepperDash.Essentials.DM
void SetupOutputCards() void SetupOutputCards()
{ {
foreach (var card in Dmps.SwitcherOutputs) foreach (var card in Dmps.SwitcherOutputs)
{
try
{ {
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType); Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
@@ -545,6 +547,11 @@ namespace PepperDash.Essentials.DM
AddOutputCard(outputCard.Number, outputCard); AddOutputCard(outputCard.Number, outputCard);
} }
catch (Exception ex)
{
Debug.LogError(Debug.ErrorLogLevel.Error, string.Format("DMPS Controller exception creating output card: {0}", ex));
}
}
} }
/// <summary> /// <summary>
@@ -697,6 +704,9 @@ namespace PepperDash.Essentials.DM
var cecPort = hdmiOutputCard.HdmiOutputPort; var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort); AddHdmiOutputPort(number, cecPort);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Hdmi Audio Output {0}", number), outputCard as Card.Dmps3HdmiOutput);
DeviceManager.AddDevice(audioOutput);
} }
else if (outputCard is Card.Dmps3HdmiOutputBackend) else if (outputCard is Card.Dmps3HdmiOutputBackend)
{ {
@@ -709,6 +719,9 @@ namespace PepperDash.Essentials.DM
else if (outputCard is Card.Dmps3DmOutput) else if (outputCard is Card.Dmps3DmOutput)
{ {
AddDmOutputPort(number); AddDmOutputPort(number);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Dm Audio Output {0}", number), outputCard as Card.Dmps3DmOutput);
DeviceManager.AddDevice(audioOutput);
} }
else if (outputCard is Card.Dmps3DmOutputBackend) else if (outputCard is Card.Dmps3DmOutputBackend)
{ {
@@ -766,6 +779,10 @@ namespace PepperDash.Essentials.DM
{ {
AddAudioOnlyOutputPort(number, "Dialer"); AddAudioOnlyOutputPort(number, "Dialer");
} }
else if (outputCard is Card.Dmps3AecOutput)
{
AddAudioOnlyOutputPort(number, "Aec");
}
else if (outputCard is Card.Dmps3DigitalMixOutput) else if (outputCard is Card.Dmps3DigitalMixOutput)
{ {
if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix1 if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix1
@@ -776,10 +793,9 @@ namespace PepperDash.Essentials.DM
|| number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2 || number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2
|| number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2) || number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2)
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString()); AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
}
else if (outputCard is Card.Dmps3AecOutput) var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number % 2 + 1), string.Format("Digital Audio Output {0}", number % 2 + 1), outputCard as Card.Dmps3DigitalMixOutput);
{ DeviceManager.AddDevice(audioOutput);
AddAudioOnlyOutputPort(number, "Aec");
} }
else else
{ {