DigiChain v1.3.0

DigiChain is a web app made to make the creation of sample chains as easy as possible for use on the Digitakt (and any other sampler that can slice up samples).


While originally created as a tool to help make evenly spaced sample chains to use on the Elektron Digitakt’s slice grid machine introduced in the 1.5 firmware update, DigiChain has grown to incorporate other features, many of which were suggested by the good folks over on the Elektronauts forum.


  • Import .wav/.syx audio files and converts them to the chosen audio context (e.g. 48k/16bit, 44.1k/24bit etc) – if the chosen context is mono, stereo samples can be processed as the Left, Right, or a Sum of both channels to mono when exporting, the playback preview of the sample will reflect this choice. In a stereo context, mono files stay as mono (unless the sample has been resampled in this context). The audio context can be changed, but sample rate changes require the list to be discarded.
  • Batch conversion – importing multiple files, or dropping folders containing files into the list and using the Download All button will output a zip file with the dropped folder structure reflected, but the contained samples will be output in the chosen audio context.
  • Master pitch selection allows all exports to be pitched up 1, 2, or 3 octaves – so save precious sample memory space on limited storage devices such as the Digitakt/Model:Samples, or simply to get longer sample lengths loaded into memory by pitching them back down on the device.
  • Using the Slice Grid option allows you to create sample chains of the files selected in the list, download with the joined button to get all the files joined together into file(s), each with up to the slice grid amounts number of samples in each file.
  • The joined spaced button will pad each sample in the chain to the length of the longest per group of files being joined, so if you choose 16 on the slice grid, you will get 16 per file, with each file padded to that length.
  • Holding the Shift key while clicking the joined buttons will add the chain files to the top of the samples list instead of outputting inside a zip file.
  • Use the per sample edit panel; to make basic edits to the samples in the list, normalize, trim silence from the end, reverse, half the playback speed, or double the playback speed – all sample edit operations are destructive! If you want to keep the original audio intact, create a duplicate with the sample duplicate icon.
  • Use the per sample slice tool to split files into slices, use the even grid options or the transient detection.
  • If you drop a .ot file in along with a sample, the slice grid will read this to slice up files prepared in the Octatrack AED, so you quickly convert Octatrack sample chains for use on the Digitakt.
  • Split loops into slices, then sort by slice# to quickly create “megabreak” sample chains.
  • Use the 120 slices grid option to create chains perfect for the Model:Samples or Analog Rytm.
  • Get off-grid by Ctrl+Clicking on the slice grid values to set your own numbers.
  • Shift+G to enter the grid view – good for those who don’t like tables (same key combo to toggle back to the list).
  • Drop URL links to .wav files to be fetched directly to the list (only works with sites that are open to Cross Origin Resource sharing – a great example is https://citizen-dj.labs.loc.gov/ ).
  • Works offline and can be installed as a desktop/mobile app on most operating systems from the browser (install as app / add to home screen).
  • All processing is done on your device, and no data is sent anywhere – open source on GitHub under the GPLv3 license.
Read More »

JavaScript frameworks and the pace of change

Being a front-end software/web/app developer, in 2015, is awesome; we have evergreen browsers from all the major providers, the amount of browser specific hacks we need to use are the fewest. So many things have changed so much for the better. JavaScript as a language is going from strength to strength with the adoption of ES6 and fantastic tools such as babel that let ES5 browsers join the party.

But the rise of JavaScript has felt like a double edged sword of late, and I’m often left feeling like Neo in the Armoury.

Tank: What do you need? Neo: npm_modules…
lots of npm_modules.

Read More »

Looking Back Over a Year with MUMPS

It’s been just over a year working in the NHS, and it has been a very interesting experience where I have had the pleasure to work on some really great new systems using all the modern web has to offer, but have also had to work with and improve/maintain some not so enjoyable legacy systems, one of those being a proprietary stack (InterSystems Caché) built atop the MUMPS language and database.

For those that have not been fortunate to have experienced this environment, here is a very short explanation – MUMPS (or simply M), is a programming language providing ACID transaction processing and is tightly coupled to a NoSQL ‘schema-less’ database Read More »

JavaScript Resources

There has never been a better time to pick up JavaScript as a first or an additional language, it is quickly becoming the language of the modern web. The current standard (ECMAScript 5) is a relatively small language compared to Java and PHP, and shares their C style syntax, but this is pretty much where the similarities end, as JavaScript is more akin to Lisp in operation.

With the launch of ECMAScript 6 Harmony right around the corner, which brings many conveniences from other languages and transpiled languages such as CoffeeScript – JavaScript is set to get a whole lot more interesting and possibly a little more difficult to understand, so getting a thorough grasp of the current standard before heading into the new stuff is a great way to go.

Fortunately, there have been some fantastic resources become available over the past few years.Read More »

Making the New Twitter Profile Slightly More Bearable

The new Twitter profile screens are pretty awful, the design itself I can live with, but the silly varying font size is awful!

To put all the fonts back to 14px in size, paste this into the developer console:

$('head').append('<style>.ProfileTweet-text{font-size: 14px !important; line-height: 1.6em !important;}</style>');

This will stick until a page refresh, twitter will sometimes do this, so its not a permanent fix, but hopefully, Twitter will sort this UI out – there are so many complaints around already!

If you are using Chrome, you can add a bookmark to do this at the click of the toolbar – create a new bookmark in Chrome from the bookmark manager (Ctrl+Shift+O) -> Organize -> Add Page, with the title “Smaller Twitter Profile Fonts” and the url as:

javascript: $('head').append('<style>.ProfileTweet-text{font-size: 14px !important; line-height: 1.6em !important;}</style>');

This will make the fonts for your tweets all the same font-size.

Removing Twitter Promoted Items

Create a new bookmark in Chrome from the bookmark manager->add page, with the title “Kill Twitter Promoted” and the url as:
[js gutter=”false”]
javascript:$(‘[class*=promoted], [data-promoted]’).remove();
When you click on this bookmark while on the twitter website, the promoted items should be removed from view 🙂

JavaScript Graham’s Scan Convex Hull Algorithm

While working with a significant amount of medical and sales data that needed to be overlaid on a map, I found myself needing to draw regions that contained sales rep positions – but wanted a nice outer hull to be drawn so that reps inside the area did not need to be joined up as google maps was doing when just feeding in the sorted co-ordinates.

After much internet scouring, I just couldn’t find a JavaScript implementation that I was after (or something that did not come with a complete mapping toolkit!), so I started looking at various implementations in other languages (seemed to be mainly C or Java). Once I had found a good explanation of the article and had (hopefully) grasped the math required via Wikipedia – I set off on creating the algorithm in JavaScript.

The resulting code is quite readable, as I am by no means a mathematician, and fairly well commented with unit testing via QUnit to test my logic is spitting out the expected paths.

Usage is quite simple

//Create a new instance.
var convexHull = new ConvexHullGrahamScan();

//add points (needs to be done for each point,
//a foreach loop on the input array can be used.)
convexHull.addPoint(x, y);

//getHull() returns the array of points that
//make up the convex hull.
var hullPoints = convexHull.getHull();

Head on over to the project page on Github, or have a read through the projects GitHub Pages site to see some live examples.

I have applied a couple of bug fixes thanks to some feedback on GitHub, its great to see code originally just written for yourself, being used by others 🙂

ExtJS 4.x form field Quicktips with required asterisk on field labels

The below gist will add Ext quicktips to all child elements of a form/component that have a fieldLabel and qtip property set.

If the allowBlank property is set to false, the fieldLabel will get a red asterisk ( * ) before the label text and the text required appended to the end of the quicktip hover element.

/*Call this method after the form has rendered, so either on the afterrender event, or from within a
method bound to that or a similar event that is fired after the form/component has rendered.
Pass the name/id of the form in a way that can be accessed using an ext component query.
In your view/form items array, for each element that you want to have a quicktip, set the property
qtip: 'your tooltip text here.'
If you want the required asterisk and text, set the property allowBlank: false
{ name: 'dateArrived', xtype: 'datefield', fieldLabel: 'Date Arrived', qtip: 'Date customer arrived.', allowBlank: false }
* Loops through all child elements of the passed component (form) and checks for and applies
* any tooltips found with the QuickTipManager.
* @param formName – the name of the component(form) to look for qtip properties.
setupQuickTips: function(formName){
Ext.Array.forEach(Ext.ComponentQuery.query(formName + ' *'), function(el){
if (el.qtip){
if (el.fieldLabel && el.allowBlank == false) el.setFieldLabel('<a class="required-ast">*</a>' + el.getFieldLabel());
if (el.allowBlank == false) el.qtip += '<a class="required">&nbsp;&nbsp;required</a>';
target: el.id,
text: el.qtip
/*CSS Styles used by the quicktip required anchors.*/
.required {
fontsize: 10px;
color: #d10000 !important;
lineheight: 14px;
.requiredast {
fontsize: 10px;
color: #d10000 !important;
position: absolute;
margintop: 3px;
marginleft: 7px;

The styles at the bottom of the gist will need to be added to an active stylesheet.