This commit is contained in:
parent
0610ed4150
commit
89fd0f36c6
4 changed files with 306 additions and 261 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,25 +104,27 @@ 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);
|
||||||
|
|
@ -130,27 +133,30 @@ namespace DMX2
|
||||||
|
|
||||||
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,20 +211,22 @@ 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;
|
||||||
|
|
||||||
|
|
@ -231,62 +241,66 @@ namespace DMX2
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
EventData last;
|
||||||
internalEvent levent=null;
|
internalEvent levent = null;
|
||||||
bool connected=false;
|
bool connected = false;
|
||||||
|
bool guirefreshflag = false;
|
||||||
bool guirefreshflag=false;
|
uint page = 1;
|
||||||
|
uint maxpage = 8;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
@ -484,45 +497,50 @@ namespace DMX2
|
||||||
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 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue