Speech synthesis in Windows with C#

As part of a little side project, I wanted to have Windows speak some text is response to a call to a service. Initially I started to look at Cortana, but this seemed overkill for my initial needs (i.e. you need to write a bot, deploy it to Azure etc.), whereas System.Speech.Synthesis offers a simple API to use text to speech.

Getting started

It can be as simple as this, add the System.Speech assembly to your references then we can use the following

using (var speech = new SpeechSynthesizer())
{
   speech.Volume = 100; 
   speech.Rate = -2; 
   speech.Speak("Hello World");
}

Volume takes a value between [0, 100] and Rate which is the speaking rate can range between [-10, 10].

Taking things a little further

We can also look at controlling other aspects of speech such as emphasis, when the word should be spelled out and ways to create “styles” for different sections of speech. To use these we can use the PromptBuilder. Let’s start by create a “style” for a section of speech

var promptBuilder = new PromptBuilder();

var promptStyle = new PromptStyle
{
   Volume = PromptVolume.Soft,
   Rate = PromptRate.Slow
};

promptBuilder.StartStyle(promptStyle);
promptBuilder.AppendText("Hello World");
promptBuilder.EndStyle();

using (var speech = new SpeechSynthesizer())
{
   speech.Speak(promptBuilder);
}

We can build up our speech from different styles and include emphasis using

promptBuilder.AppendText("Hello ", PromptEmphasis.Strong);

we can also spell out words using

promptBuilder.AppendTextWithHint("Hello", SayAs.SpellOut);

Speech Recognition

The System.Speech assembly also includes the ability to recongize speech. This will require the Speech Recongition software within Windows to run (see Control Panel | Ease of Access | Speech Recognition.

To enable your application to use speech recognition you need to execute the following

SpeechRecognizer recognizer = new SpeechRecognizer();

Just executing this will allow the speech recognition code (on the focused application) to do things like execute button code as if the button was pressed. You can also hook into events to use recogonised speech within your application, for example using

SpeechRecognizer recognizer = new SpeechRecognizer();
recognizer.SpeechRecognized += (sender, args) => 
{ 
   input.Text = args.Result.Text; 
};

gitconfig, the where and how’s

The git configuration files are stored at three different levels.

Local are stored within the cloned repository’s .git folder and the file is named config.

Global is stored in a file with no name and with the extension .gitconfig. It’s stored in your home directory. On Windows this can be confusing especially if the home directory is in a roaming profile. For example, normally we’d find the it in c:\users\your-user-name, however if you have a roaming profile then you’ll need to check

HOME="$HOMEDRIVE$HOMEPATH"

So for example this might end up as H:\

System is stored as gitconfig (filename but no extension). In the case of a Windows OS, this will be in C:\Program Files\Git\mingw64\etc, further configuration data may be found in the config file (filename but no extension) within C:\ProgramData\Git.

Scope

The scope of these files is as follows, local overrides global options and global overrides system.

List the configurations

If you execute the command below, you’ll see a list of all the configuration along with the location of the files used.

git config --list --show-origin

Note: beware if passwords are stored in the configuration then these will be displayed when you run this command.

The command does not show you what’s “actually” being used for configuration from the current repo. so much as “here’s all the configuration values”, so you’ll need to look at the scope of each file to determine what values are currently being used by git.

We can also use the same command along with the switch –local, –system and –global to list the files used along with the configuration used.

Further reading

git-config
git config (Atlassian)

A .NET service registered with Eureka

To create a .NET service which is registered with Eureka we’ll use the Steeltoe libraries…

Create an ASP.NET Core Web Application and select WebApi. Add the Steeltoe.Discovery.Client NuGet package, now in the Startup.cs within ConfigureServices add the following

services.AddDiscoveryClient(Configuration);

and within the Configure method add

app.UseDiscoveryClient();

We’re not going to create any other code to implement a service, but we will need some configuration added to the appsettings.json file, so add the following

"spring": {
    "application": {
      "name": "eureka-test-service"
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldRegisterWithEureka": true,
      "shouldFetchRegistry": false
    },
    "instance": {
      "hostname": "localhost",
      "port": 5000
    }
  }

The application name is what’s going to be displayed within Eureka and visible via http://localhost:8761/eureka/apps (obviously replacing the host name and ip with your Eureka server’s).

Spring boot Eureka server

Using Spring boot, we can very easily run up a Eureka server.

In IntelliJ create a new project using the Spring Initializr, simply select the Eureka Server dependency.

Once the application is create, I found I needed to add the @EnableEurekaServer annotation to the application class, so here’s my EurekatesApplication.java

package com.putridparrot.eurekatest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekatestApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekatestApplication.class, args);
    }
}

