// TODO: The order of data in the matrix is reverse of the channel index. // m[11] => channel 0, etc. protected override void Write(ONIContextTask ctx, Arr input) { var inputMatrix = input.GetMat(); // Check dims var size = inputMatrix.Rows * inputMatrix.Cols; if (size % AnalogInputDataFrame.NumberOfChannels != 0) { throw new IndexOutOfRangeException("Source must contain a multiple of 12 elements."); } if (DataType == AnalogDataType.S16 && inputMatrix.Depth == Depth.S16) { var data = new Mat(inputMatrix.Size, Depth.U16, 1); CV.ConvertScale(inputMatrix, data, 1, 32768); ctx.Write((uint)DeviceAddress.Address, data.Data, 2 * size); } else if (DataType == AnalogDataType.Volts && (inputMatrix.Depth == Depth.F32 || inputMatrix.Depth == Depth.F64)) { var data = new Mat(inputMatrix.Size, Depth.U16, 1); CV.ConvertScale(inputMatrix, data, 3276.75, 32768); ctx.Write((uint)DeviceAddress.Address, data.Data, 2 * size); } else { throw new Bonsai.WorkflowRuntimeException("Source element depth must Depth.S16 when " + "DataType is S16 and either Depth.F32 or Depth.F64 when Datatype is Volts."); } }
protected abstract void Write(ONIContextTask ctx, TSource input);
protected override void OnFinally(ONIContextTask ctx) { WriteRegister((int)Register.TRIGGER, 0); }
protected override void OnNext(ONIContextTask ctx, bool triggered) { WriteRegister((int)Register.TRIGGER, (uint)(triggered ? 1 : 0)); }
protected override void OnNext(ONIContextTask ctx, bool enabled) { ClockEnabled = enabled; }
protected override void Write(ONIContextTask ctx, ulong input) { writeArray[0] = (uint)(input & uint.MaxValue); writeArray[1] = (uint)(input >> 32); ctx.Write((uint)DeviceAddress.Address, writeArray); }
public ONIContextDisposable(ONIContextTask contextTask, IDisposable disposable, object contextLock) { Context = contextTask ?? throw new ArgumentNullException(nameof(contextTask)); resource = disposable ?? throw new ArgumentNullException(nameof(disposable)); lockObject = contextLock ?? throw new ArgumentNullException(nameof(contextLock)); }
protected override void Write(ONIContextTask ctx, int input) { ctx.Write((uint)DeviceAddress.Address, (uint)input); }
protected virtual void OnFinally(ONIContextTask ctx) { }
protected abstract void OnNext(ONIContextTask ctx, TSource source);
public static ONIContextDisposable ReserveContext(ONIHardwareSlot slot, bool releaseWaiting = false, bool resetRunning = false) { var contextCounted = default(Tuple <ONIContextTask, RefCountDisposable>); lock (openContextLock) { if (string.IsNullOrEmpty(slot.Driver)) { contextCounted = openContexts.Count == 1 ? openContexts.Values.Single() : throw new ArgumentException("An ONI hardware slot must be specified.", nameof(slot)); } if (!openContexts.TryGetValue(slot.MakeKey(), out contextCounted)) { var configuration = LoadConfiguration(); if (configuration.Contains(slot.MakeKey())) { slot = configuration[slot.MakeKey()]; } var ctx = new ONIContextTask(slot.Driver, slot.Index); var dispose = Disposable.Create(() => { ctx.Dispose(); contextWaitHandles[slot.MakeKey()].Reset(); // Context and wait handles are removed from dictionaries together openContexts.Remove(slot.MakeKey()); contextWaitHandles.Remove(slot.MakeKey()); }); if (!contextWaitHandles.TryGetValue(slot.MakeKey(), out EventWaitHandle waitHandle)) { contextWaitHandles.Add(slot.MakeKey(), new EventWaitHandle(false, EventResetMode.ManualReset)); } if (releaseWaiting) { contextWaitHandles[slot.MakeKey()].Set(); } var referenenceCount = new RefCountDisposable(dispose); contextCounted = Tuple.Create(ctx, referenenceCount); openContexts.Add(slot.MakeKey(), contextCounted); return(new ONIContextDisposable(ctx, referenenceCount, openContextLock)); } if (resetRunning) { contextCounted.Item1.Reset(); } if (releaseWaiting) { // Will already be created if we in this portion of code. contextWaitHandles[slot.MakeKey()].Set(); } #if DEBUG Console.WriteLine("Context slot " + slot + " reserved by " + new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType); #endif return(new ONIContextDisposable(contextCounted.Item1, contextCounted.Item2.GetDisposable(), openContextLock)); } }