Skip to content

Instantly share code, notes, and snippets.

@imorrish
Last active November 29, 2018 22:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imorrish/5614d4369ca111f7096aff31d27e4d98 to your computer and use it in GitHub Desktop.
Save imorrish/5614d4369ca111f7096aff31d27e4d98 to your computer and use it in GitHub Desktop.
# Sample script using midi device to control Blackmagic ATEM Upstream Key Chroma settings
# Uses these 2 projects
# https://ianmorrish.wordpress.com/v-ise/atem/
# https://github.com/Psychlist1972/Windows-10-PowerShell-MIDI
#
add-type -path 'documents\windowspowershell\SwitcherLib.dll'
Import-Module ".\Documents\WindowsPowerShell\PeteBrown.PowerShellMidi.dll"
#region ATEM settings
$Global:atem = New-Object SwitcherLib.Switcher("192.168.1.8")
$atem.Connect()
$MEs = $atem.GetMEs()
$Global:ME1 = $MEs[0]
$USKs = $atem.GetKeys()
$Global:usk1=$USKs[0]
$Global:usk1.Type="Chroma"
$Global:usk1.ChromaNarrow = 1
$Global:usk1.InputFill = 3020 #MediaPlayer2
#endregion
$Global:Debug = $false
$global:AdjustmentFactor = 1
#Find the input and output device ID's
#Use script "list-midi-examples.ps1" to find name string for your device(s)
$inputDevices = Get-MidiInputDeviceInformation
foreach ($device in $inputDevices){
if ($device.Name -eq "CMD DC-1 [1]"){
Write-Host $device.Name
$MidiINID = $device.Id
}
}
$outputDevices = Get-MidiOutputDeviceInformation
foreach ($device in $outputDevices){
If ($device.Name -eq "CMD DC-1 [0]"){
[string]$MidiOutID = $device.Id
}
}
[PeteBrown.PowerShellMidi.MidiInputPort]$inputPort = Get-MidiInputPort -id $MidiINID
$outputPort = Get-MidiOutputPort -id $MidiOutID
# this is just an identifier for our own use. It can be anything, but must
# be unique for each event subscription.
$noteOnSourceId = "NoteOnMessageReceivedID"
$controlChangeSourceId = "ControlChangeMessageReceivedID"
# remove the event if we are running this more than once in the same session.
#Write-Host "Unregistering existing event handlers ----------------------------------------- "
Unregister-Event -SourceIdentifier $noteOnSourceId -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier $controlChangeSourceId -ErrorAction SilentlyContinue
# register for the event
#Write-Host "Registering for input port .net object events --------------------------------- "
# Note-on event handler script block
function HandleNoteOn($event)
{
if(Global:Debug){
Write-Host " "
Write-Host "Powershell: MIDI Note-on message received" -ForegroundColor Cyan -BackgroundColor Black
Write-Host " Channel: " -NoNewline -ForegroundColor DarkGray; Write-Host $event.Channel -ForegroundColor Red
Write-Host " Note: " -NoNewline -ForegroundColor DarkGray; Write-Host $event.Note -ForegroundColor Red
Write-Host " Velocity: " -NoNewline -ForegroundColor DarkGray; Write-Host $event.Velocity -ForegroundColor Red
}
if($event.Velocity -eq 127){
#switch($event.sourceEventArgs.Note){
switch($event.Note){
0 {
if($usk1.OnAir){#Toggle USK on-air
$usk1.OnAir = 0
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 0 -Velocity 0
}
else{
$usk1.OnAir = 1
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 0 -Velocity 1
}
}
1 {
if($Global:AdjustmentFactor -eq 1){#Toggle AdjustmentFactor
$Global:AdjustmentFactor= .1
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 1 -Velocity 1
}
else{
$Global:AdjustmentFactor = 1
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 1 -Velocity 0
}
}
2 {
if($usk1.Masked){#Toggle Mask
$usk1.Masked = 0
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 2 -Velocity 0
}
else{
$usk1.Masked = 1
Send-MidiNoteOnMessage -Port $outputPort -Channel 0 -Note 2 -Velocity 1
}
}
}
}
}
$HandleControlChange =
{
#Chroma Key values (Hue, Gain, Y Sup, Lift
switch ($event.sourceEventArgs.Controller){
16{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.ChromaHue = $usk1.ChromaHue + $global:AdjustmentFactor
}
else{#decrease value
$usk1.ChromaHue = $usk1.ChromaHue - $global:AdjustmentFactor
}
Write-Host " Hue changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.ChromaHue -ForegroundColor Red
}
17{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.ChromaGain = $usk1.ChromaGain + ($global:AdjustmentFactor/100)
}
else{#decrease value
$usk1.ChromaGain = $usk1.ChromaGain - ($global:AdjustmentFactor/100)
}
Write-Host " Gain changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.ChromaGain -ForegroundColor Red
}
18{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.ChromaYSuppress = $usk1.ChromaYSuppress + ($global:AdjustmentFactor/100)
}
else{#decrease value
$usk1.ChromaYSuppress = $usk1.ChromaYSuppress - ($global:AdjustmentFactor/100)
}
Write-Host " Y Supp changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.ChromaYSuppress -ForegroundColor Red
}
19{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.ChromaLift = $usk1.ChromaLift + ($global:AdjustmentFactor/100)
}
else{#decrease value
$usk1.ChromaLift = $usk1.ChromaLift - ($global:AdjustmentFactor/100)
}
Write-Host " Lift changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.ChromaLift -ForegroundColor Red
}
20{# Mask Top
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.MaskTop = $usk1.MaskTop + $global:AdjustmentFactor
}
else{#decrease value
$usk1.MaskTop = $usk1.MaskTop - $global:AdjustmentFactor
}
Write-Host " Mask Top changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.MaskTop -ForegroundColor Red
}
21{#Mask Left
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.MaskLeft = $usk1.MaskLeft + $global:AdjustmentFactor
}
else{#decrease value
$usk1.MaskLeft = $usk1.MaskLeft - $global:AdjustmentFactor
}
Write-Host " MaskLeft changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.MaskLeft -ForegroundColor Red
}
22{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.MaskBottom = $usk1.MaskBottom + $global:AdjustmentFactor
}
else{#decrease value
$usk1.MaskBottom = $usk1.MaskBottom - $global:AdjustmentFactor
}
Write-Host " MaskBottom changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.MaskBottom -ForegroundColor Red
}
23{
if($event.sourceEventArgs.Value -eq 65)
{#increase value
$usk1.MaskRight = $usk1.MaskRight + $global:AdjustmentFactor
}
else{#decrease value
$usk1.MaskRight = $usk1.MaskRight - $global:AdjustmentFactor
}
Write-Host " MaskRight changed: " -NoNewline -ForegroundColor DarkGray; Write-Host $usk1.MaskRight -ForegroundColor Red
}
}
}
# Actually register the events
$job1 = Register-ObjectEvent -InputObject $inputPort -EventName NoteOnMessageReceived -SourceIdentifier $noteOnSourceId -Action {HandleNoteOn($event.sourceEventArgs)}
$job2 = Register-ObjectEvent -InputObject $inputPort -EventName NoteOffMessageReceived -SourceIdentifier $noteOffSourceId -Action $HandleNoteOff
$job3 = Register-ObjectEvent -InputObject $inputPort -EventName ControlChangeMessageReceived -SourceIdentifier $controlChangeSourceId -Action $HandleControlChange
$job4 = Register-ObjectEvent -InputObject $inputPort -EventName PitchBendChangeMessageReceived -SourceIdentifier $pitchBendChangeSourceId -Action $HandlePitchBendChange
#ISE will now wait for midi events
#Video demo of script in use https://youtu.be/07l8VHP_DWs
#Connect to ATEM
add-type -path 'documents\windowspowershell\SwitcherLib6.9b.dll'
$Global:atem = New-Object SwitcherLib.Switcher("192.168.1.8")
$atem.Connect()
$Global:mes=$atem.GetMEs()
$Global:me = $Global:mes[0]
$Global:activeME = $Global:mes[0]
$Global:usks=$atem.getKeys()
$Global:USK1 = $Global:usks[0]
#Get the CMD Micro midi controller
Import-Module ".\Documents\WindowsPowerShell\PeteBrown.PowerShellMidi.dll"
[string]$MidiInID = ""
$inputDevices = Get-MidiInputDeviceInformation
$inputDevices
foreach ($device in $inputDevices)
{
#if ($device.Name -eq "CMD Micro")
if ($device.Name -eq "CMD DC-1 [1]")
{
$MidiInID = $device.Id
write-host $device.Id
}
}
[string]$MidiOutID = ""
$outputDevices = Get-MidiOutputDeviceInformation
$outputDevices
foreach ($device in $outputDevices)
{
#if ($device.Name -eq "CMD Micro")
if ($device.Name -eq "CMD DC-1 [0]")
{
$MidiOutID = $device.Id
write-host $device.Id
}
}
[PeteBrown.PowerShellMidi.MidiInputPort]$inputPort = Get-MidiInputPort -id $MidiInID
$outputPort = Get-MidiOutputPort -id $MidiOutID
# set this to false if you don't want the input port to translate a zero velocity note on message into a note off message
$inputPort.TranslateZeroVelocityNoteOnMessage = $true;
# this is just an identifier for our own use. It can be anything, but must be unique for each event subscription.
$noteOnSourceId = "NoteOnMessageReceivedID"
$noteOffSourceId = "NoteOffMessageReceivedID"
$controlChangeSourceId = "ControlChangeMessageReceivedID"
$pitchBendChangeSourceId = "PitchBendChangeMessageReceivedID"
# remove the event if we are running this more than once in the same session.
Unregister-Event -SourceIdentifier $noteOnSourceId -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier $noteOffSourceId -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier $controlChangeSourceId -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier $pitchBendChangeSourceId -ErrorAction SilentlyContinue
# register for the event
 