Next we need to add the following properties to the resources/application.properties

server.port=8761

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF

Now when you run the application and view the web page http://localhost:8761/, you should see the Spring Eureka web page. Running http://localhost:8761/eureka/apps from your preferred browser will list any applications registered with the server.

At this point we’ve not application registered with the server, so let’s add a .NET server in the next post.

Xamarin UITest (on Android)

Having used the likes of TestStack.White in the past I was interested in trying out the Xamarin UITest library for executing tests against my mobile application’s UI.

For now I’m primarily discussing testing against an Android device or emulator, but I will amend the post as and when I run tests against iOS.

Some problems and solutions

It didn’t go smoothly, initially, getting a project running. Hence, this part of the post is going to cover some of the issues I had and some of the possible solutions.

  • If you have platform-tools.old followed by a number of digits within C:\Program Files (x86)\Android\android-sdk (for example platform-tools.old1970091580), either delete these folders or for safety’s sake, move them outside of the C:\Program Files (x86)\Android\android-sdk folder, otherwise running the UITests seems to get confused which adk it should use.
  • Add an environment variable (if not already existing) named ANDROID_HOME and set it’s value to your install of the android-sdk, i.e. C:\Program Files (x86)\Android\android-sdk
  • The version of the UITest NuGet package seems to be related to the version of the Android SDK, so after you’ve created a UITest project and added the Xamarin.UITest package, depending on the Android SDK you might need to get a previous version of this package – in my case I’m using Xamarin.UITest version 2.2.7.0 and Android SDK Tools 26.1.1
  • For an Android application, we need to set the project properties Android Manifest, Required permissions to include the INTERNET permission
  • For Android projects we need to run against a Release build
  • Again for Android projects, if we added a UITest project which include the ApplInitializer.cs file, we need to supply the application name or the path to the .apk file being used, for example
    if(platform == Platform.Android)
    {
       return ConfigureApp
          .Android
          .InstalledApp("com.putridparrot.MyApp")
          .PreferIdeSettings()
          .EnableLocalScreenshots()
          .StartApp();
    }
    

    Note: In place of InstalledApp we could use ApkFile with the path of our apk file, i.e.

       .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
    
  • If you’ve previously installed your application on the emulator or device, I found it best to manually uninstall it first
  • Before running your tests, make sure the emulator is running or the device is connected (I know, probably obvious)

Creating our UI test project

  • Add a Xamarin.UITest Cross-Platform Test Project to your solution
  • Build the project so it restores any missing NuGet packages, I needed to update the following packages to Xamarin.UITest version 2.2.7.0 and NUnit 3.11.0.0
  • Deploy your application to your device before running the tests
  • When running your tests, they may take a little time before you see anything happening on the emulator or device – so don’t be too impatient.

Before we can actually run our tests (which we’ll discuss next) we need to build our application and generate an APK for Android (if running against Android).

Writing our UI tests

To allow our UITests to locate controls in our user interface we supply each control (that we need to interact with) with an AutomationId, this should be unique (so it’s easy for our tests to locate).

For Android application I found this configuration works (obviously replace the ApkFile location/name with your apk).

if(platform == Platform.Android)
{
   return ConfigureApp
      .Android
      .ApkFile(@"C:\Development\MyApp\com.putridparrot.MyApp.apk")
      .PreferIdeSettings()
      .EnableLocalScreenshots()
      .StartApp();
}

