示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="recognition"></param>
        /// <param name="recording"></param>
        /// <param name="exceptionsBag"></param>
        /// <param name="cancellationToken"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <returns></returns>
        public static async Task BindRecordingAsync(
            this IStreamingRecognition recognition,
            IRecording recording,
            ExceptionsBag?exceptionsBag         = null,
            CancellationToken cancellationToken = default)
        {
            recognition = recognition ?? throw new ArgumentNullException(nameof(recognition));
            recording   = recording ?? throw new ArgumentNullException(nameof(recording));

            if (recording.Settings.Format is not AudioFormat.Raw)
            {
                if (!recording.Header.Any())
                {
                    throw new ArgumentException("recording.Header is empty.");
                }

                await recognition.WriteAsync(recording.Header, cancellationToken).ConfigureAwait(false);
            }

            if (recording.Data.Any())
            {
                await recognition.WriteAsync(recording.Data, cancellationToken).ConfigureAwait(false);
            }

            async void OnDataReceived(object?_, byte[] bytes)
            {
                try
                {
                    await recognition.WriteAsync(bytes, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    exceptionsBag?.OnOccurred(exception);
                }
            }

            void OnStopped(object?o, byte[] bytes)
            {
                try
                {
                    recording.DataReceived -= OnDataReceived;
                    recording.Stopped      -= OnStopped;
                }
                catch (Exception exception)
                {
                    exceptionsBag?.OnOccurred(exception);
                }
            }

            recording.DataReceived += OnDataReceived;
            recording.Stopped      += OnStopped;
        }
示例#2
0
        public static async Task BaseModuleTest <T1, T2>(
            string name1,
            string name2,
            Func <ExceptionsBag, T1, T2, CancellationToken, Task> testFunc)
            where T1 : class, IModule
            where T2 : class, IModule
        {
            using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(15));
            var cancellationToken = cancellationTokenSource.Token;

            var exceptions = new ExceptionsBag();

            await using var manager = new ModuleManager <IModule>(
                            Path.Combine(Path.GetTempPath(), $"H.Containers.Tests_{name1}_{name2}"));
            manager.ExceptionOccurred += (_, exception) =>
            {
                Console.WriteLine($"ExceptionOccurred: {exception}");
                exceptions.OnOccurred(exception);

                // ReSharper disable once AccessToDisposedClosure
                cancellationTokenSource.Cancel();
            };

            using var instance1 = await manager.AddModuleAsync <T1>(
                      CreateContainer (name1),
                      name1,
                      name1,
                      ResourcesUtilities.ReadFileAsBytes($"{name1}.zip"),
                      cancellationToken);

            using var instance2 = await manager.AddModuleAsync <T2>(
                      CreateContainer (name2),
                      name2,
                      name2,
                      ResourcesUtilities.ReadFileAsBytes($"{name2}.zip"),
                      cancellationToken);

            Assert.IsNotNull(instance1);
            Assert.IsNotNull(instance2);

            foreach (var instance in new IModule[] { instance1, instance2 })
            {
                instance.EnableLog();
            }

            await testFunc(exceptions, instance1, instance2, cancellationToken);

            try
            {
                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
            }
            catch (OperationCanceledException)
            {
            }

            exceptions.EnsureNoExceptions();
        }
