This commit is contained in:
tzim 2014-05-25 21:13:59 +00:00
parent 0610ed4150
commit 89fd0f36c6
4 changed files with 306 additions and 261 deletions

View file

@ -27,7 +27,8 @@ namespace DMX2
public const byte SND_SEQ_ADDRESS_BROADCAST = 255; public const byte SND_SEQ_ADDRESS_BROADCAST = 255;
public const byte SND_SEQ_QUEUE_DIRECT = 253; public const byte SND_SEQ_QUEUE_DIRECT = 253;
public enum snd_seq_client_type_t : int { public enum snd_seq_client_type_t : int
{
SND_SEQ_USER_CLIENT = 1, SND_SEQ_USER_CLIENT = 1,
SND_SEQ_KERNEL_CLIENT = 2 SND_SEQ_KERNEL_CLIENT = 2
} }
@ -276,6 +277,7 @@ namespace DMX2
} }
return _subscriberInfoSize; return _subscriberInfoSize;
} }
static int GetQuerySubscribeInfoSize () static int GetQuerySubscribeInfoSize ()
{ {
if (_query_subscribeInfoSize == 0) { if (_query_subscribeInfoSize == 0) {

View file

@ -97,20 +97,25 @@ namespace DMX2
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_port_subscribe_sizeof (); public static extern int snd_seq_port_subscribe_sizeof ();
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_sizeof (); public static extern int snd_seq_query_subscribe_sizeof ();
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_client (IntPtr info); public static extern int snd_seq_query_subscribe_get_client (IntPtr info);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_port (IntPtr info); public static extern int snd_seq_query_subscribe_get_port (IntPtr info);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_queue (IntPtr info); public static extern int snd_seq_query_subscribe_get_queue (IntPtr info);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_time_real (IntPtr info); public static extern int snd_seq_query_subscribe_get_time_real (IntPtr info);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_time_update (IntPtr info); public static extern int snd_seq_query_subscribe_get_time_update (IntPtr info);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_query_subscribe_get_exclusive (IntPtr info); public static extern int snd_seq_query_subscribe_get_exclusive (IntPtr info);
@ -140,6 +145,7 @@ namespace DMX2
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr snd_seq_query_subscribe_get_addr (IntPtr subs); public static extern IntPtr snd_seq_query_subscribe_get_addr (IntPtr subs);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr snd_seq_query_subscribe_get_root (IntPtr subs); public static extern IntPtr snd_seq_query_subscribe_get_root (IntPtr subs);
@ -175,6 +181,7 @@ namespace DMX2
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_connect_to (IntPtr handle, int myport, int dest_client, int dest_port); public static extern int snd_seq_connect_to (IntPtr handle, int myport, int dest_client, int dest_port);
[DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)] [DllImport(ASOUND_LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
public static extern int snd_seq_disconnect_from (IntPtr handle, int myport, int src_client, int src_port); public static extern int snd_seq_disconnect_from (IntPtr handle, int myport, int src_client, int src_port);

View file

@ -7,8 +7,7 @@ namespace DMX2
{ {
public static partial class AlsaSeqLib public static partial class AlsaSeqLib
{ {
static SeqHandleWrapper seq_handle=null; static SeqHandleWrapper seq_handle = null;
static int clientId; static int clientId;
static int inport; static int inport;
static int outport; static int outport;
@ -19,8 +18,7 @@ namespace DMX2
int id; int id;
snd_seq_client_type_t type; snd_seq_client_type_t type;
string name; string name;
List<Port> ports = new List<Port> ();
List<Port> ports = new List<Port>();
public int Id { public int Id {
get { get {
@ -33,6 +31,7 @@ namespace DMX2
return type; return type;
} }
} }
public string Name { public string Name {
get { get {
return name; return name;
@ -41,21 +40,22 @@ namespace DMX2
public ReadOnlyCollection<Port> Ports { public ReadOnlyCollection<Port> Ports {
get { get {
return ports.AsReadOnly(); return ports.AsReadOnly ();
} }
} }
internal Client(PointerWrapper clientInfo){ internal Client (PointerWrapper clientInfo)
id = Invoke.snd_seq_client_info_get_client(clientInfo.Pointer); {
IntPtr nameptr = Invoke.snd_seq_client_info_get_name(clientInfo.Pointer); id = Invoke.snd_seq_client_info_get_client (clientInfo.Pointer);
name = nameptr.PtrToString(); IntPtr nameptr = Invoke.snd_seq_client_info_get_name (clientInfo.Pointer);
type = (snd_seq_client_type_t)Invoke.snd_seq_client_info_get_type(clientInfo.Pointer); name = nameptr.PtrToString ();
type = (snd_seq_client_type_t)Invoke.snd_seq_client_info_get_type (clientInfo.Pointer);
using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) { using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) {
Invoke.snd_seq_port_info_set_client (portInfo.Pointer, id); Invoke.snd_seq_port_info_set_client (portInfo.Pointer, id);
Invoke.snd_seq_port_info_set_port (portInfo.Pointer, -1); Invoke.snd_seq_port_info_set_port (portInfo.Pointer, -1);
while(Invoke.snd_seq_query_next_port(seq_handle.Handle, portInfo.Pointer) >= 0) { while (Invoke.snd_seq_query_next_port(seq_handle.Handle, portInfo.Pointer) >= 0) {
ports.Add(new Port(portInfo)); ports.Add (new Port (portInfo));
} }
} }
} }
@ -79,6 +79,7 @@ namespace DMX2
return clientId; return clientId;
} }
} }
public int PortId { public int PortId {
get { get {
return portId; return portId;
@ -103,54 +104,59 @@ namespace DMX2
} }
} }
internal Port(PointerWrapper portInfo){ internal Port (PointerWrapper portInfo)
clientId = Invoke.snd_seq_port_info_get_client(portInfo.Pointer); {
portId = Invoke.snd_seq_port_info_get_port(portInfo.Pointer); clientId = Invoke.snd_seq_port_info_get_client (portInfo.Pointer);
IntPtr namePtr = Invoke.snd_seq_port_info_get_name(portInfo.Pointer); portId = Invoke.snd_seq_port_info_get_port (portInfo.Pointer);
IntPtr namePtr = Invoke.snd_seq_port_info_get_name (portInfo.Pointer);
caps = Invoke.snd_seq_port_info_get_capability (portInfo.Pointer); caps = Invoke.snd_seq_port_info_get_capability (portInfo.Pointer);
type = Invoke.snd_seq_port_info_get_type(portInfo.Pointer); type = Invoke.snd_seq_port_info_get_type (portInfo.Pointer);
name = namePtr.PtrToString(); name = namePtr.PtrToString ();
} }
} }
public static void Init () public static void Init ()
{ {
if(seq_handle!=null) return; if (seq_handle != null)
return;
seq_handle = new SeqHandleWrapper(); seq_handle = new SeqHandleWrapper ();
clientId = Invoke.snd_seq_client_id(seq_handle.Handle); clientId = Invoke.snd_seq_client_id (seq_handle.Handle);
outport = inport= Invoke.snd_seq_create_simple_port(seq_handle.Handle,"dmx_ctrl", outport = inport = Invoke.snd_seq_create_simple_port (seq_handle.Handle, "dmx_ctrl",
SND_SEQ_PORT_CAP_WRITE + SND_SEQ_PORT_CAP_SUBS_WRITE + SND_SEQ_PORT_CAP_WRITE + SND_SEQ_PORT_CAP_SUBS_WRITE +
SND_SEQ_PORT_CAP_READ + SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_CAP_READ + SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_APPLICATION); SND_SEQ_PORT_TYPE_APPLICATION);
} }
public static void Close () public static void Close ()
{ {
if(seq_handle==null) return; if (seq_handle == null)
seq_handle.Dispose(); return;
seq_handle.Dispose ();
seq_handle = null; seq_handle = null;
} }
public static bool GetEvent (out snd_seq_event_t ev)
public static bool GetEvent(out snd_seq_event_t ev){ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
ev = new snd_seq_event_t(); throw new InvalidOperationException ();
if(Invoke.snd_seq_event_input_pending(seq_handle.Handle,1)<=0) return false; ev = new snd_seq_event_t ();
if (Invoke.snd_seq_event_input_pending (seq_handle.Handle, 1) <= 0)
return false;
IntPtr evPtr; IntPtr evPtr;
// Recup du pointeur vers l'ev // Recup du pointeur vers l'ev
Invoke.snd_seq_event_input(seq_handle.Handle, out evPtr); Invoke.snd_seq_event_input (seq_handle.Handle, out evPtr);
// Copie de la zone mémoire dans une structure managee // Copie de la zone mémoire dans une structure managee
ev =(snd_seq_event_t) Marshal.PtrToStructure(evPtr,typeof(snd_seq_event_t)); ev = (snd_seq_event_t)Marshal.PtrToStructure (evPtr, typeof(snd_seq_event_t));
// liberation du pointeur // liberation du pointeur
Invoke.snd_seq_free_event(evPtr); Invoke.snd_seq_free_event (evPtr);
// TODO : Manage System Events here // TODO : Manage System Events here
@ -158,43 +164,45 @@ namespace DMX2
} }
static PointerWrapper evOutPtr = new PointerWrapper (32);
static PointerWrapper evOutPtr = new PointerWrapper(32);
public static void SendEvent (snd_seq_event_t ev) public static void SendEvent (snd_seq_event_t ev)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
throw new InvalidOperationException ();
ev.queue = SND_SEQ_QUEUE_DIRECT; ev.queue = SND_SEQ_QUEUE_DIRECT;
ev.source.client = (byte)clientId; ev.source.client = (byte)clientId;
ev.source.port = (byte) outport; ev.source.port = (byte)outport;
Marshal.StructureToPtr(ev,evOutPtr.Pointer,false); Marshal.StructureToPtr (ev, evOutPtr.Pointer, false);
Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer); Invoke.snd_seq_event_output (seq_handle.Handle, evOutPtr.Pointer);
Invoke.snd_seq_drain_output(seq_handle.Handle); Invoke.snd_seq_drain_output (seq_handle.Handle);
} }
public static void SendEventToSubscribers (snd_seq_event_t ev) public static void SendEventToSubscribers (snd_seq_event_t ev)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
ev.dest.client=SND_SEQ_ADDRESS_SUBSCRIBERS; throw new InvalidOperationException ();
ev.dest.port= SND_SEQ_ADDRESS_UNKNOWN; ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS;
SendEvent(ev); ev.dest.port = SND_SEQ_ADDRESS_UNKNOWN;
SendEvent (ev);
} }
public static IEnumerable<Client> EnumClients () public static IEnumerable<Client> EnumClients ()
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
throw new InvalidOperationException ();
using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) { using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) {
Invoke.snd_seq_client_info_set_client(clientInfo.Pointer, -1); Invoke.snd_seq_client_info_set_client (clientInfo.Pointer, -1);
while (Invoke.snd_seq_query_next_client(seq_handle.Handle,clientInfo.Pointer)>=0) { while (Invoke.snd_seq_query_next_client(seq_handle.Handle,clientInfo.Pointer)>=0) {
yield return new Client(clientInfo); yield return new Client (clientInfo);
} }
} }
} }
public static Client GetClientByID (int client) public static Client GetClientByID (int client)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
throw new InvalidOperationException ();
using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) { using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) {
if (Invoke.snd_seq_get_any_client_info (seq_handle.Handle, client, clientInfo.Pointer) >= 0) { if (Invoke.snd_seq_get_any_client_info (seq_handle.Handle, client, clientInfo.Pointer) >= 0) {
return new Client (clientInfo); return new Client (clientInfo);
@ -203,90 +211,96 @@ namespace DMX2
} }
} }
public static Port GetPortByIDs(int client,int port){ public static Port GetPortByIDs (int client, int port)
if(seq_handle==null) throw new InvalidOperationException(); {
if (seq_handle == null)
throw new InvalidOperationException ();
using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) { using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) {
if(Invoke.snd_seq_get_any_port_info(seq_handle.Handle,client,port,portInfo.Pointer) >= 0) { if (Invoke.snd_seq_get_any_port_info (seq_handle.Handle, client, port, portInfo.Pointer) >= 0) {
return new Port(portInfo); return new Port (portInfo);
} } else
else
return null; return null;
} }
} }
public static bool Connect(Port port) public static bool Connect (Port port)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
throw new InvalidOperationException ();
bool isInput = (port.Caps & SND_SEQ_PORT_CAP_WRITE) == SND_SEQ_PORT_CAP_WRITE; bool isInput = (port.Caps & SND_SEQ_PORT_CAP_WRITE) == SND_SEQ_PORT_CAP_WRITE;
bool isOutput = (port.Caps & SND_SEQ_PORT_CAP_READ) == SND_SEQ_PORT_CAP_READ; bool isOutput = (port.Caps & SND_SEQ_PORT_CAP_READ) == SND_SEQ_PORT_CAP_READ;
if (isInput) if (isInput)
if (!ConnectTo (port.ClientId, port.PortId)) if (!ConnectTo (port.ClientId, port.PortId))
return false; return false;
if (isOutput) if (isOutput)
if (!ConnectFrom (port.ClientId, port.PortId)) if (!ConnectFrom (port.ClientId, port.PortId))
return false; return false;
return true; return true;
} }
public static bool ConnectTo(int client, int port){ public static bool ConnectTo (int client, int port)
if(seq_handle==null) throw new InvalidOperationException(); {
return Invoke.snd_seq_connect_to(seq_handle.Handle,outport,client,port)==0; if (seq_handle == null)
throw new InvalidOperationException ();
return Invoke.snd_seq_connect_to (seq_handle.Handle, outport, client, port) == 0;
} }
public static bool ConnectFrom(int client, int port){
if(seq_handle==null) throw new InvalidOperationException(); public static bool ConnectFrom (int client, int port)
return Invoke.snd_seq_connect_from(seq_handle.Handle,inport,client,port)==0; {
if (seq_handle == null)
throw new InvalidOperationException ();
return Invoke.snd_seq_connect_from (seq_handle.Handle, inport, client, port) == 0;
} }
public static void Deconnecte (int client, int port) public static void Deconnecte (int client, int port)
{ {
if(seq_handle==null) throw new InvalidOperationException(); if (seq_handle == null)
throw new InvalidOperationException ();
snd_seq_addr_t local = new snd_seq_addr_t (); snd_seq_addr_t local = new snd_seq_addr_t ();
local.client = (byte)clientId; local.client = (byte)clientId;
local.port = (byte)inport; local.port = (byte)inport;
snd_seq_addr_t addr; snd_seq_addr_t addr;
using (PointerWrapper subqueryInfo = new PointerWrapper(GetQuerySubscribeInfoSize())) using (PointerWrapper subqueryInfo = new PointerWrapper(GetQuerySubscribeInfoSize()))
using (PointerWrapper localAddr =new PointerWrapper(local.SndSeqAddrToPtr())) using (PointerWrapper localAddr =new PointerWrapper(local.SndSeqAddrToPtr())) {
Invoke.snd_seq_query_subscribe_set_root (subqueryInfo.Pointer, localAddr.Pointer);
{ Invoke.snd_seq_query_subscribe_set_type (subqueryInfo.Pointer, SND_SEQ_QUERY_SUBS_WRITE);
Invoke.snd_seq_query_subscribe_set_root(subqueryInfo.Pointer,localAddr.Pointer);
Invoke.snd_seq_query_subscribe_set_type(subqueryInfo.Pointer,SND_SEQ_QUERY_SUBS_WRITE);
for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0); for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0);
Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0; Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0;
Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer, Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,
Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1) Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1)
){ ) {
//root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr(); //root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr();
addr = Invoke.snd_seq_query_subscribe_get_addr(subqueryInfo.Pointer).PtrToSndSeqAddr(); addr = Invoke.snd_seq_query_subscribe_get_addr (subqueryInfo.Pointer).PtrToSndSeqAddr ();
if( addr.client != client || addr.port != port) if (addr.client != client || addr.port != port)
continue; continue;
Invoke.snd_seq_disconnect_from(seq_handle.Handle,inport,client,port); Invoke.snd_seq_disconnect_from (seq_handle.Handle, inport, client, port);
} }
Invoke.snd_seq_query_subscribe_set_type(subqueryInfo.Pointer,SND_SEQ_QUERY_SUBS_READ); Invoke.snd_seq_query_subscribe_set_type (subqueryInfo.Pointer, SND_SEQ_QUERY_SUBS_READ);
for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0); for (Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,0);
Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0; Invoke.snd_seq_query_port_subscribers (seq_handle.Handle,subqueryInfo.Pointer)>=0;
Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer, Invoke.snd_seq_query_subscribe_set_index(subqueryInfo.Pointer,
Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1) Invoke.snd_seq_query_subscribe_get_index(subqueryInfo.Pointer) +1)
){ ) {
//root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr(); //root = Invoke.snd_seq_query_subscribe_get_root(subqueryInfo.Pointer).PtrToSndSeqAddr();
addr = Invoke.snd_seq_query_subscribe_get_addr(subqueryInfo.Pointer).PtrToSndSeqAddr(); addr = Invoke.snd_seq_query_subscribe_get_addr (subqueryInfo.Pointer).PtrToSndSeqAddr ();
if( addr.client != client || addr.port != port) if (addr.client != client || addr.port != port)
continue; continue;
Invoke.snd_seq_disconnect_to(seq_handle.Handle,outport,client,port); Invoke.snd_seq_disconnect_to (seq_handle.Handle, outport, client, port);
} }
} }