Note: we should be able to replace the ApkFile line with .InstalledApp(“com.putridparrot.MyApp”) if you prefer.

The UITest project will require an AppInitializer.cs file which, if you created via the project template, will be included. Here’s an example of one

public class AppInitializer
{
   public static IApp StartApp(Platform platform)
   {
      if(platform == Platform.Android)
      {
         return ConfigureApp
            .Android
            .InstalledApp("com.putridparrot.MyApp")
            .PreferIdeSettings()
            .EnableLocalScreenshots()
            .StartApp();
     }
     return ConfigureApp
        .iOS
        .StartApp();
}

Test files (again the project template will include a Tests.cs file) might look like this

[TestFixture(Platform.Android)]
[TestFixture(Platform.iOS)]
public class Tests
{
   private IApp _app;
   private readonly Platform _platform;

   private static readonly 
      Func<AppQuery, AppQuery> LoginButton = 
         c => c.Marked("Login");

   public Tests(Platform platform)
   {
      _platform = platform;
   }

   [SetUp]
   public void BeforeEachTest()
   {
      _app = AppInitializer.StartApp(_platform);
   }

   [Test]
   public void DoesNothing()
   {
      // Arrange
      // Act
      // Assert
   }
}

Writing UI tests is much the same as writing standard unit tests, we mark our test methods with the NUnit TestAttribute, then Arrange, Act and Assert our UI. For example let’s assume we have a button with an AutomationId Login then we can create a static field within our Test class like this

private static readonly 
   Func<AppQuery, AppQuery> LoginButton = 
      c => c.Marked("Login");

This function can be used within various _app methods, such as _app.Tap(LoginButton).

As you’ve guessed I’m testing a login UI, so assuming we have a login screen with username, password and a login button we might setup our tests like this…

First Arrange our UI, for example check that we’re on the correct screen and we’ve entered a username and password. Then we’d Act by tapping the Login button then finally Assert by checking we’ve moved on from the Login screen.

REPL

When we run our tests we might want to run the _app.Repl() method which will display a REPL command line, this allows us to view the tree representing our UI.

References

Cannot run XAMARIN UI TEST on xamarin.forms, error System.Exception

The Elvis (conditional null) operator is not magic

I was looking over somebody else’s code the other day and was intrigued by the liberal use of the Elvis or correctly known as, conditional null operator, i.e. the ?.

I assumed that for every ?. the compiler would create an IF statement, but it did make me wonder whether the compiler was actually able to optimize such code (where the ?. is used multiple times on the same object), so for example, what’s produced in IL for the following

var s = ??? // null or an instance 
Console.WriteLine(s?.Name?.Length);
Console.WriteLine(s?.Name);

My assumption would be that (without any optimization) we’d end up with the following

Console.WriteLine(s != null ? (s.Name != null ? s.Name.Length : 0) : 0);
Console.WriteLine(s != null ? s.Name : null);

Or, would if magically create code like this

object o = null;
int? l = null;

if (s != null)
{
   o = s.Name;
   if (s.Name != null)
   {
      l = s.Name.Length;
   }
}

Console.WriteLine(l);
Console.WriteLine(o);

With the first snippet of code, a best case scenario results in the IF statement being called twice (when s is null), the worst case (when nothing is null) is that the IF statement will be called three times. Whereas the second example would have the IF called once (when s is null) and twice in the worst case (when nothing is null).

Ofcourse the easiest way to see what happens is to fire up ILSpy and take a look at the generated IL/C# code. Here’s the C# that ILSpy created for us based upon the IL

object obj;
if (s == null)
{
   obj = null;
}
else
{
   string name = s.Name;
   obj = ((name != null) ? new int?(name.Length) : null);
}
Console.WriteLine((int?)obj);
Console.WriteLine((s != null) ? s.Name : null);

In this code, the best case (when s is null), the IF statement is called twice and worst case (when nothing is null), it’s called three times.

This is a simple example, but it’s worth being aware of what code is being produced using such syntactic sugar.

Solution specific NuGet repository locations

Whether we’re making our code available to others or want to simply implement solution specific changes to our NuGet repository locations, we can create a NuGet.config file which is stored in the same location as our solution. Here’s a simple example of a NuGet.config which adds a local NuGet location

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
       <add key="Local" value="c:\Development\LocalNuGet" />
    </packageSources>
</configuration>

References

Configuring NuGet behavior

Tasks and CancellationTokens

We’re executing some code on a background thread using the Task API, for example let’s create a really simple piece of code where we loop on a task every second and call UpdateStatus to display the current iteration to some UI control, such as this

Task.Factory.StartNew(() =>
{
   for (var i = 1; i <= 100; i++)
   {
      UpdateStatus(i.ToString());
      Thread.Sleep(1000);
   }
});

Now this is fine, but what about if we want to call this code multiple times, stopping any previous iterations or we simply want a way to cancel the thread mid-operation.

Cancellation is a co-operative process, i.e. we can call the Cancel method on a CancellationTokenSource but we still need code within our task’s loop (in this case) to check if cancel has been called and then exit the loop.

The cancellation token is actually taken from CancellationTokenSource which acts as a wrapper for a single token (see References for information about this separation of concerns). So in our class we’d have the following member field

private CancellationTokenSource _cancellationTokenSource;

If the code which uses this token is called prior to completion then we’d potentially want to call the Cancel method on it and then dispose of it.

_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();

As mentioned, the separation of the token source and token means that when we execute a task we pass, not the token source, but a token take from the source, i.e.

var cancellationToken = _cancellationTokenSource.Token;
Task.Factory.StartNew(() =>
{
   // do something
}, cancellationToken);

The final piece of using the cancellation token is within our task, where we need to check if the cancellation token has been cancelled and if so, we can throw an exception using the following

cancellationToken.ThrowIfCancellationRequested();

Here’s a very simple example of using the cancellation token

public partial class MainWindow : Window
{
   private CancellationTokenSource _cancellationTokenSource;