示例#3
0
        /// <summary>
        /// Stop when values for <paramref name="silenceInMilliseconds"></paramref> of
        /// <paramref name="bufferInMilliseconds"/> will be lower than <paramref name="threshold"></paramref>. <br/>
        /// NAudioRecorder produces 100 DataReceived events per seconds. <br/>
        /// It can be set up by NAudioRecorder.Delay property. <br/>
        /// </summary>
        /// <param name="recording"></param>
        /// <param name="bufferInMilliseconds"></param>
        /// <param name="silenceInMilliseconds"></param>
        /// <param name="threshold"></param>
        /// <param name="exceptions"></param>
        public static IRecording StopWhenSilence(
            this IRecording recording,
            int bufferInMilliseconds  = 3000,
            int silenceInMilliseconds = 2500,
            double threshold          = 0.02,
            ExceptionsBag?exceptions  = null)
        {
            recording = recording ?? throw new ArgumentNullException(nameof(recording));

            var delay         = (int)recording.Settings.Delay.TotalMilliseconds;
            var bufferSize    = bufferInMilliseconds / delay;
            var requiredCount = silenceInMilliseconds / delay;

            var detector = new SilenceDetector(recording.Settings, bufferSize, requiredCount, threshold);

            detector.Detected += async(_, _) =>
            {
                try
                {
                    await recording.StopAsync().ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    exceptions?.OnOccurred(exception);
                }
            };
            recording.DataReceived += (_, bytes) =>
            {
                try
                {
                    detector.Write(bytes);
                }
                catch (Exception exception)
                {
                    exceptions?.OnOccurred(exception);
                }
            };

            return(recording);
        }
        public static void EnableLogging(
            this IServiceBase service,
            ExceptionsBag?exceptions       = null,
            CancellationTokenSource?source = null)
        {
            service.ExceptionOccurred += (_, exception) =>
            {
                Console.WriteLine($"{nameof(service.ExceptionOccurred)}: {exception}");
                exceptions?.OnOccurred(exception);
                source?.Cancel();
            };
            if (service is ICommandProducer commandProducer)
            {
                commandProducer.CommandReceived += (_, value) =>
                {
                    Console.WriteLine($"{nameof(commandProducer.CommandReceived)}: {value}");
                };
                commandProducer.AsyncCommandReceived += (_, value, _) =>
                {
                    Console.WriteLine($"{nameof(commandProducer.AsyncCommandReceived)}: {value}");

                    return(Task.FromResult(EmptyArray <IValue> .Value));
                };
            }
            switch (service)
            {
            case HookService hookService:
                hookService.UpCaught += (_, value) =>
                {
                    Console.WriteLine($"{nameof(hookService.UpCaught)}: {value}");
                };
                hookService.DownCaught += (_, value) =>
                {
                    Console.WriteLine($"{nameof(hookService.DownCaught)}: {value}");
                };
                hookService.BoundUpCaught += (_, value) =>
                {
                    Console.WriteLine($"{nameof(hookService.BoundUpCaught)}: {value.Keys}, {value.Command}");
                };
                hookService.BoundDownCaught += (_, value) =>
                {
                    Console.WriteLine($"{nameof(hookService.BoundDownCaught)}: {value.Keys}, {value.Command}");
                };
                break;

            case RecognitionService recognitionService:
                recognitionService.PreviewCommandReceived += (_, value) =>
                {
                    Console.WriteLine($"{nameof(recognitionService.PreviewCommandReceived)}: {value}");
                };
                break;

            case RunnerService runnerService:
                runnerService.CallRunning += (_, call) =>
                {
                    Console.WriteLine($"{nameof(runnerService.CallRunning)}: {call}");
                };
                runnerService.CallRan += (_, call) =>
                {
                    Console.WriteLine($"{nameof(runnerService.CallRan)}: {call}");
                };
                runnerService.CallCancelled += (_, call) =>
                {
                    Console.WriteLine($"{nameof(runnerService.CallCancelled)}: {call}");
                };
                runnerService.NotSupported += (_, command) =>
                {
                    Console.WriteLine($"{nameof(runnerService.NotSupported)}: {command}");
                };
                break;
            }
        }