View file

@ -15,7 +15,6 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections.Generic; using System.Collections.Generic;
@ -26,10 +25,11 @@ namespace DMX2
public class MidiEventProvider : IEventProvider, IDisposable public class MidiEventProvider : IEventProvider, IDisposable
{ {
class internalEvent { class internalEvent
{
readonly string internalName; readonly string internalName;
bool bound=false; bool bound = false;
readonly uint page; readonly uint page;
readonly int midiEvCode; readonly int midiEvCode;
@ -60,15 +60,14 @@ namespace DMX2
} }
} }
public internalEvent (string _id, uint _page, int _evHCode)
public internalEvent(string _id, uint _page, int _evHCode)
{ {
internalName=_id; internalName = _id;
page=_page; page = _page;
midiEvCode = _evHCode; midiEvCode = _evHCode;
} }
int lastknownvalue=-1; int lastknownvalue = -1;
public int LastKnownValue { public int LastKnownValue {
get { get {
@ -80,6 +79,7 @@ namespace DMX2
} }
AlsaSeqLib.snd_seq_event_t storedevent; AlsaSeqLib.snd_seq_event_t storedevent;
public AlsaSeqLib.snd_seq_event_t StoredEvent { public AlsaSeqLib.snd_seq_event_t StoredEvent {
get { get {
return storedevent; return storedevent;
@ -89,18 +89,20 @@ namespace DMX2
} }
} }
} }
abstract class feedbackinfo : IFeedbackInfo {
abstract class feedbackinfo : IFeedbackInfo
{
MidiEventProvider prov; MidiEventProvider prov;
readonly internalEvent iev; readonly internalEvent iev;
protected AlsaSeqLib.snd_seq_event_t ev; protected AlsaSeqLib.snd_seq_event_t ev;
public feedbackinfo (MidiEventProvider _prov, internalEvent _iev)
public feedbackinfo(MidiEventProvider _prov, internalEvent _iev){ {
prov = _prov; prov = _prov;
iev=_iev; iev = _iev;
} }
protected abstract bool UpdateEvent(byte data); protected abstract bool UpdateEvent (byte data);
#region IFeedbackInfo implementation #region IFeedbackInfo implementation
bool IFeedbackInfo.FeedBack (byte data) bool IFeedbackInfo.FeedBack (byte data)
@ -108,14 +110,15 @@ namespace DMX2
bool update = UpdateEvent (data); bool update = UpdateEvent (data);
iev.StoredEvent = ev; iev.StoredEvent = ev;
if (!update) return true; if (!update)
return true;
iev.LastKnownValue = data; iev.LastKnownValue = data;
if (prov.CurrentPage == iev.Page || iev.Page == 0) { if (prov.CurrentPage == iev.Page || iev.Page == 0) {
prov.SendEvent (ev); prov.SendEvent (ev);
foreach (int srcid in prov.feedbacksources) { foreach (int srcid in prov.feedbacksources) {
prov.lastValueOfSrc[CombineHash( srcid , iev.MidiEvCode)] = data; prov.lastValueOfSrc [CombineHash (srcid, iev.MidiEvCode)] = data;
} }
} }
@ -123,55 +126,65 @@ namespace DMX2
} }
#endregion #endregion
} }
class ctrlfeedbackinfo : feedbackinfo {
public ctrlfeedbackinfo(MidiEventProvider _prov, internalEvent _iev, byte channel,uint param) class ctrlfeedbackinfo : feedbackinfo
{
public ctrlfeedbackinfo (MidiEventProvider _prov, internalEvent _iev, byte channel, uint param)
:base(_prov,_iev) :base(_prov,_iev)
{ {
ev = new AlsaSeqLib.snd_seq_event_t(); ev = new AlsaSeqLib.snd_seq_event_t ();
ev.data_ev_ctrl.channel = channel; ev.data_ev_ctrl.channel = channel;
ev.data_ev_ctrl.param= param; ev.data_ev_ctrl.param = param;
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER; ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER;
} }
protected override bool UpdateEvent (byte data) protected override bool UpdateEvent (byte data)
{ {
int newvalue= (int)data * 127 / 255; int newvalue = (int)data * 127 / 255;
if(newvalue==ev.data_ev_ctrl.value) return false; if (newvalue == ev.data_ev_ctrl.value)
return false;
ev.data_ev_ctrl.value = newvalue; ev.data_ev_ctrl.value = newvalue;
return true; return true;
} }
} }
class pitchbendfeedbackinfo : feedbackinfo {
public pitchbendfeedbackinfo(MidiEventProvider _prov, internalEvent _iev, byte channel) class pitchbendfeedbackinfo : feedbackinfo
{
public pitchbendfeedbackinfo (MidiEventProvider _prov, internalEvent _iev, byte channel)
:base(_prov,_iev) :base(_prov,_iev)
{ {
ev = new AlsaSeqLib.snd_seq_event_t(); ev = new AlsaSeqLib.snd_seq_event_t ();
ev.data_ev_ctrl.channel = channel; ev.data_ev_ctrl.channel = channel;
ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND; ev.type = AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND;
} }
protected override bool UpdateEvent (byte data) protected override bool UpdateEvent (byte data)
{ {
int newvalue = (int)data * 16000 / 255-8000; int newvalue = (int)data * 14000 / 255 - 7000;
if(newvalue==ev.data_ev_ctrl.value) return false; if (newvalue == ev.data_ev_ctrl.value)
return false;
ev.data_ev_ctrl.value = newvalue; ev.data_ev_ctrl.value = newvalue;
return true; return true;
} }
} }
public class MidiDev{ public class MidiDev
{
string name; string name;
public string Name {get{return name;} }
public string Name { get { return name; } }
public bool HasFeedback { get; set; } public bool HasFeedback { get; set; }
readonly List<int> connected = new List<int>(); readonly List<int> connected = new List<int> ();
public List<int> ConnectedPorts { public List<int> ConnectedPorts {
get{return connected;} get{ return connected;}
} }
public MidiDev(string _name) public MidiDev (string _name)
{ {
name=_name; name = _name;
} }
} }
@ -179,45 +192,42 @@ namespace DMX2
/// <summary> /// <summary>
/// Etat interne des evenements midi paginés. /// Etat interne des evenements midi paginés.
/// </summary> /// </summary>
readonly Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent>(); readonly Dictionary<string,internalEvent> eventlist = new Dictionary<string, internalEvent> ();
/// <summary> /// <summary>
/// Liste des peripheriques connus (presents ou non) /// Liste des peripheriques connus (presents ou non)
/// </summary> /// </summary>
readonly Dictionary<string,MidiDev> knowndevices = new Dictionary<string,MidiDev>(); readonly Dictionary<string,MidiDev> knowndevices = new Dictionary<string,MidiDev> ();
/// <summary> /// <summary>
/// Liste des ports connectés avec feedback /// Liste des ports connectés avec feedback
/// </summary> /// </summary>
readonly List<int> feedbacksources = new List<int>(); readonly List<int> feedbacksources = new List<int> ();
//static readonly Dictionary<int,MidiDev> srcidToDev = new Dictionary<int, MidiDev>(); //static readonly Dictionary<int,MidiDev> srcidToDev = new Dictionary<int, MidiDev>();
readonly List<byte> unpaginatedchannels = new List<byte>(); readonly List<byte> unpaginatedchannels = new List<byte> ();
/// <summary> /// <summary>
/// Derniere valeur connue pour une evenement sur source donnée : /// Derniere valeur connue pour une evenement sur source donnée :
/// Soit recue, soit envoyée (feedback / changement de page) /// Soit recue, soit envoyée (feedback / changement de page)
/// </summary> /// </summary>
readonly Dictionary<int,byte> lastValueOfSrc = new Dictionary<int, byte>(); readonly Dictionary<int,byte> lastValueOfSrc = new Dictionary<int, byte> ();
EventData last;
internalEvent levent = null;
EventData last; bool connected = false;
internalEvent levent=null; bool guirefreshflag = false;
bool connected=false; uint page = 1;
uint maxpage = 8;
bool guirefreshflag=false;
uint page=1;
uint maxpage=8;
public uint CurrentPage { public uint CurrentPage {
get { get {
return page; return page;
} }
set { set {
if(value<1 || value > maxpage) return; if (value < 1 || value > maxpage)
return;
page = value; page = value;
Refresh(); Refresh ();
} }
} }
@ -229,6 +239,7 @@ namespace DMX2
maxpage = value; maxpage = value;
} }
} }
public List<byte> UnpaginatedChannels { public List<byte> UnpaginatedChannels {
get { get {
return unpaginatedchannels; return unpaginatedchannels;
@ -237,30 +248,29 @@ namespace DMX2
public bool GuiRefreshFlag { public bool GuiRefreshFlag {
get { get {
if(guirefreshflag){ if (guirefreshflag) {
guirefreshflag=false; guirefreshflag = false;
return true; return true;
} }
return false; return false;
} }
} }
public void ConnectDevice (string name) public void ConnectDevice (string name)
{ {
knowndevices.Add(name,new MidiDev(name)); knowndevices.Add (name, new MidiDev (name));
AutoConnect(); AutoConnect ();
} }
public void RefreshFeedback (string name) public void RefreshFeedback (string name)
{ {
foreach (int port in knowndevices[name].ConnectedPorts) { foreach (int port in knowndevices[name].ConnectedPorts) {
if(knowndevices[name].HasFeedback){ if (knowndevices [name].HasFeedback) {
if(!feedbacksources.Contains(port)) if (!feedbacksources.Contains (port))
feedbacksources.Add(port); feedbacksources.Add (port);
}else{ } else {
if(feedbacksources.Contains(port)) if (feedbacksources.Contains (port))
feedbacksources.Remove(port); feedbacksources.Remove (port);
} }
} }
} }
@ -275,12 +285,13 @@ namespace DMX2
foreach (int connectedport in dev.ConnectedPorts) { foreach (int connectedport in dev.ConnectedPorts) {
int client = connectedport >> 8; int client = connectedport >> 8;
int port = connectedport & 0xFF; int port = connectedport & 0xFF;
AlsaSeqLib.Deconnecte(client,port); AlsaSeqLib.Deconnecte (client, port);
} }
} }
public bool IsKnownDevice(string name){ public bool IsKnownDevice (string name)
return knowndevices.ContainsKey(name); {
return knowndevices.ContainsKey (name);
} }
public IEnumerable<MidiDev> KnownDevices { public IEnumerable<MidiDev> KnownDevices {
@ -289,7 +300,6 @@ namespace DMX2
} }
} }
public MidiEventProvider (EventManager manager) public MidiEventProvider (EventManager manager)
{ {
/*MidiDev dev = new MidiDev("VMPK Input:VMPK Input"); /*MidiDev dev = new MidiDev("VMPK Input:VMPK Input");
@ -302,16 +312,16 @@ namespace DMX2
manager.RegisterProvider (this); manager.RegisterProvider (this);
AlsaSeqLib.Init (); AlsaSeqLib.Init ();
AlsaSeqLib.ConnectFrom(AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE); AlsaSeqLib.ConnectFrom (AlsaSeqLib.SND_SEQ_CLIENT_SYSTEM, AlsaSeqLib.SND_SEQ_PORT_SYSTEM_ANNOUNCE);
AutoConnect(); AutoConnect ();
} }
void AutoConnect () void AutoConnect ()
{ {
foreach (var cli in AlsaSeqLib.EnumClients()) { foreach (var cli in AlsaSeqLib.EnumClients()) {
foreach(var p in cli.Ports){ foreach (var p in cli.Ports) {
PortDetected(cli,p); PortDetected (cli, p);
} }
} }
} }
@ -322,21 +332,21 @@ namespace DMX2
// teste si connection auto au port et connecte si besoin // teste si connection auto au port et connecte si besoin
guirefreshflag=true; guirefreshflag = true;
string fullportname = cli.Name + ':' + p.Name; string fullportname = cli.Name + ':' + p.Name;
if(knowndevices.ContainsKey(fullportname)){ if (knowndevices.ContainsKey (fullportname)) {
int srcid = p.ClientId <<8 + p.PortId; int srcid = p.ClientId << 8 + p.PortId;
if(knowndevices[fullportname].ConnectedPorts.Contains(srcid)) if (knowndevices [fullportname].ConnectedPorts.Contains (srcid))
return; return;
AlsaSeqLib.Connect(p); AlsaSeqLib.Connect (p);
} }
} }
void PortConnect (AlsaSeqLib.snd_seq_connect_t cn, bool connect) void PortConnect (AlsaSeqLib.snd_seq_connect_t cn, bool connect)
{ {
int clientId,portId; int clientId, portId;
if (cn.dest.client == AlsaSeqLib.ClientId) { if (cn.dest.client == AlsaSeqLib.ClientId) {
clientId = cn.sender.client; clientId = cn.sender.client;
portId = cn.sender.port; portId = cn.sender.port;
@ -347,14 +357,15 @@ namespace DMX2
int srcid = clientId << 8 + portId; int srcid = clientId << 8 + portId;
if (connect) { if (connect) {
string fpname= AlsaSeqLib.GetClientByID(clientId).Name + ":"+ AlsaSeqLib.GetPortByIDs (clientId, portId).Name; string fpname = AlsaSeqLib.GetClientByID (clientId).Name + ":" + AlsaSeqLib.GetPortByIDs (clientId, portId).Name;
if (!knowndevices.ContainsKey(fpname)) return; if (!knowndevices.ContainsKey (fpname))
return;
if (knowndevices [fpname].ConnectedPorts.Contains (srcid)) if (knowndevices [fpname].ConnectedPorts.Contains (srcid))
return; return;
knowndevices [fpname].ConnectedPorts.Add (srcid); knowndevices [fpname].ConnectedPorts.Add (srcid);
if(knowndevices [fpname].HasFeedback) if (knowndevices [fpname].HasFeedback)
feedbacksources.Add (srcid); feedbacksources.Add (srcid);
guirefreshflag=true; guirefreshflag = true;
//srcidToDev[srcid] = knowndevices [fpname]; //srcidToDev[srcid] = knowndevices [fpname];
@ -362,12 +373,11 @@ namespace DMX2
} }
foreach (var dev in knowndevices.Values) { foreach (var dev in knowndevices.Values) {
if(dev.ConnectedPorts.Contains (srcid)) if (dev.ConnectedPorts.Contains (srcid)) {
{
/*if(srcidToDev.ContainsKey(srcid)) /*if(srcidToDev.ContainsKey(srcid))
srcidToDev.Remove(srcid);*/ srcidToDev.Remove(srcid);*/
dev.ConnectedPorts.Remove(srcid); dev.ConnectedPorts.Remove (srcid);
guirefreshflag=true; guirefreshflag = true;
return; return;
} }
} }
@ -383,23 +393,23 @@ namespace DMX2
protected bool HasFeedback (int source) protected bool HasFeedback (int source)
{ {
return feedbacksources.Contains(source); return feedbacksources.Contains (source);
} }
public void SendEvent (AlsaSeqLib.snd_seq_event_t ev) public void SendEvent (AlsaSeqLib.snd_seq_event_t ev)
{ {
AlsaSeqLib.SendEventToSubscribers(ev); AlsaSeqLib.SendEventToSubscribers (ev);
} }
public void Refresh () public void Refresh ()
{ {
foreach (var ievent in eventlist.Values) { foreach (var ievent in eventlist.Values) {
if (ievent.Page == page){ if (ievent.Page == page) {
SendEvent(ievent.StoredEvent); SendEvent (ievent.StoredEvent);
foreach(int src in feedbacksources){ foreach (int src in feedbacksources) {
int lnvk = CombineHash(src, ievent.MidiEvCode); int lnvk = CombineHash (src, ievent.MidiEvCode);
if(ievent.LastKnownValue!=-1) if (ievent.LastKnownValue != -1)
lastValueOfSrc[lnvk] = (byte)ievent.LastKnownValue; lastValueOfSrc [lnvk] = (byte)ievent.LastKnownValue;
} }
} }
} }
@ -408,7 +418,7 @@ namespace DMX2
#region IEventProvider implementation #region IEventProvider implementation
static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex( static System.Text.RegularExpressions.Regex regexEventID = new System.Text.RegularExpressions.Regex (
@"MIDI-PAGE(?<page>\d+)-(?<id>.+)", @"MIDI-PAGE(?<page>\d+)-(?<id>.+)",
System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.RegexOptions.Compiled);
@ -420,26 +430,29 @@ namespace DMX2
if (! eventlist.ContainsKey (eventId)) { if (! eventlist.ContainsKey (eventId)) {
var res = regexEventID.Match (eventId); var res = regexEventID.Match (eventId);
if (!res.Success) return false; if (!res.Success)
return false;
uint _page = uint.Parse (res.Groups ["page"].Value); uint _page = uint.Parse (res.Groups ["page"].Value);
int _evHC = res.Groups["id"].Value.GetHashCode(); int _evHC = res.Groups ["id"].Value.GetHashCode ();
eventlist.Add (eventId, new internalEvent (eventId,_page,_evHC )); eventlist.Add (eventId, new internalEvent (eventId, _page, _evHC));
} }
eventlist[eventId].Bound = true; eventlist [eventId].Bound = true;
return true; return true;
} }
void IEventProvider.Unbind (string eventId) void IEventProvider.Unbind (string eventId)
{ {
if(! eventlist.ContainsKey(eventId)) return; if (! eventlist.ContainsKey (eventId))
eventlist[eventId].Bound = false; return;
eventlist [eventId].Bound = false;
return; return;
} }
Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler) Gtk.Menu IEventProvider.GetProviderSubMenu (EventManager.EventMenuData state, Gtk.ButtonPressEventHandler handler)
{ {
if(!connected) return null; // Si pas encore recu d'evenements => pas de menu if (!connected)
return null; // Si pas encore recu d'evenements => pas de menu
Gtk.Menu retmenu = new Gtk.Menu (); Gtk.Menu retmenu = new Gtk.Menu ();
if (levent != null) { // Creation du sous menu "Dernier" if (levent != null) { // Creation du sous menu "Dernier"
@ -447,9 +460,9 @@ namespace DMX2
retmenu.Add (lmenuitem); retmenu.Add (lmenuitem);
Gtk.Menu lmenu = new Gtk.Menu (); Gtk.Menu lmenu = new Gtk.Menu ();
lmenuitem.Submenu = lmenu;*/ lmenuitem.Submenu = lmenu;*/
Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(levent.InternalName)); Gtk.MenuItem item = new Gtk.MenuItem (GetDescription (levent.InternalName));
item.Data[EventManager.EventIdKey] = levent.InternalName; item.Data [EventManager.EventIdKey] = levent.InternalName;
item.Data[EventManager.StateKey] = state; item.Data [EventManager.StateKey] = state;
item.ButtonPressEvent += handler; item.ButtonPressEvent += handler;
retmenu.Add (item); retmenu.Add (item);
} }
@ -459,14 +472,14 @@ namespace DMX2
Gtk.Menu evmenu = new Gtk.Menu (); Gtk.Menu evmenu = new Gtk.Menu ();
evmenuitem.Submenu = evmenu; evmenuitem.Submenu = evmenu;
List<string> sortedKeys = eventlist.Keys.ToList(); // On recupere des IDs List<string> sortedKeys = eventlist.Keys.ToList (); // On recupere des IDs
sortedKeys.Sort(); // et on les trie sortedKeys.Sort (); // et on les trie
foreach ( string key in sortedKeys ) { foreach (string key in sortedKeys) {
internalEvent evt= eventlist[key]; internalEvent evt = eventlist [key];
Gtk.MenuItem item = new Gtk.MenuItem(GetDescription(evt.InternalName)); Gtk.MenuItem item = new Gtk.MenuItem (GetDescription (evt.InternalName));
item.Data[EventManager.EventIdKey] = evt.InternalName; item.Data [EventManager.EventIdKey] = evt.InternalName;
item.Data[EventManager.StateKey] = state; item.Data [EventManager.StateKey] = state;
item.ButtonPressEvent += handler; item.ButtonPressEvent += handler;
evmenu.Add (item); evmenu.Add (item);
} }
@ -480,49 +493,54 @@ namespace DMX2
AlsaSeqLib.snd_seq_event_t evS; AlsaSeqLib.snd_seq_event_t evS;
uint evpage; uint evpage;
// Tant qu'il y des evenements midi en attente // Tant qu'il y des evenements midi en attente
while (AlsaSeqLib.GetEvent(out evS)) { while (AlsaSeqLib.GetEvent(out evS)) {
string id = null; string id = null;
int value=0; int value = 0;
byte channel = 255; byte channel = 255;
switch (evS.type) { switch (evS.type) {
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED: // Connection d'un périph midi case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED: // Connection d'un périph midi
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
PortConnect( PortConnect (
evS.data_connect, evS.data_connect,
evS.type==AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED evS.type == AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_SUBSCRIBED
); );
continue; continue;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CONTROLLER:
if(evS.data_ev_ctrl.param==127 && evS.data_ev_ctrl.value >0){ if (evS.data_ev_ctrl.param == 127 && evS.data_ev_ctrl.value > 0) {
CurrentPage++; continue; CurrentPage++;
continue;
} }
if(evS.data_ev_ctrl.param==126 && evS.data_ev_ctrl.value>0){ if (evS.data_ev_ctrl.param == 126 && evS.data_ev_ctrl.value > 0) {
CurrentPage--; continue; CurrentPage--;
continue;
} }
id = string.Format("CTRL-C{0}P{1}",evS.data_ev_ctrl.channel,evS.data_ev_ctrl.param); id = string.Format ("CTRL-C{0}P{1}", evS.data_ev_ctrl.channel, evS.data_ev_ctrl.param);
channel = evS.data_ev_ctrl.channel; channel = evS.data_ev_ctrl.channel;
value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255} value = 255 * evS.data_ev_ctrl.value / 127; // Conversion {0,127} => {0,255}
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEON:
id = string.Format("NOTE-C{0}N{1}",evS.data_ev_note.channel, evS.data_ev_note.note ); id = string.Format ("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note);
channel = evS.data_ev_note.channel; channel = evS.data_ev_note.channel;
value = 255 ; value = 255;
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_NOTEOFF:
id = string.Format("NOTE-C{0}N{1}",evS.data_ev_note.channel, evS.data_ev_note.note ); id = string.Format ("NOTE-C{0}N{1}", evS.data_ev_note.channel, evS.data_ev_note.note);
channel = evS.data_ev_note.channel; channel = evS.data_ev_note.channel;
value = 0; value = 0;
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PITCHBEND:
id = string.Format("PB-C{0}",evS.data_ev_ctrl.channel); id = string.Format ("PB-C{0}", evS.data_ev_ctrl.channel);
channel = evS.data_ev_ctrl.channel; channel = evS.data_ev_ctrl.channel;
value = ((evS.data_ev_ctrl.value + 8000) *255 / 16000); value = ((evS.data_ev_ctrl.value + 7000) * 255 / 14000);
if(value<0) value =0; if(value>255) value = 255; if (value < 0)
value = 0;
if (value > 255)
value = 255;
break; break;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_CLOCK:
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_SENSING:
@ -531,16 +549,16 @@ namespace DMX2
CurrentPage = (uint)evS.data_ev_ctrl.value; CurrentPage = (uint)evS.data_ev_ctrl.value;
continue; continue;
case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_START: case AlsaSeqLib.snd_seq_event_type_t.SND_SEQ_EVENT_PORT_START:
PortDetected( PortDetected (
AlsaSeqLib.GetClientByID(evS.data_addr.client), AlsaSeqLib.GetClientByID (evS.data_addr.client),
AlsaSeqLib.GetPortByIDs(evS.data_addr.client,evS.data_addr.port) AlsaSeqLib.GetPortByIDs (evS.data_addr.client, evS.data_addr.port)
); );
continue; continue;
//TODO : Regarder si d'autres controles interessants. //TODO : Regarder si d'autres controles interessants.
default: default:
id= null; id = null;
#if DEBUG #if DEBUG
Console.WriteLine(string.Format ("event {0}", evS.type) ); Console.WriteLine(string.Format ("event {0}", evS.type) );
Info.Publish(string.Format ("event {0}", evS.type) ); // On affiche les evenements inconnus Info.Publish(string.Format ("event {0}", evS.type) ); // On affiche les evenements inconnus
@ -548,49 +566,49 @@ namespace DMX2
continue; continue;
} }
connected=true; connected = true;
if(id!=null) if (id != null) {
{
// Hashcode de l'ev Midi, non pagine // Hashcode de l'ev Midi, non pagine
int evHC = id.GetHashCode(); int evHC = id.GetHashCode ();
int srcid = evS.source.client <<8 + evS.source.port; int srcid = evS.source.client << 8 + evS.source.port;
int lnvk = CombineHash( srcid , evHC); int lnvk = CombineHash (srcid, evHC);
if(channel == 255 || unpaginatedchannels.Contains(channel)) if (channel == 255 || unpaginatedchannels.Contains (channel))
evpage= 0; evpage = 0;
else else
evpage= page; evpage = page;
// Construction de l'ID evenement // Construction de l'ID evenement
id = string.Format("MIDI-PAGE{0}-{1}",evpage,id); id = string.Format ("MIDI-PAGE{0}-{1}", evpage, id);
// Creation de l'objet interne si innexistant // Creation de l'objet interne si innexistant
if(!eventlist.ContainsKey(id)) if (!eventlist.ContainsKey (id))
eventlist.Add(id,new internalEvent(id,page,evHC)); eventlist.Add (id, new internalEvent (id, page, evHC));
levent= eventlist[id]; //Dernier Evenement recu conserve pour menu levent = eventlist [id]; //Dernier Evenement recu conserve pour menu
if(!lastValueOfSrc.ContainsKey(lnvk)) if (!lastValueOfSrc.ContainsKey (lnvk))
lastValueOfSrc[lnvk]= (byte)value; lastValueOfSrc [lnvk] = (byte)value;
EventData evData = new EventData(); EventData evData = new EventData ();
evData.id = id; evData.id = id;
evData.value = (byte)value; evData.value = (byte)value;
evData.prev_value = lastValueOfSrc[lnvk]; evData.prev_value = lastValueOfSrc [lnvk];
if(evData.Equals(last)) continue; if (evData.Equals (last))
continue;
last = evData; last = evData;
if(eventlist[id].Bound) { if (eventlist [id].Bound) {
callback(evData); callback (evData);
} }
lastValueOfSrc[lnvk] = (byte)value; lastValueOfSrc [lnvk] = (byte)value;
eventlist[id].StoredEvent = evS; eventlist [id].StoredEvent = evS;
eventlist[id].LastKnownValue = (byte)value; eventlist [id].LastKnownValue = (byte)value;
} }
} }
@ -604,59 +622,59 @@ namespace DMX2
//TODO gerer pages et feeddback //TODO gerer pages et feeddback
static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex( static System.Text.RegularExpressions.Regex regexCtrlEventID = new System.Text.RegularExpressions.Regex (
@"MIDI-PAGE(?<page>\d+)-CTRL-C(?<chan>\d+)P(?<param>\d+)", @"MIDI-PAGE(?<page>\d+)-CTRL-C(?<chan>\d+)P(?<param>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.RegexOptions.Compiled);
static System.Text.RegularExpressions.Regex regexPbEventID = new System.Text.RegularExpressions.Regex (
static System.Text.RegularExpressions.Regex regexPbEventID = new System.Text.RegularExpressions.Regex(
@"MIDI-PAGE(?<page>\d+)-PB-C(?<chan>\d+)", @"MIDI-PAGE(?<page>\d+)-PB-C(?<chan>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.RegexOptions.Compiled);
static System.Text.RegularExpressions.Regex regexNoteEventID = new System.Text.RegularExpressions.Regex (
static System.Text.RegularExpressions.Regex regexNoteEventID = new System.Text.RegularExpressions.Regex(
@"MIDI-PAGE(?<page>\d+)-NOTE-C(?<chan>\d+)N(?<note>\d+)", @"MIDI-PAGE(?<page>\d+)-NOTE-C(?<chan>\d+)N(?<note>\d+)",
System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.RegexOptions.Compiled);
string GetDescription (string eventId) string GetDescription (string eventId)
{ {
if(!eventlist.ContainsKey(eventId)) return null; if (!eventlist.ContainsKey (eventId))
return null;
var res = regexCtrlEventID.Match (eventId); var res = regexCtrlEventID.Match (eventId);
if (res.Success) { if (res.Success) {
uint page = uint.Parse(res.Groups ["page"].Value); uint page = uint.Parse (res.Groups ["page"].Value);
byte chan = byte.Parse (res.Groups ["chan"].Value); byte chan = byte.Parse (res.Groups ["chan"].Value);
uint param = uint.Parse (res.Groups ["param"].Value); uint param = uint.Parse (res.Groups ["param"].Value);
return string.Format("Page {2} => Control-Change C({0}) Param-{1}",chan+1,param,page); return string.Format ("Page {2} => Control-Change C({0}) Param-{1}", chan + 1, param, page);
} }
res = regexPbEventID.Match (eventId); res = regexPbEventID.Match (eventId);
if (res.Success) { if (res.Success) {
uint page = uint.Parse(res.Groups ["page"].Value); uint page = uint.Parse (res.Groups ["page"].Value);
byte chan = byte.Parse (res.Groups ["chan"].Value); byte chan = byte.Parse (res.Groups ["chan"].Value);
return string.Format("Page {1} => PitchBend C({0})",chan+1,page); return string.Format ("Page {1} => PitchBend C({0})", chan + 1, page);
} }
res = regexNoteEventID.Match (eventId); res = regexNoteEventID.Match (eventId);
if (res.Success) { if (res.Success) {
uint page = uint.Parse(res.Groups ["page"].Value); uint page = uint.Parse (res.Groups ["page"].Value);
byte chan = byte.Parse (res.Groups ["chan"].Value); byte chan = byte.Parse (res.Groups ["chan"].Value);
byte note = byte.Parse (res.Groups ["note"].Value); byte note = byte.Parse (res.Groups ["note"].Value);
return string.Format("Page {2} => Note C({0}) Note-{1}",chan+1,note,page); return string.Format ("Page {2} => Note C({0}) Note-{1}", chan + 1, note, page);
} }
return eventId; return eventId;
} }
IFeedbackInfo IEventProvider.GetFeedbackInfo (string eventId) IFeedbackInfo IEventProvider.GetFeedbackInfo (string eventId)
{ {
if(!eventlist.ContainsKey(eventId)) return null; if (!eventlist.ContainsKey (eventId))
return null;
var res = regexCtrlEventID.Match (eventId); var res = regexCtrlEventID.Match (eventId);
if (res.Success) { if (res.Success) {
byte chan = byte.Parse (res.Groups ["chan"].Value); byte chan = byte.Parse (res.Groups ["chan"].Value);
uint param = uint.Parse (res.Groups ["param"].Value); uint param = uint.Parse (res.Groups ["param"].Value);
return new ctrlfeedbackinfo (this, eventlist[eventId],chan, param); return new ctrlfeedbackinfo (this, eventlist [eventId], chan, param);
} }
res = regexPbEventID.Match (eventId); res = regexPbEventID.Match (eventId);
if (res.Success) { if (res.Success) {
byte chan = byte.Parse (res.Groups ["chan"].Value); byte chan = byte.Parse (res.Groups ["chan"].Value);
return new pitchbendfeedbackinfo (this, eventlist[eventId], chan); return new pitchbendfeedbackinfo (this, eventlist [eventId], chan);
} }
return null; return null;
@ -667,16 +685,19 @@ namespace DMX2
#region IDisposable implementation #region IDisposable implementation
bool disposed=false; bool disposed = false;
~MidiEventProvider(){ ~MidiEventProvider ()
Dispose(); {
Dispose ();
} }
public void Dispose () public void Dispose ()
{ {
if(disposed)return; if (disposed)
disposed=true; return;
AlsaSeqLib.Close(); disposed = true;
AlsaSeqLib.Close ();
} }
#endregion #endregion
@ -695,14 +716,15 @@ namespace DMX2
foreach (byte ch in unpaginatedchannels) { foreach (byte ch in unpaginatedchannels) {
el.AppendChild (xmlEl = parent.OwnerDocument.CreateElement ("UPC")); el.AppendChild (xmlEl = parent.OwnerDocument.CreateElement ("UPC"));
xmlEl.SetAttribute ("ch", ch.ToString()); xmlEl.SetAttribute ("ch", ch.ToString ());
} }
} }
public void Load (System.Xml.XmlElement el) public void Load (System.Xml.XmlElement el)
{ {
if(el==null) return; if (el == null)
return;
maxpage = uint.Parse (el.TryGetAttribute ("maxpage", "8")); maxpage = uint.Parse (el.TryGetAttribute ("maxpage", "8"));
foreach (var xd in el.GetElementsByTagName("MidiDev")) { foreach (var xd in el.GetElementsByTagName("MidiDev")) {
@ -712,13 +734,13 @@ namespace DMX2
knowndevices.Add (name, new MidiDev (name)); knowndevices.Add (name, new MidiDev (name));
knowndevices [name].HasFeedback = bool.Parse (xdev.TryGetAttribute ("feedback", "false")); knowndevices [name].HasFeedback = bool.Parse (xdev.TryGetAttribute ("feedback", "false"));
} }
unpaginatedchannels.Clear(); unpaginatedchannels.Clear ();
foreach (var xu in el.GetElementsByTagName("UPC")) { foreach (var xu in el.GetElementsByTagName("UPC")) {
System.Xml.XmlElement xupc = xu as System.Xml.XmlElement; System.Xml.XmlElement xupc = xu as System.Xml.XmlElement;
unpaginatedchannels.Add(byte.Parse(xupc.GetAttribute("ch"))); unpaginatedchannels.Add (byte.Parse (xupc.GetAttribute ("ch")));
} }
AutoConnect(); AutoConnect ();
} }
} }