   public MainWindow()
   {
      InitializeComponent();
   }

   private void Start_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);

      _cancellationTokenSource = new CancellationTokenSource();
      var cancellationToken = _cancellationTokenSource.Token;

      UpdateStatus("Starting");
      Task.Factory.StartNew(() =>
      {
         for (var i = 1; i <= 100; i++)
         {
            cancellationToken.ThrowIfCancellationRequested();

            UpdateStatus(i.ToString());

            Thread.Sleep(1000);
         }
      }, cancellationToken)
      .ContinueWith(ca =>
      {
         DisposeOfCancellationTokenSource();
      }, TaskContinuationOptions.OnlyOnFaulted);
   }

   private void UpdateStatus(string status)
   {
      Status.Dispatcher.Invoke(() => Status.Content = status);
   }

   private void DisposeOfCancellationTokenSource(bool cancelFirst = false)
   {
      if (_cancellationTokenSource != null)
      {
         if (cancelFirst)
         {
            _cancellationTokenSource.Cancel();
            UpdateStatus("Cancel called");
         }
         _cancellationTokenSource.Dispose();
         _cancellationTokenSource = null;
         UpdateStatus("TokenSource Disposed");
      }
   }

   private void Stop_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);
   }
}
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Start" Margin="10" Click="Start_OnClick"/>
        <Button Grid.Row="1" Content="Stop" Margin="10" Click="Stop_OnClick"/>
        <Label Grid.Row="2" Name="Status" Content=""/>
    </Grid>

References

Why CancellationToken is separate from CancellationTokenSource?
Task Cancellation
CancellationTokenSource.Dispose Method

Java’s Linq equivalent, Streams

I was working on a previous post on Java and GraphQL and wanted to use a Linq query. Java doesn’t have Linq but it does have something equivalent (in Java 8) called Stream. For the examples within this post we’ll create the following simple method for generating our test data

private static List<String> getData() {
   return Arrays.asList(
      "2", "2", "2", "4", "4", 
      "6", "7", "7", "9", "10");
}

