POC Sequenceur MIDI

This commit is contained in:
Tzim 2017-06-30 16:33:09 +02:00
parent 8b13311420
commit ca1690929e
4 changed files with 166 additions and 9 deletions

View file

@ -224,12 +224,47 @@ namespace DMX2
} }
); );
item = new Gtk.SeparatorMenuItem ();
m.Add(item);
item = new MenuItem("Connecter");
item.Submenu = EnumMidiDevices ();
m.Add(item);
m.ShowAll(); m.ShowAll();
m.Popup(); m.Popup();
} }
static public object PortKey = new object();
Gtk.Menu EnumMidiDevices(){
Gtk.Menu m = new Menu ();
Gtk.MenuItem item;
foreach (var dev in AlsaSeqLib.EnumClients ()) {
if(dev.Id== AlsaSeqLib.ClientId || dev.Id == 0 || dev.Id == 14 ) continue;
foreach(var port in dev.Ports){
if((port.Caps & AlsaSeqLib.SND_SEQ_PORT_CAP_WRITE) == AlsaSeqLib.SND_SEQ_PORT_CAP_WRITE){
string name = dev.Name+":"+port.Name;
item = new MenuItem (name);
item.Data[PortKey] = port;
item.ButtonPressEvent+= ConnectMidiDevEvent;
m.Add (item);
}
}
}
return m;
}
public override void Update (bool full) public override void Update (bool full)
{ {
if (fullUpdFlag || full) if (fullUpdFlag || full)
@ -251,6 +286,13 @@ namespace DMX2
} }
} }
void ConnectMidiDevEvent (object o, ButtonPressEventArgs args)
{
Gtk.MenuItem item = o as Gtk.MenuItem;
AlsaSeqLib.Port port = item.Data [PortKey] as AlsaSeqLib.Port;
sequenceur.Connect (port);
}
void SelectionneEffet (int index) void SelectionneEffet (int index)
{ {

View file

@ -24,14 +24,14 @@ using System.Threading;
namespace DMX2 namespace DMX2
{ {
public class SequenceurMidi : Sequenceur public class SequenceurMidi : Sequenceur , IDisposable
{ {
public class Ligne { public class Ligne {
public Ligne(){} public Ligne(){}
string nom = string.Empty; string nom = string.Empty;
TimeSpan top = TimeSpan.MinValue; TimeSpan top = TimeSpan.MinValue;
string commande =null; string commande =string.Empty;
public string Nom { public string Nom {
get { get {
@ -104,6 +104,11 @@ namespace DMX2
bool paused=false; bool paused=false;
int midiport=-1;
static int portnum=0;
List<AlsaSeqLib.Port> mididests = new List<AlsaSeqLib.Port>();
public bool Paused { public bool Paused {
get { get {
return paused; return paused;
@ -113,6 +118,14 @@ namespace DMX2
} }
} }
int midiCh=0;
public int MidiCh {
get{
return midiCh;
}
}
public SequenceurMidi () public SequenceurMidi ()
{ {
@ -134,8 +147,22 @@ namespace DMX2
return true; return true;
} }
); );
string portname = string.Format ("midi_seq_{0}", portnum++);
midiport = AlsaSeqLib.CreatePort (portname);
} }
bool disposed=false;
~SequenceurMidi ()
{
((IDisposable)this).Dispose ();
}
void IDisposable.Dispose (){
if (disposed)
return;
disposed = true;
AlsaSeqLib.DeletePort (midiport);
}
public int IndexLigneEnCours public int IndexLigneEnCours
{ {
@ -145,6 +172,9 @@ namespace DMX2
} }
} }
public void Connect (AlsaSeqLib.Port port){
AlsaSeqLib.ConnectTo (midiport, port.ClientId, port.PortId);
}
public int IndexLigneaSuivre public int IndexLigneaSuivre
{ {
@ -231,8 +261,19 @@ namespace DMX2
enCours = lignes[index]; enCours = lignes[index];
// Gestion de la Reprise // Gestion de la Reprise
// if(enCours.Circuits.ToLower().Equals("r") && ligneMaitre != null) if (enCours.Commande.ToLower ().Equals ("r") && ligneMaitre != null) {
// enCours = ligneMaitre; enCours = ligneMaitre;
}
System.Text.RegularExpressions.Match m = regexGotoCmd.Match (enCours.Commande);
if (m.Success) {
int gtindex = int.Parse (m.Groups [2].Value)-1;
if (lignes.Count >= gtindex) {
timeStamp = TimeSpan.Zero;
enCours = lignes [gtindex];
}
}
if(enCours.Nom.Length!=0) if(enCours.Nom.Length!=0)
{ {
@ -264,10 +305,70 @@ namespace DMX2
} }
} }
static System.Text.RegularExpressions.Regex regexMidiCmd = new System.Text.RegularExpressions.Regex(
@"(ch(\d+))|(CC(\d+),(\d+))|(PC(\d+))|(N(\d+)(\+|\-)(\d+)?)",
System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase );
static System.Text.RegularExpressions.Regex regexGotoCmd = new System.Text.RegularExpressions.Regex(
@"(GT(\d+))",
System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.IgnoreCase );
void LanceCommandeMidi () void LanceCommandeMidi ()
{ {
Console.WriteLine (enCours.Commande); Console.WriteLine (enCours.Commande);
AlsaSeqLib.snd_seq_event_t ev;
var matches = regexMidiCmd.Matches (enCours.Commande);
foreach (System.Text.RegularExpressions.Match match in matches) {
if (match.Groups [2].Success) {
midiCh = int.Parse (match.Groups [2].Value);
continue;
}
if (match.Groups [4].Success) {
ev = new AlsaSeqLib.snd_seq_event_t ();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
ev.data_ev_ctrl.channel = (byte)midiCh;
ev.data_ev_ctrl.param = uint.Parse (match.Groups [4].Value);
ev.data_ev_ctrl.value = int.Parse (match.Groups [5].Value);
ev.source.port = (byte)midiport;
AlsaSeqLib.SendEventToSubscribers (ev);
}
if (match.Groups [7].Success) {
ev = new AlsaSeqLib.snd_seq_event_t ();
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PGMCHANGE;
ev.data_ev_ctrl.channel = (byte)midiCh;
ev.data_ev_ctrl.value = int.Parse (match.Groups [7].Value);
ev.source.port = (byte)midiport;
AlsaSeqLib.SendEventToSubscribers (ev);
}
if (match.Groups [9].Success) {
ev = new AlsaSeqLib.snd_seq_event_t ();
ev.data_ev_note.note = byte.Parse (match.Groups [9].Value);
ev.data_ev_note.channel = (byte)midiCh;
if (match.Groups [10].Value.Equals ("+")) {
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON;
if (match.Groups [11].Success)
ev.data_ev_note.velocity = byte.Parse (match.Groups [11].Value);
else
ev.data_ev_note.velocity = 127;
} else {
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF;
if (match.Groups [11].Success)
ev.data_ev_note.off_velocity = byte.Parse (match.Groups [11].Value);
else
ev.data_ev_note.off_velocity = 0;
}
ev.source.port = (byte)midiport;
AlsaSeqLib.SendEventToSubscribers (ev);
}
}
} }

View file

@ -8,8 +8,6 @@ namespace DMX2
private global::Gtk.ToggleAction closeAction; private global::Gtk.ToggleAction closeAction;
private global::Gtk.Action circuitsAction;
private global::Gtk.Action goForwardAction; private global::Gtk.Action goForwardAction;
private global::Gtk.Action goBackAction; private global::Gtk.Action goBackAction;
@ -66,8 +64,6 @@ namespace DMX2
this.closeAction = new global::Gtk.ToggleAction ("closeAction", " ", null, "gtk-close"); this.closeAction = new global::Gtk.ToggleAction ("closeAction", " ", null, "gtk-close");
this.closeAction.ShortLabel = " "; this.closeAction.ShortLabel = " ";
w2.Add (this.closeAction, null); w2.Add (this.closeAction, null);
this.circuitsAction = new global::Gtk.Action ("circuitsAction", null, "Association des circuits\nau sequenceur", "circuits");
w2.Add (this.circuitsAction, null);
this.goForwardAction = new global::Gtk.Action ("goForwardAction", null, null, "gtk-go-forward"); this.goForwardAction = new global::Gtk.Action ("goForwardAction", null, null, "gtk-go-forward");
w2.Add (this.goForwardAction, null); w2.Add (this.goForwardAction, null);
this.goBackAction = new global::Gtk.Action ("goBackAction", null, null, "gtk-go-back"); this.goBackAction = new global::Gtk.Action ("goBackAction", null, null, "gtk-go-back");

View file

@ -2238,6 +2238,24 @@ au sequenceur</property>
<property name="AutoSize">True</property> <property name="AutoSize">True</property>
</packing> </packing>
</child> </child>
<child>
<widget class="Gtk.Label" id="label1">
<property name="MemberName" />
<property name="Xalign">0</property>
<property name="LabelProp" translatable="yes">CC : Control Change (ex: CC12,100)
PC : Program Change (ex: PC5)
N : Note On/Off (ex: N64+127 ou N12-)
GT : Go To (ex: GT4)
r: loop</property>
<property name="UseMarkup">True</property>
</widget>
<packing>
<property name="Position">2</property>
<property name="AutoSize">True</property>
<property name="Expand">False</property>
<property name="Fill">False</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>
@ -4711,4 +4729,4 @@ trames DMX (ms)</property>
</widget> </widget>
</child> </child>
</widget> </widget>
</stetic-interface> </stetic-interface>