Sorting Algorithm Visualization & Sonification Plugin for Max for Live

Soni.f(y, sorts): a Max for Live device that turns each step of a sorting algorithm into a MIDI note, playable as a Live instrument.


I built Soni.f(y, sorts) — a Max for Live device that converts the operations of sorting algorithms into MIDI note sequences, making them playable as an instrument inside Ableton Live.

https://github.com/atsukoba/sonify-sorts

Sorting Algorithm Visualizations

Visualizing and sonifying sorting algorithms is a popular way to build intuition about algorithmic behavior. Countless developers and educators have produced videos and interactive demos on this theme.

Here are some well-known examples:

15 Sorting Algorithms in 6 Minutes (Timo Bingmann, 2013)

Each comparison and swap is mapped to a pitch, creating a distinctive sonic fingerprint for each algorithm. Tens of millions of views.

AlgoRhythmics (Sapientia University)

Sorting algorithms performed as folk dances — a wonderfully embodied take on algorithmic structure. (https://www.youtube.com/user/AlgoRhythmics)

sorting.at (Carlo Zapponi)

An interactive browser-based visualization of many sorting algorithms.

https://sorting.at/

VisuAlgo (National University of Singapore)

Step-by-step animated explanations of sorting and other algorithms.
https://visualgo.net/en/sorting

https://visualgo.net/en/sorting

These are all great as standalone visualizations or pre-rendered videos. What they lack is interactivity with a live music production environment. That's the gap Soni.f(y, sorts) aims to fill.

Max/MSP and Max for Live

Max/MSP

Max/MSP is a visual programming environment by Cycling '74, widely used for music, video, and interactive media. Programs are built as patches (.maxpat) by wiring together objects in a dataflow style.

One of Max's strengths is its [js] object, which lets you embed JavaScript directly in a patch for logic-heavy tasks that would be awkward to express visually.

Max for Live (M4L)

Max for Live integrates Max into Ableton Live, allowing you to build custom MIDI effects, audio effects, and instruments that run directly in a Live set and are distributed as .amxd files.

Soni.f(y, sorts)

Soni.f(y, sorts) screenshot

Soni.f(y, sorts) maps each step of a sorting algorithm (comparisons, swaps, insertions) to a MIDI note, which is then routed to any instrument in Ableton Live.

Supported Algorithms

  • Bubble Sort
  • Selection Sort
  • Insertion Sort
  • Quick Sort
  • Merge Sort

How It Works

1[Input sequence (MIDI note numbers)]
23[sort.js — inside Max [js] object]
4  · Runs the full sort, recording every operation in stepHistory[]
56[One step replayed per bang]
7  outlet0 : current sequence state
8  outlet1 : accessed note + adjacent notes → MIDI out
9  outlet2 : index pointer sequence
1011[Ableton Live MIDI instrument]

The patch loads sort.js into a [js] object. When it receives the sort message it pre-computes the entire sort and stores all operations in a history array. Each subsequent bang replays one step from that history, outputting the accessed MIDI notes to Live. When the history is exhausted, outlet 6 fires a bang to signal completion.

JavaScript Implementation (sort.js)

Max's [js] object runs ECMAScript 5-compatible JavaScript (Max JS Object Reference).

The core data structure is stepHistory — an array that records every elementary operation performed during the sort:

1inlets = 2;
2outlets = 7;
3
4var availableAlgorithms = [
5  "bubble",
6  "selection",
7  "insertion",
8  "quick",
9  "merge",
10];
11var selectedAlgorithm = "bubble";
12var stepHistory = Array();
13
14// swap two elements (type 0)
15function swap(array, i, j, saveHistory) {
16  var tmp = array[i];
17  array[i] = array[j];
18  array[j] = tmp;
19  if (saveHistory) stepHistory.push([0, i, j]);
20}
21
22// copy element at j to position i (type 1)
23function insert(array, i, j, saveHistory) {
24  array[i] = array[j];
25  if (saveHistory) stepHistory.push([1, i, j]);
26}
27
28// write a specific value to position i (type 2)
29function insertValue(array, i, value, saveHistory) {
30  array[i] = value;
31  if (saveHistory) stepHistory.push([2, i, value]);
32}

Each sort function (bubbleSort, selection_sort, insertionSort, quickSort, mergeSort) calls these primitives with saveHistory = true, accumulating every atomic operation into stepHistory.

Playback via bang

1function bang() {
2  if (bangCount === 0) playSequence = inputArray.slice(); // reset on first step
3
4  if (bangCount === stepHistory.length) {
5    outlet(6, "bang"); // signal sort complete
6    bangCount = 0;
7    return;
8  }
9
10  var op = stepHistory[bangCount];
11  // re-apply swap / insert / insertValue to playSequence
12  // ...
13
14  // output accessed note and its neighbors as MIDI
15  outlet(1, [
16    playSequence[Math.max(0, idx - 1)],
17    playSequence[idx],
18    playSequence[Math.min(playSequence.length - 1, idx + 1)],
19  ]);
20  outlet(0, playSequence); // current state
21  bangCount++;
22}

Separating the sort computation from its playback means the tempo is fully independent — you can use Ableton Live's transport, a [metro] object, or any other bang source to step through the sort at any speed.

Usage

  1. Drop sonify-sorts.amxd onto a MIDI track in Ableton Live.
  2. Set the input sequence (a list of MIDI note numbers, e.g. a shuffled scale).
  3. Choose an algorithm and press sort to pre-compute the step history.
  4. Press play (or sync to a tempo-driven bang) to step through the sort. Each step outputs MIDI notes.
  5. Route the MIDI output to any Live instrument (synth, sampler, etc.) and listen to the algorithm play itself.

Usage screenshot (placeholder)

Conclusion

Sorting algorithm visualizations are a staple of CS education. Taking that idea one step further and making the algorithm a playable MIDI instrument inside Ableton Live opens up an interesting intersection of music and computation.

Using Max's [js] object keeps the algorithmic logic clean and maintainable in plain JavaScript, without having to express complex sorting logic through visual patching. The behavioral differences between algorithms — the dense, chaotic swap patterns of bubble sort vs. the structured partitioning of quick sort — translate directly into distinct rhythmic and melodic textures.

Links