Let’s look at some of the standard sort of functionality…

Distinct

We can get a distinct stream from our data using

Stream<String> distinct = getData()
   .stream()
   .distinct();

Selection/Filtering

If we want to filter our data to select only strings longer than one character, for example, then we can use the following

Stream<String> where = getData()
   .stream()
   .filter(s -> s.length() > 1);

Matching

There are several methods which return a Boolean, for example if all items in the Stream are of a certain value, or any of the values no matches, for example

boolean allMatch = getData()
   .stream()
   .allMatch(s -> s.contains("4"));

boolean anyMatch = getData()
   .stream()
   .anyMatch(s -> s.contains("4"));

boolean noneMatch = getData()
   .stream()
   .noneMatch(s -> s.contains("4"));

Map

In scenarios where we wish to change the data returned from a stream (i.e. like Select in Linq), for example we’ll simply loop through each item and return the length of each string as a Stream, we can use

Stream<Integer> select = getData()
   .stream()
   .map(String::length);

Reduce

If we want to take a stream and reduce it to a single value, for example taking our data and concatenating into a single String, we could use the following

String reduce = getData()
   .stream()
   .reduce("", (a, b) -> a + b);

The initial value “” in this case is a starting value for the reduced value, in this case we’re not wanting to prepend anything to our string. The result of the reduce is a String with the value 22244677910.

Creating an empty Stream

We can create an empty Stream (useful in those situations where we do not wish to return a null) using

Stream<String> empty = Stream.empty();

Iteration

We can iterate over the Stream using the forEach method, for example

getData()
   .stream()
   .forEach(s -> System.out.println(s));

Parallel Streams

We can also parallelize (is that a word) our Stream using the parallelStream, for example

Stream<Integer> parallel = getData()
   .parallelStream()
   .map(String::length);

As you’d expect the order or processing of the map in this instance is indeterminate.

Obviously there’s more to Stream than I’ve listed here, but you get the idea.

Creating a TaskScheduler

In my previous post, ExecutorService based multi-threading in Java, I looked at the ExectorService which allows us to create our own fixed size threadpool which can, at times, be extremely useful.

As part of a port of some Java code (which used the ExectorService) to C# I had a need for a similar class in .NET and came across the LimitedConcurrencyLevelTaskScheduler which is part of the Samples for Parallel Programming with the .NET Framework. The code and example of this class can also be found here, TaskScheduler Class.

The Task factory’s StartNew method comes with an overload which takes a TaskScheduler class and this is where the LimitedConcurrencyLevelTaskScheduler is used. For example

var taskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);
var tsk = Task.Factory.StartNew(() =>
{
   // do something
}, 
CancellationToken.None, 
TaskCreationOptions.None, 
taskScheduler);

So, if we’re in a situation where we need to create a new TaskScheduler then we simply implement a TaskScheduler class, here’s the required overrides.

public class MyTaskScheduler : TaskScheduler
{
   protected override IEnumerable<Task> GetScheduledTasks()
   {
   }

   protected override void QueueTask(Task task)
   {
   }

   protected override bool TryExecuteTaskInline(
      Task task, bool taskWasPreviouslyQueued)
   {
   }
}

The QueueTask method is called when a Task is added to the scheduler. In the case of an implementation such as LimitedConcurrencyLevelTaskScheduler, this is where we add a task to a queue prior to executing the task.

TryExecuteTaskInline is called when trying to execute a task on the current thread, it’s passed a Boolean taskWasPreviouslyQueued which denotes whether the task has already been queued.

GetScheduledTasks is called to get an enumerable of the tasks currently scheduled within our TaskScheduler.

Optionally, we may wish to override the MaximumConcurrencyLevel property which stipulates the maximum concurrency level supported (i.e. number of threads), the default is MaxValue. Also where we might be maintaining a queue of tasks, we wold want to override the TryDequeue method for when the scheduler tries to remove a previously scheduled task.

Obviously implementing the TaskScheduler will also require the developer to handle any thread synchronization etc. within the implementation.