示例#5
0
        /// <summary>
        /// Dispose is required!.
        /// </summary>
        /// <param name="recognizer"></param>
        /// <param name="recorder"></param>
        /// <param name="exceptionsBag"></param>
        /// <param name="cancellationToken"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public static async Task <IStreamingRecognition> StartStreamingRecognitionAsync(
            this IRecognizer recognizer,
            IRecorder recorder,
            ExceptionsBag?exceptionsBag         = null,
            CancellationToken cancellationToken = default)
        {
            recognizer = recognizer ?? throw new ArgumentNullException(nameof(recognizer));
            recorder   = recorder ?? throw new ArgumentNullException(nameof(recorder));

            if (!recognizer.SupportedStreamingSettings.Any())
            {
                throw new ArgumentException("Recognizer does not support streaming recognition.");
            }

            var isStopped = false;
            var settings  = recognizer.SupportedStreamingSettings.First();
            var recording = await recorder.StartAsync(settings, cancellationToken)
                            .ConfigureAwait(false);

            recording.StopWhenSilence();

            var recognition = await recognizer.StartStreamingRecognitionAsync(settings, cancellationToken)
                              .ConfigureAwait(false);

            recognition.Stopping += async(_, _) =>
            {
                if (isStopped)
                {
                    return;
                }

                try
                {
                    await recording.StopAsync(cancellationToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    exceptionsBag?.OnOccurred(exception);
                }
                finally
                {
                    recording.Dispose();
                }
            };
            recording.Stopped += async(_, _) =>
            {
                isStopped = true;

                try
                {
                    await recognition.StopAsync(cancellationToken).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    exceptionsBag?.OnOccurred(exception);
                }
                finally
                {
                    recording.Dispose();
                }
            };

            await recognition.BindRecordingAsync(recording, exceptionsBag, cancellationToken).ConfigureAwait(false);

            return(recognition);
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="process"></param>
        /// <param name="cancellationToken"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        /// <returns></returns>
        public async Task <Rectangle> SelectAsync(
            IProcess <ICommand> process,
            CancellationToken cancellationToken = default)
        {
            process = process ?? throw new ArgumentNullException(nameof(process));

            if (Window == null)
            {
                await InitializeAsync(cancellationToken).ConfigureAwait(false);
            }

            Window = Window ?? throw new InvalidOperationException("Window is null.");

            var scaleFactor = await Dispatcher.InvokeAsync(
                () => Window.GetDpi(),
                DispatcherPriority.Normal,
                cancellationToken);

            var startPoint   = new Point();
            var endPoint     = new Point();
            var currentPoint = new Point();

            using var exceptions = new ExceptionsBag();
            using var hook       = new LowLevelMouseHook
                  {
                      GenerateMouseMoveEvents = true,
                  };
            hook.ExceptionOccurred += (_, exception) =>
            {
                // ReSharper disable once AccessToDisposedClosure
                exceptions.OnOccurred(exception);
            };

            var isInitialized = false;

            hook.Move += (_, args) =>
            {
                currentPoint = args.Position;
                if (isInitialized)
                {
                    return;
                }

                startPoint    = currentPoint.ToApp(scaleFactor);
                endPoint      = startPoint;
                isInitialized = true;
            };
            hook.Start();

            using var timer = new Timer(15);
            timer.Elapsed  += (_, _) =>
            {
                if (!isInitialized)
                {
                    return;
                }

                endPoint = currentPoint.ToApp(scaleFactor);

                Dispatcher.Invoke(() =>
                {
                    ApplyRectangle(
                        Window,
                        startPoint,
                        endPoint);
                });
            };
            timer.Start();

            await Dispatcher.InvokeAsync(() =>
            {
                ApplyRectangle(
                    Window,
                    startPoint,
                    endPoint);
                Window.Border.Visibility = Visibility.Visible;
            }, DispatcherPriority.Normal, cancellationToken);

            await process.WaitAsync(cancellationToken).ConfigureAwait(false);

            timer.Dispose();
            hook.Dispose();

            await Dispatcher.InvokeAsync(() =>
            {
                Window.Border.Visibility = Visibility.Hidden;
            }, DispatcherPriority.Normal, cancellationToken);

            return(startPoint
                   .ToRectangle(endPoint)
                   .Normalize()
                   .ToPhysical(scaleFactor));
        }