Naledi

November 02, 2023

Live Demo

Click Here

Running as a live installation at the Fair Isle Brewing taproom Nov 2, 2023 onward for a limited period of time.

Concept

This marks the second year of my collaboration with Fair Isle Brewing for the special release of Naledi beer.

In this project, I endeavored to capture the dynamic and unpredictable nature of the fermentation process. Naledi uses Syrah and Mourvèdre grapes with a touch of Lilac flowers. As a wine enthusiast, I chose to use the “terroir” data of the grapes to inform the label artwork. I converted the July 2022 temperature and wind data from Yakima, where the grapes were grown, into MIDI clips. The daily average temperature determined the pitch of the MIDI notes. These notes were then played with a synthesized sound, and a visualization was created to dynamically draw lines corresponding to the music’s amplitude. This visualization became the label art.

For the live installation, we made the visualization interactive. In the absence of nearby people, the graph continues to evolve with the music. However, when a camera detects someone’s pose or a hand gesture in the taproom, it modifies the drawing in response. Patrons, therefore, become part of the interactive experience merely by their presence and engagement.

Read more about last year’s collaboration, Ardi, here.

For those interested in the technical aspects, read on.

Data to Music

In this piece, I aimed to experiment with music generation and visualization from a data source.

I utilized AbletonOSC to convert the daily average temperature data into MIDI notes for synthetic music. Each day’s temperature was rounded to the nearest integer and transposed down by a constant of 10 to set the note’s pitch. The day’s wind speed determined the MIDI note’s velocity. Each note lasted for eight beats and was spaced four beats apart.

lucy ableton

The source code looks something like:

client.send_message("/live/clip/add/notes", (track_id, clip_id, 65, 0.0, 8, 4.8, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 64, 4.0, 8, 6.4, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 60, 8.0, 8, 9.4, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 56, 12.0, 8, 5.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 56, 16.0, 8, 5.6, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 58, 20.0, 8, 5.0, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 58, 24.0, 8, 3.4, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 62, 28.0, 8, 6.5, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 61, 32.0, 8, 6.9, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 64, 36.0, 8, 4.2, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 65, 40.0, 8, 5.3, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 69, 44.0, 8, 6.2, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 70, 48.0, 8, 7.0, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 67, 52.0, 8, 5.8, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 69, 56.0, 8, 6.4, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 66, 60.0, 8, 6.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 60, 64.0, 8, 8.3, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 60, 68.0, 8, 4.0, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 65, 72.0, 8, 4.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 71, 76.0, 8, 5.8, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 69, 80.0, 8, 6.8, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 68, 84.0, 8, 9.2, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 66, 88.0, 8, 4.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 70, 92.0, 8, 6.0, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 71, 96.0, 8, 5.5, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 74, 100.0, 8, 5.8, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 78, 104.0, 8, 5.0, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 78, 108.0, 8, 5.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 79, 112.0, 8, 7.6, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 77, 116.0, 8, 4.7, 0))
client.send_message("/live/clip/add/notes", (track_id, clip_id, 76, 120.0, 8, 5.1, 0))

I picked the Drifting Ambient pack to give the sound a mysterious and windy feel.

Music to Visualization

Next, with the music, I used p5.js to visualize the sound.

We went through some iterations and landed at a minimal, mysterious line animation in sync with the volume of the music.

lucy lucy1 lucy2

Older Iterations

Some of my older iterations involved using ChatGPT to write poems about grapes and Lilac flowers, and display random words drawn from these poems alongside a circular visualization.

lucy old lucy old 1 lucy old 2