Author Archive

Co2 emissions database available via #EEA


If you are looking for environmental data on vehicles, to judge their impact on the environment, then this dataset available from the EEA has a record of millions of european vehicles, and their CO2 footprint.

It’s available for download here;

Categories: Uncategorized

Using JsonReaderWriterFactory. CreateJsonReader in C#


Whenever you want to read JSON in C#, I don’t normally look any further than Newtonsoft.Json , but if you are not allowed to use third-party libraries in your project, then there is a little known JSON parser built into .NET (or the System.Runtime.Serialization.Json library).

But, it’s not nice to use, and who wants to use XPath Queries with Json anyway, it’s awkward and unnatural!

So, I’ve written a class that does not use any third-party libraries, but uses a similar calling structure to Newtonsoft.JSON.

using System.Collections.Generic;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml.Linq;

namespace Synergy.Common
/// <summary>
/// A simplified version of JSON
/// </summary>
public class MyJson : Dictionary<string, MyJson>
/// <summary>
/// The value of the node
/// </summary>
public string Value;

// public Dictionary<string, MyJson> Children = new Dictionary<string, MyJson>();

/// <summary>
/// Parses the specified json.
/// </summary>
/// <param name=”json”>The json.</param>
/// <returns></returns>
public static MyJson Parse(string json)
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), new System.Xml.XmlDictionaryReaderQuotas());
var xe = XElement.Load(jsonReader);
return FromElement(xe);

private static MyJson FromElement(XContainer xe)
var root = new MyJson { Value = “” };
foreach (var element in xe.Elements())
if (root.ContainsKey(element.Name.LocalName)) continue; // Don’t support duplicates so far
element.HasElements ? FromElement(element) : new MyJson {Value = element.Value});
return root;

You call MyJson.Parse() passing in some JSON, and what you get back, is a nested dictionary, where each dictionary entry can have sub-dictionaries. If it has an empty sub-dictionary, then it will have a Value property set.

The Value property is always a string, so there is no fancy date or number parsing yet, and it does not allow duplicate keys.

Feel free to comment with improvements.

Categories: Uncategorized

Get language codes from a country code in C#


Given a country code – i.e. BE (Belgium), you might want to know the most commonly spoken languages in that country – i.e FR and NL (French and Dutch), here’s some code to do that in C#, without a database lookup.

private static IEnumerable<string> GetLanguagesSpokenInCountry(string country)
var allCultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
var languagesSpoken = allCultures.Where(c =>
if (c.IsNeutralCulture) return false;
if (c.LCID == 0x7F) return false; // Ignore Invariant culture
var region = new RegionInfo(c.LCID);
return region.TwoLetterISORegionName == country;
}).Select(c => c.TwoLetterISOLanguageName.ToUpper()).ToList();
return languagesSpoken;

You might be surprised that India (IN) returns 19 languages! – on my PC.

Categories: Uncategorized

Cloud Answering Machine #app just re-launched for #android

Cloud Answering Machine is a service where you can get a second phone number hosted virtually online, that allows you to recieve voicemail and SMS messages, without requiring another physical phone, or physical phone line. What’s more, you can create a phone number anywhere in the world, so you can give the impression that your buisness is based in New York, when you really live in the UK.

The main use for a second phone line is to separate high importance calls from your work or family, from low importance calls from people who don’t need to be dealt with urgently. Perhaps separating calls from your sideline business and your day job, or even to create a phone number for purposes that you don’t want your wife or boss knowning about.

We’ve recently relaunched our app based on a purely Native platform, rather than the old Cordova based version at

Please feel free to download it – it’s free!, and please give us a good rating if you like it.

We’ve also open sourced it, so it’s free for you to build upon, or create your own companion apps for this. Check out the repo on Github:

Categories: Uncategorized

Translate #RESX files online for #free

resx  is a website that allows you upload .NET RESX files or Resource files, and have them translated into one of 25 languages automatically, and for free.

You upload the RESX file, enter in your email address, the language pair required, and the translation quality level. It then emails you back the translated RESX file in seconds (or minutes, depending on the size).

The automatic translation is powered by Yandex translate, which offers a translation API, which is called via a simple API as follows;

var strUrl = “;;
strUrl += “key=trnsl….”;
strUrl += “&text=” + text;
strUrl += “&lang=” + language;
var wc = new WebClient { Encoding = Encoding.UTF8 };
var strJson = wc.DownloadString(strUrl);
var jTranslate = JObject.Parse(strJson);
var strEnglish = jTranslate[“text”].First.ToString();
return strEnglish;


Categories: Uncategorized

Convert #3gp to #wav in c# using #ffmpeg


I recently found today that Android’s native audio recording format is 3GP ( 3rd Generation Partnership Project ), which may need to be decoded to a decompressed raw format like WAV before you do certain processing on it. My first google searches led me to Alvas, which seemed good, but their trial version has a nag screen that would break IIS, and I didn’t want to pay.

