|Update 29 November 2021: Updated sonifications of the locality-preserving properties of several traversals in up to seven-dimensional Euclidean space, and in eight-dimensional permutation space.|
|Update 17 November 2021: Added new sonifications of the locality-preserving properties of several traversals in up to seven-dimensional Euclidean space, and in eight-dimensional permutation space.|
|Update 12 March 2018: Added more sonifications of the locality-preserving properties of several traversals in up to seven dimensions, with a detailed explanation of how the traversals are mapped to sound.|
|Update 18 February 2018: New tracks through turning-function/direction mapping: hear the Peano curve's gentle rocking motion on multiple levels, and hear the interesting metre of the Meander curve.|
|Update 3 February 2018: Added a track based on the lowest three voices of the Hilbert curve through turning-function mapping with centre point sampling, highlighting the harmonies.|
|Update 20 December 2017: Added sound tracks of four-, five-, and six-dimensional Harmonious Hilbert curves.|
I am exploring approaches to make sonifications or music of space-filling curves. My initial approach and possible implications are described in:
I have also developed a second approach. sonifying the locality-preserving properties of curves, which results in much more orchestral sound tracks. For the sound tracks and some basic background on the second approach, click here; more to follow.
This web page contains a number of sound tracks of space-filling curves related to my first approach. They are provided here as examples, interesting examples, but not necessarily good and well-polished examples. The examples use various techniques, resulting in musical styles that vary from kind-of-classical to minimalist. People visiting this web page seem to have different opinions on which tracks are their favourites. Regardless of your musical taste, I recommend you first check out the following tracks, just to get accustomed to the main idea of what is going on here:
| Technical issues with play-back:
* When using Internet Explorer, instead of audio files you might see error messages “Invalid source”. Workaround: right-click on the player and select “Copy audio URL”, then paste the url into the address bar. Or use another browser.
* I recommend using good speakers/headphones. On mediocre laptop speakers/headphones, you might miss the lower tones.
In addition to the above, the following material is available:
More experimental examples of sonifications through location mapping can be found on a separate page.
The sound track plays the above sketch vertex by vertex, at a leisurely pace of 75 beats per minute, so it is quite possible to follow the curve every step of the way while listening. The sound track is a “prototype” in which supporting voices gradually join in with the primary voices playing the curve (dynamics and articulation are rudimentary). The vertices that are marked in the figure (at 1/4, 2/4, and 3/4 of the length) are also marked musically. For first hearing, take the track without intro, then you know when the curve starts.
|left up||voice 1 moves one step down|
|right down||voice 1 moves one step up|
|left down||voice 2 moves one step down|
|right up||voice 2 moves one step up|
If you would like to know what it sounds like without supporting voices, here is the “raw” sound track:
The following sample plays the Meander curve in a quite different style, and a lot faster. In this track, all notes stem from the space-filling curve, but in different ways. There are three pairs of voices: a melodic pair, a rhythmic pair, and a “coarser” pair. The melodic pair plays the 27 x 27 grid of 729 notes, similar to the track described above, but now in reverse direction, and with different scales. The rhythmic pair has the same pitches as the melodic pair, but staccato, with dynamics controlled by the curve as well: the beats are stronger in the four corner subsquares out of the nine subsquares of any square (and recursively so). The coarse pair plays the curve at a slower sampling rate: effectively each group of 9 beats is merged into one chord with the pitch values of the 9th beat. The rhythmic pair of voices plays throughout the whole track; each melodic voice plays through most of the track but is sometimes replaced by the corresponding coarser voice.
|1||C2 E2 F2 G2 A♭2 B♭(!)2 C3 E3 F3 G3 A♭3 B3 C4 D♭4 E4 F4 G4 A♭4 B4 C5 D♭5 E5 F5 G5 A♭5 B5 C6|
|2||C3 D♭3 E3 F3 G3 A♭3 B3 C4 D(!)4 E4 F4 G4 A♭4 B4 C5 D♭5 E5 F5 F♯5 G5 A♭5 B5 C6 D♭6 E6 F6 G6|
|A curve that reminds me of a world map (126 vertices in 30 seconds)|
|version 1 (shown)||version 2|
|raw sound track|
This curve was also described by Ventrella. The figure also shows the generator (in grey), and the pitch mapping for version 1. One clearly hears the strict syncopic structure of the counterpoint, caused by the fact that horizontal and vertical segments in the sketch of the curve alternate. The curve is played quite fast, but it is possible to follow what is happening if one focuses on one voice at a time. The vertical axis (horizontal segments) plays the bass, the horizontal axis (vertical segments) the top voice.
Version 2 plays the curve in the opposite direction, and with a different mapping (in which the horizontal keyboard is also reflected, so the track starts at the right end with the top voice medium high and the bass low, and ends at the left end with the top voice high and the bass low again.
Below are two renderings of Butz's five-dimensional Hilbert curve, sampled on a 4x4x4x4x4 grid. This is simply “raw” material, except for the addition of a gradual crescendo and decrescendo, no additional voices. The sound track covers the 1024 grid points along the curve in 3.5 minutes. The first version sounds fairly gentle, the second is more adventurous.
In both versions, we can hear several characteristic properties of the curve. Here I will highlight only some of these. The curve fills 32 subcubes of a five-dimensional cube one by one. This results in 32 musical “blocks” of about 6 seconds each. These differ in how they are rotated in five-dimensional space: we can hear this in the music because the rotation determines which voice has which rhythm. In fact, only five different rotations are used. The first and the last block share the same rotation, and all other blocks appear in pairs that have one of the four remaining rotations. As a result, we effectively hear a short first block (6 seconds), 15 long blocks (about 13 seconds each), and a short final block. Every odd long block has the same rotation. These blocks alternate with the other 7 long blocks, which use the remaining three rotations: one of these is used four times, one is used two times, and one is used only once (in the central block), clearly marking the middle of the sound track.
|voice 1||voice 2||voice 3||voice 4||voice 5||sound track|
As described in my paper, there are theoretical considerations that suggest that three- and four-dimensional space-filling curves might have the greatest musical potential. Below is a first experiment in four dimensions: the “squared Hilbert curve” as described in my manuscript on higher-dimensional curves. Technically, it is obtained from the two-dimensional Hilbert curve as follows: consider the Hilbert curve as a mapping h from the unit interval to the unit square; now convert each two-dimensional point h(t) to a point with four coordinates by applying h to each coordinate of h(t). Thus we obtain a mapping from the unit interval to a four-dimensional cube, which turns out to have an interesting rhythm.
The sound track plays the 4096 points of a 8x8x8x8 grid in 14 minutes, simply the “raw” material, except for the automatic addition of dynamics. The dynamics are governed by the curve as follows: the music is softer when visiting points that are close to the starting point (by L1-distance in four-dimensional space), and louder when visiting points close to the second-last corner of the four-dimensional cube that is visited by the curve.
|1||A1 B1 C♯2 D2 E2 F♯2 G♯2 A2|
|2||C♯3 E3 F♯3 G♯3 A3 B3 C♯4 E4|
|3||E4 F♯4 G♯4 A4 B4 C♯5 E5 F♯5|
|4||G♯4 A4 B4 C♯5 E5 F♯5 G♯5 A5|
More experimental examples of sonifications through location mapping can be found on a separate page.
The composer Tom Johnson wrote music based on the Heighway dragon curve, by encoding the left and right turns of a sketch of the curve as follows: at a left turn, move up in pitch; at a right turn, move down in pitch. This turns a traversal of the curve into a sound track that does not give the listener a sense of location the plane, but instead gives a sense of how much the curve spirals in and out while filling the plane. Because the sketch only defines one voice, it is relatively easy to overlay sketches of different refinement levels. (Johnson appears to do this in Formulas for String Quartet, part 7.) Below I apply such techniques to the Hilbert curve.
We sketch the path of the Hilbert curve through a grid of 4k squares by drawing, in each square, a line segment from the point where the space-filling curve enters the square to the centre of the square, and from the centre of the square to the point where the space-filling curve leaves the square. In the sound track I overlay sketches for k = 1, 2, 3, 4, 5, played by five voices centred around G1, G2, G3, G4 and G5 respectively.
Only the first half of the curve is rendered. The coarser, and therefore shorter, sketches (k < 5) are spaced out with rests to remain synchronized with the most detailed sketch (k = 5). The sketches for k = 4 and k = 5 are truncated at the beginning and the end of the track, starting later and ending earlier than the other sketches. Phrasing is achieved by voices swapping sketches in a regular pattern, and by a regular progression of soft chords in the background (these are the only notes not determined by the space-filling curve). Dynamics are determined by location in the plane, getting louder when moving in the direction of the point half-way the rendered section of the curve, and softer when moving away from it.
Below I start from a sketch of the Hilbert curve through a grid of 4k squares in the style of Hilbert himself: the sketch connects the centres of the squares in order. In his book Self-Similar Melodies, Johnson also proposes to use this style, and gives the melody (in abstract form, without a concrete scale) for k = 3. In my sound track I overlay sketches for k = 2, 3, 4, 5, 6, played by five voices centred on D2, A(!)3, D4, D5 and D6 respectively.
The top three voices use a pentatonic scale with D, E, F♯, A and B; the fourth voice uses a pentatonic scale with G, A, B, D, and E; the fifth (bottom) voice additionally includes C2 in the scale. The coarser sketches (k < 6) are stretched so that they synchronize with the most detailed sketch (k = 6). The sketch for k=6 is rendered at 7.5 notes per second, the sketch for k=2 has notes of more than half a minute. In the beginning of the sound track, the five voices enter one by one: this is because each sketch starts with an edge from the first square to the second, and it is only after half a minute that we reach the second square of the 16 squares represented in the coarsest sketch. The final chord represents a line segment that would connect the whole unit square to another square to the right of it.
Loudness is determined by distance (according to the L∞-metric) to the end point. Changes in relative volume of the voices and instrumentation (decaying versus sustained notes) are used to emphasize or suppress sketches for certain values of k in certain sections of the sound track. The melodic “climax” is reached after approximately 7.5 minutes, when the finest sketch completes a 540 degrees' turn to the right, taking it up to E7; a few seconds after that, the coarsest sketch completes it 180 degrees' turn to the right to enter the 14th of square of 16. In some sections in the last two squares, some voices are amplified by high or low “bells”. In the final square, voices swap sketches among them, ultimately moving the finest and fastest sketch down to the bass voice, to obtain a satisfactory closing.
All notes in the sound track linked above are space-filling curve notes; no hand-composed notes have been added. To get a pleasant sequence of harmonies, all I did is choosing the different scales for the different voices carefully.
The track below plays the basic chords of the previous track as they emerge from the lowest three voices (that is, the sketches for k = 2, 3, 4), but a lot faster, and without the higher levels of refinement. Loudness is determined by distance to the centre of the third quadrant. I could not resist adding a supporting voice between the lowest voice and the middle voice in the last quarter of the track, and a rallentando in the last 1/16th part:
The track below plays the Peano curve, sampled at the centre points of the squares in the first four levels of refinement (94=6561 points). The pitch mapping is as follows (pitches representing the initial/final direction in bold): first level C2 F2 B♭2; second level C3 E3 G3 B♭3 C4 D4 F4; third level G3 B♭3 C4 D4 E4 F4 G4 A4 B♭4 C5 D5; fourth level C4 D4 E4 F4 G4 B♭4 C5 C♯5 D5 E5 F5 G5 A5 B♭5 C6. Volume decreases with L∞-distance to the corner that is reached at 3/4 of the track. As usual, consecutive notes at the same pitch are merged into one. No further tricks. Hear the curve rock or meander its way on multiple levels to the centre of the square, turning inwards by 720 degrees and up to C6, and then on to the corner at three quarters, after which the track finishes gently with a decrescendo repetition of the beginning.
The Meander curve, sampled at the centre points of the squares in the first three levels of refinement, gives a nice melody with an interesting metre. Pitch mapping: first level B1 D2 E2 G2; second level C♯3 D3 E3 F♯3 G3 A3 B3 C(!)4; third level F♯4 G4 A4 B4 C♯5 D5 E5 F♯5 G5 A5 B5 C(!)6.
For d = 1 up to 6, the following sound track plays, one after another, a sketch of how a d-dimensional Harmonious Hilbert curve (as described here) traverses a grid of 4d subcubes. The track uses six different pitch classes (A, G, F, E, D, C) that correspond to steps in the 1st, 2nd, 3rd, 4th, 5th and 6th dimension, respectively (whether the step goes up or down in that dimension is not encoded). On top of that, there are 2d−1 voices that each sketch one of the 2d−1 facets of the d-dimensional cube that are each traversed in the order of the (d−1)-dimensional Harmonious Hilbert curve. In these sketches, more emphasis is given (by means of slower decay of the sound burst) to each 2nd, each 4th, each 8th, each 16th step etc. The sketches for the facets are aligned with the sketch of the d-dimensional curve, that is, the “steps” of the sketch of each (d−1)-dimensional curve are played when the d-dimensional curve makes the corresponding steps. Thus, the entire sound track is unisono, but the voices for the 2d−1 facets sound in different registers (the axis of the outward normal determines the octave, and the sign of the outward normal determines the timbre).
Note that in the six-dimensional section, the sketches for the facets play 11 times 1023 notes, while the six-dimensional sketch is only 4095 notes. Thus, on average, each note is hit by almost three facet voices. It is mostly the variations in how many (and which) facet voices are playing that create the dynamics of the sound track (there are no hand-composed notes or dynamics on this track!). One may listen to the salient features of the unexpectedly rich sound track and think about how those features arise from the structure of the curve and the six-dimensional cube—or one can just listen to the “music”.
Below is a track with an alternative pitch set (C, D, E♭, F♯, G), playing the Harmonious Hilbert curves up to five dimensions:
The following track plays the curve up to four dimensions (on C, B, A, G), but at a higher resolution (8 × 8 × 8 × 8), resulting in a track that is less dense: there are 7 facet voices of 511 notes each on a track of 4095 notes, so there is lots of “quiet time” in which one hears only the four-dimensional curve.
One of the most useful properties of space-filling curves in computer science is that they tend to preserve locality: points that are close to each other along the curve are (usually) close to each other in d-dimensional space, and vice versa. Below is an attempt to sonify the variations in locality-preserving qualities along the curves. Each track traverses the curve from beginning to end. At any point in time we are at some point along the curve, and we play low sounds for other points that are nearby in space but far ahead along the curve. At the same time, we play high sounds for other points that are nearby in space but far back along the curve. The further back, the higher, and the further ahead, the lower. The volume of these sounds is determined by the ratio of distance along the curve and the d-th power of the distance in d-dimensional space: the greater this ratio, the louder the sound. The result is a sound track that represents, in a way, how the space-filling curve bounces against itself to fill the space.
For clarity, we start with two examples in two dimensions, that may not sound very nice but they form an interesting contrast. In the first track, sonifying the Z-order traversal, one hears pairs of pulses of almost constant pitch, while the second track, sonifying the Hilbert curve, exhibits many glissandi (continuously rising tones). This contrast can be traced back directly to the distinct properties of these traversals: unlike the Z-order traversal, the Hilbert curve is palindromic. This means that as one travels along the boundary of one of the squares in the subdivision of the plane that underlies the curve, the signed distance along the curve to the neighbouring point on the other side of that boundary always decreases. This results in almost-continuously rising tones for the Hilbert curve, whereas the Z-order traversal generates pulses of almost constant pitch.
|2D Hilbert curve|
Below, there are some more examples that sound more musical.
|7D Z-order traversal|
|4D Peano curve|
|3D Z-order traversal|
|3D Meurthe curve|
For details about the mapping from curve to sound and for some more examples, see the dedicated page on proximity mapping.