loupiottes/DMX-2.0/AlsaSeqLib.cs

199 lines
4.8 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace DMX2
{
public static partial class AlsaSeqLib
{
static SeqHandleWrapper seq_handle=null;
static int clientId;
static int inport;
static int outport;
public class Client
{
int id;
snd_seq_client_type_t type;
string name;
List<Port> ports = new List<Port>();
public int Id {
get {
return id;
}
}
public snd_seq_client_type_t Type {
get {
return type;
}
}
public string Name {
get {
return name;
}
}
public ReadOnlyCollection<Port> Ports {
get {
return ports.AsReadOnly();
}
}
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);
name = nameptr.PtrToString();
type = (snd_seq_client_type_t)Invoke.snd_seq_client_info_get_type(clientInfo.Pointer);
using (PointerWrapper portInfo = new PointerWrapper(GetPortInfoSize ())) {
Invoke.snd_seq_port_info_set_client (portInfo.Pointer, id);
Invoke.snd_seq_port_info_set_port (portInfo.Pointer, -1);
while(Invoke.snd_seq_query_next_port(seq_handle.Handle, portInfo.Pointer) >= 0) {
ports.Add(new Port(portInfo));
}
}
}
public override bool Equals (object obj)
{
return ((Client)obj).id == id;
}
}
public class Port
{
int portId;
int clientId;
string name;
uint caps;
uint type;
public int ClientId {
get {
return clientId;
}
}
public int PortId {
get {
return portId;
}
}
public string Name {
get {
return name;
}
}
public uint Caps {
get {
return caps;
}
}
public uint Type {
get {
return type;
}
}
internal Port(PointerWrapper portInfo){
clientId = Invoke.snd_seq_port_info_get_client(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);
type = Invoke.snd_seq_port_info_get_type(portInfo.Pointer);
name = namePtr.PtrToString();
}
}
public static void Init ()
{
if(seq_handle!=null) return;
seq_handle = new SeqHandleWrapper();
clientId = Invoke.snd_seq_client_id(seq_handle.Handle);
inport= Invoke.snd_seq_create_simple_port(seq_handle.Handle,"dmx_ctrl_in",
SND_SEQ_PORT_CAP_WRITE + SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_APPLICATION);
outport= Invoke.snd_seq_create_simple_port(seq_handle.Handle,"dmx_ctrl_out",
SND_SEQ_PORT_CAP_READ + SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_APPLICATION);
}
public static bool GetEvent(out snd_seq_event_t ev){
if(seq_handle==null) throw new InvalidOperationException();
ev = new snd_seq_event_t();
if(Invoke.snd_seq_event_input_pending(seq_handle.Handle,1)<=0) return false;
IntPtr evPtr;
// Recup du pointeur vers l'ev
Invoke.snd_seq_event_input(seq_handle.Handle, out evPtr);
// Copie de la zone mémoire dans une structure managee
ev =(snd_seq_event_t) Marshal.PtrToStructure(evPtr,typeof(snd_seq_event_t));
// liberation du pointeur
Invoke.snd_seq_free_event(evPtr);
// TODO : Manage System Events here
return true;
}
static PointerWrapper evOutPtr = new PointerWrapper(32);
public static void SendEventToSubscribers (snd_seq_event_t ev)
{
if(seq_handle==null) throw new InvalidOperationException();
ev.queue = SND_SEQ_QUEUE_DIRECT;
ev.source.port = (byte) outport;
ev.dest.client=SND_SEQ_ADDRESS_SUBSCRIBERS;
ev.dest.port= SND_SEQ_ADDRESS_UNKNOWN;
Marshal.StructureToPtr(ev,evOutPtr.Pointer,false);
Invoke.snd_seq_event_output(seq_handle.Handle,evOutPtr.Pointer);
Invoke.snd_seq_drain_output(seq_handle.Handle);
}
public static IEnumerable<Client> EnumClients ()
{
using (PointerWrapper clientInfo = new PointerWrapper(GetClientInfoSize())) {
Invoke.snd_seq_client_info_set_client(clientInfo.Pointer, -1);
while (Invoke.snd_seq_query_next_client(seq_handle.Handle,clientInfo.Pointer)>=0) {
yield return new Client(clientInfo);
}
}
}
public static bool Connect(Port port)
{
// TODO : detecter le sens et se connecter au port.
return false;
}
public static bool ConnectTo(int client, int port){
return Invoke.snd_seq_connect_to(seq_handle.Handle,outport,client,port)==0;
}
public static bool ConnectFrom(int client, int port){
return Invoke.snd_seq_connect_from(seq_handle.Handle,inport,client,port)==0;
}
}
}