$HandleNoteOn =
{
write-host $event.sourceEventArgs.Note
switch ($event.sourceEventArgs.Note) {
36{$ME.Program = 1}
37{$ME.Program = 2}
38{$ME.Program = 3}
39{$ME.Program = 4}
40{$ME.Program = 5}
41{$ME.Program = 6}
42{$ME.Program = 7}
43{$ME.Program = 8}
}
}
$job1 = Register-ObjectEvent -InputObject $inputPort -EventName NoteOnMessageReceived -SourceIdentifier $noteOnSourceId -Action $HandleNoteOn
#Set initial LED state
$Global:Program = $ME.Program
if($Global:Program -gt 0 -And $Global:Program -lt 5){
#turn on new program led
Send-MidiNoteOnMessage -Channel 0 -Note (35+$Global:Program) -Port $outputPort -Velocity 1
}
#region Timer
$timer = New-Object System.Timers.Timer
$timer.Interval = 500
$timer.AutoReset = $true
$sourceIdentifier = "TimerJob"
$timerAction = {
#Write-Host "looping"
#update leds
#Program
$CurrentProgram = $Global:ME.Program
if($Global:Program -ne $CurrentProgram){
if($Global:Debug -eq $true){write-host "Program changed from $($Global:Program) to $($CurrentProgram) "}
if($Global:Program -gt 0 -And $Global:Program -lt 9){
#turn off current LED
Send-MidiNoteOnMessage -Channel 0 -Note (35+$Global:Program) -Port $outputPort -Velocity 0
if($CurrentProgram -gt 0 -And $CurrentProgram -lt 9){
#turn on new program led
Send-MidiNoteOnMessage -Channel 0 -Note (35+$CurrentProgram) -Port $outputPort -Velocity 1
}
}
$Global:Program = $CurrentProgram
}
else{
#no program led was on
if($CurrentProgram -gt 0 -And $CurrentProgram -lt 9){
#turn on new program led
Send-MidiNoteOnMessage -Channel 0 -Note (35+$CurrentProgram) -Port $outputPort -Velocity 1
$Global:Program = $CurrentProgram
}
}
}
Unregister-Event $sourceIdentifier -ErrorAction SilentlyContinue
$timer.stop()
$start = Register-ObjectEvent -InputObject $timer -SourceIdentifier $sourceIdentifier -EventName Elapsed -Action $timeraction
$timer.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment