Skip to content

Commit 224c33b

Browse files
committed
First drop of IconPlatform code
(Will write a blog post when I've got the D2 text working.)
1 parent 3b9bcd1 commit 224c33b

12 files changed

+550
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\IconPlatform.Model\IconPlatform.Model.csproj" />
10+
</ItemGroup>
11+
12+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using IconPlatform.Model;
2+
using System;
3+
using System.Threading.Tasks;
4+
5+
namespace IconPlatform.ConsoleDemo
6+
{
7+
class Program
8+
{
9+
static async Task Main(string[] args)
10+
{
11+
var controller = await PlatformMXController.ConnectAsync("Platform M+ V2.15");
12+
13+
controller.ButtonChanged += (sender, args) =>
14+
{
15+
Console.WriteLine($"Channel {args.Channel} button {args.Button} {(args.Down ? "pressed" : "released")}");
16+
controller.SetLight(args.Channel, args.Button, args.Down);
17+
};
18+
controller.KnobTurned += (sender, args) =>
19+
{
20+
Console.WriteLine($"Channel {args.Channel} knob turned with value {args.Value}");
21+
};
22+
controller.FaderMoved += (sender, args) =>
23+
{
24+
Console.WriteLine($"Channel {args.Channel} fader moved to {args.Position}");
25+
controller.MoveFader(args.Channel, args.Position);
26+
};
27+
await Task.Delay(60000);
28+
}
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\..\OscMixerControl\OscMixerControl\OscMixerControl.csproj" />
10+
<ProjectReference Include="..\IconPlatform.Model\IconPlatform.Model.csproj" />
11+
</ItemGroup>
12+
13+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2021 Jon Skeet. All rights reserved.
2+
// Use of this source code is governed by the Apache License 2.0,
3+
// as found in the LICENSE.txt file.
4+
5+
using IconPlatform.Model;
6+
using OscMixerControl;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Threading;
11+
using System.Threading.Tasks;
12+
13+
namespace IconPlatform.MixerControl
14+
{
15+
internal class MixerConnector : IDisposable
16+
{
17+
private readonly List<Channel> channels;
18+
private readonly Mixer mixer;
19+
private readonly Timer renewTimer;
20+
private readonly Channel mainOutput;
21+
private readonly PlatformMXController controller;
22+
23+
internal MixerConnector(PlatformMXController controller, Mixer mixer)
24+
{
25+
this.controller = controller;
26+
this.mixer = mixer;
27+
controller.ButtonChanged += HandleButtonChanged;
28+
controller.FaderMoved += ChangeVolume;
29+
30+
// TODO: Mapping from knob to input channel customization
31+
channels = Enumerable.Range(1, 8)
32+
.Select(index => XAir.CreateInputChannel(mixer, index))
33+
.ToList();
34+
renewTimer = new Timer(RefreshSubscriptionsAsync);
35+
}
36+
37+
private async void RefreshSubscriptionsAsync(object state)
38+
{
39+
await mixer.SendXRemoteAsync();
40+
await mixer.SendRenewAllAsync();
41+
}
42+
43+
private void HandleButtonChanged(object sender, ButtonEventArgs e)
44+
{
45+
if (e.Button == ButtonType.Mute && e.Down)
46+
{
47+
var channel = channels[e.Channel - 1];
48+
channel.SetOn(1 - channel.On);
49+
}
50+
}
51+
52+
private void ChangeVolume(object sender, FaderEventArgs e) =>
53+
channels[e.Channel - 1].SetFaderLevel(e.Position / 1023f);
54+
55+
internal async Task StartAsync()
56+
{
57+
for (int i = 0; i < channels.Count; i++)
58+
{
59+
int oneChannel = i + 1;
60+
var channel = channels[i];
61+
channel.PropertyChanged += (sender, args) =>
62+
{
63+
switch (args.PropertyName)
64+
{
65+
case nameof(Channel.On):
66+
controller.SetLight(oneChannel, ButtonType.Mute, channel.On == 1 ? false : true);
67+
break;
68+
case nameof(Channel.FaderLevel):
69+
controller.MoveFader(oneChannel, (int) (channel.FaderLevel * 1023));
70+
break;
71+
}
72+
};
73+
await channel.RequestDataOnce().ConfigureAwait(false);
74+
}
75+
renewTimer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(5));
76+
}
77+
78+
public void Dispose() => renewTimer.Dispose();
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using IconPlatform.Model;
2+
using OscMixerControl;
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace IconPlatform.MixerControl
8+
{
9+
class Program
10+
{
11+
static async Task Main(string[] args)
12+
{
13+
// MIDI input name hard-coded as I think the chances of anyone else running this are slim...
14+
await using (var controller = await PlatformMXController.ConnectAsync("Platform M+ V2.15"))
15+
{
16+
Console.WriteLine("Connected to controller");
17+
18+
using (var mixer = new Mixer())
19+
{
20+
// IP address hard-coded as I think the chances of anyone else running this are slim...
21+
mixer.Connect("192.168.1.41", 10024);
22+
mixer.RegisterHandler("/info", (sender, message) => Console.WriteLine($"Mixer info response: {string.Join("/", message)}"));
23+
await mixer.SendInfoAsync();
24+
25+
using (var connector = new MixerConnector(controller, mixer))
26+
{
27+
await connector.StartAsync();
28+
await Task.Delay(Timeout.Infinite);
29+
}
30+
}
31+
}
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2021 Jon Skeet. All rights reserved.
2+
// Use of this source code is governed by the Apache License 2.0,
3+
// as found in the LICENSE.txt file.
4+
5+
namespace IconPlatform.Model
6+
{
7+
/// <summary>
8+
/// Information provided when a button is pressed or released.
9+
/// </summary>
10+
public sealed class ButtonEventArgs
11+
{
12+
/// <summary>
13+
/// The 1-based channel containing the button.
14+
/// </summary>
15+
public int Channel { get; }
16+
17+
/// <summary>
18+
/// The button type.
19+
/// </summary>
20+
public ButtonType Button { get; }
21+
22+
/// <summary>
23+
/// True if this event is for a button being pressed; false if
24+
/// it is for a button being released.
25+
/// </summary>
26+
public bool Down { get; }
27+
28+
public ButtonEventArgs(int channel, ButtonType button, bool down) =>
29+
(Channel, Button, Down) = (channel, button, down);
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace IconPlatform.Model
2+
{
3+
public enum ButtonType
4+
{
5+
Sel,
6+
Mute,
7+
Solo,
8+
Record,
9+
Knob,
10+
Fader
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace IconPlatform.Model
2+
{
3+
public sealed record FaderEventArgs
4+
{
5+
public int Channel { get; }
6+
7+
public int Position { get; }
8+
9+
public FaderEventArgs(int channel, int position) => (Channel, Position) = (channel, position);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<LangVersion>9</LangVersion>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="managed-midi" Version="1.9.14" />
10+
</ItemGroup>
11+
12+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2021 Jon Skeet. All rights reserved.
2+
// Use of this source code is governed by the Apache License 2.0,
3+
// as found in the LICENSE.txt file.
4+
5+
namespace IconPlatform.Model
6+
{
7+
/// <summary>
8+
/// Information provided when a knob is turned.
9+
/// </summary>
10+
public sealed class KnobTurnedEventArgs
11+
{
12+
public int Channel { get; }
13+
14+
/// <summary>
15+
/// The reported knob value, in the range 0-127.
16+
/// In standard mode this is the knob position in the range 0-127.
17+
/// In Mackie Control Mode this is the velocity: values 0x01-0x07
18+
/// are clockwise, and values 0x41-0x47 are counter-clockwise.
19+
/// </summary>
20+
public int Value { get; }
21+
22+
public KnobTurnedEventArgs(int channel, int value) => (Channel, Value) = (channel, value);
23+
}
24+
}

0 commit comments

Comments
 (0)