So, I turned to FFMPEG, a free tool, that’s typically used for Video conversion, but also works on audio. The command from the CLI is

ffmpeg -i bible.3gp bible.wav

Which generates the following dump of data;

ffmpeg version N-93863-g58d167bcd5 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8.3.1 (GCC) 20190414
configuration: –enable-gpl –enable-version3 –enable-sdl2 –enable-fontconfig –enable-gnutls –enable-iconv –enable-libass –enable-libdav1d –enable-libbluray –enable-libfreetype –enable-libmp3lame –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libopenjpeg –enable-libopus –enable-libshine –enable-libsnappy –enable-libsoxr –enable-libtheora –enable-libtwolame –enable-libvpx –enable-libwavpack –enable-libwebp –enable-libx264 –enable-libx265 –enable-libxml2 –enable-libzimg –enable-lzma –enable-zlib –enable-gmp –enable-libvidstab –enable-libvorbis –enable-libvo-amrwbenc –enable-libmysofa –enable-libspeex –enable-libxvid –enable-libaom –enable-libmfx –enable-amf –enable-ffnvcodec –enable-cuvid –enable-d3d11va –enable-nvenc –enable-nvdec –enable-dxva2 –enable-avisynth –enable-libopenmpt
libavutil 56. 27.100 / 56. 27.100
libavcodec 58. 52.101 / 58. 52.101
libavformat 58. 27.103 / 58. 27.103
libavdevice 58. 7.100 / 58. 7.100
libavfilter 7. 53.100 / 7. 53.100
libswscale 5. 4.101 / 5. 4.101
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from ‘bible.3gp’:
major_brand : 3gp6
minor_version : 256
compatible_brands: isom3gp6
creation_time : 2015-07-24T19:40:33.000000Z
Duration: 00:04:03.30, start: 0.000000, bitrate: 229 kb/s
Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 320×180 [SAR 1:1 DAR 16:9], 193 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 30k tbc (default)
creation_time : 2015-07-24T19:40:33.000000Z
handler_name : IsoMedia File Produced by Google, 5-11-2011
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 22050 Hz, mono, fltp, 32 kb/s (default)
creation_time : 2015-07-24T19:40:33.000000Z
handler_name : IsoMedia File Produced by Google, 5-11-2011
Stream mapping:
Stream #0:1 -> #0:0 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to ‘bible.wav’:
major_brand : 3gp6
minor_version : 256
compatible_brands: isom3gp6
ISFT : Lavf58.27.103
Stream #0:0(eng): Audio: pcm_s16le ([1][0][0][0] / 0x0001), 22050 Hz, mono, s16, 352 kb/s (default)
creation_time : 2015-07-24T19:40:33.000000Z
handler_name : IsoMedia File Produced by Google, 5-11-2011
encoder : Lavc58.52.101 pcm_s16le
size= 10478kB time=00:04:03.29 bitrate= 352.8kbits/s speed=22.7x
video:0kB audio:10478kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000727%

To, write the same code in C# it’s

Process p = new Process
StartInfo =
FileName = @”D:\Research\ffmpeg.exe”,
Arguments = @”-i d:\research\bible.3gp d:\research\bible.wav”,
WindowStyle = ProcessWindowStyle.Hidden,
RedirectStandardOutput = true,
UseShellExecute = false

.. And yes, I’m using a file called bible.3gp, not that I’m in any way religious, it was just the first 3gp file I could find online.

This code also works in a ASP.NET page, hosted by IIS, without elevated privileges.

FYI, this code is going to be used in an upcomming Android app for

Categories: Uncategorized

Simple #logging in C#


If you have some software in C# that runs unattended, or doesn’t have a graphical interface, then hunting down problems with it, can be a pain, and a simple text logger comes to the rescue.  – So at least you can check a log file to see what went wrong.

Writing a text logger isn’t complicated, in fact, it’s probably only a handful of lines of code, but it’s not something that a client or your boss is going to pay you for, it’s just a diagnostic tool, that adds nothing to the end user experience. So, it needs to be super-simple to add and use.

My favourite, so far is SimpleLogger, which you can install via nuget here;

Install-Package SimpleLogger

Then to use it, you firstly configure it as follows;

.AddHandler(new ConsoleLoggerHandler())
.AddHandler(new FileLoggerHandler())
.AddHandler(new DebugConsoleLoggerHandler());

Then write out your progress as follows;


And it outputs to the console, and to a file, which is date stamped, so you can look back over it.

The only downside is, that I guess there is no limit to the log file sizes, I’m not sure how to do cleanup, in case you write too much to the file. – And I did notice, that if you call this in a multi-threaded environment, if you get a collision (two logs at once), the logger will crash.

Anyway, top marks for simplicity!

Categories: Uncategorized