My fascination with linguistics stems from growing up with three languages and the creative urge to experiment with language. This naturally led me to explore the relationship between music and language. Singing has been a part of my life since childhood and adolescence, and recently, I have rekindled my passion for it in a more serious way.
Wanting to take this exploration further, I began researching existing practices that integrate words—or even just syllables—into structured musical frameworks. In Western music, we recognize this through solfège (do-re-mi-fa-so-la-ti-do). Similarly, in jazz, scat singing allows vocalists to use nonsensical syllables to mimic instruments and improvise melodies freely.
This project draws inspiration from South Asian musical traditions, particularly the rhythmic intricacies of Carnatic music and its concept of rhythmic speech, such as Konnakol. Given my Southeast Asian heritage, I feel naturally drawn to what is often referred to as “non-Western” musical traditions. Unlike jazz scat singing, which is more melodic and fluid, Konnakol is highly structured, following precise tala (rhythmic cycles). My goal is to recreate and experiment with these rhythmic patterns using a coding language, thus a very mathematical approach, translating these ancient vocal traditions into a digital framework.
Concept:
The core of this project is the development of a system where written text is transformed into a musical composition. Each letter of the alphabet is assigned a musical note, and punctuation marks are treated as different kind of rests, allowing the text to be translated into a full musical piece. Drawing from the Carnatic tradition’s emphasis on rhythmic speaking and the South Asian focus on the relationship between sound and language, this system bridges the gap between exact linguistic expression and exact musical notation. It could be used in installations, where users are asked to type in individual words or whole sentences into the program and are then provided a musical output. A conversational approach could be used as well, where two people hold a conversation through text which is translated into music.
Technical Approach:
To bring this concept to life, I used Python to create a program that:
- Assigns musical notes to each letter in the alphabet (using a starting pitch of C4). Optionally, note duration can be assigned too.
- Transforms punctuation marks into different lengths of musical rests.
The output is a MIDI file, which can be played back or further manipulated in a digital audio workstation (DAW), and if opened on a notation program provides a lead sheet for musicians.
Code:
from midiutil import MIDIFile
def assign_notes_to_alphabet():
"""Assigns each letter of the alphabet a musical note"""
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
octave = 4
note_mapping = {}
note_index = 0
for letter in alphabet:
note_mapping[letter] = f"{notes[note_index]}{octave}"
note_index += 1
if note_index == len(notes):
note_index = 0
octave += 1
return note_mapping
def convert_note_to_midi(note):
"""Converts a note into a MIDI note number."""
pitch_class, octave = note[:-1], int(note[-1])
midi_note_number = {
"C": 0, "C#": 1, "D": 2, "D#": 3, "E": 4, "F": 5,
"F#": 6, "G": 7, "G#": 8, "A": 9, "A#": 10, "B": 11
}[pitch_class] + (octave + 1) * 12
return midi_note_number
def text_to_midi(text, output_file="output.mid"):
"""Converts text into a MIDI file where each note has a unique duration."""
# Assign notes to letters
note_mapping = assign_notes_to_alphabet()
# Define unique lengths for each note, can be varied
note_length_mapping = {
"C": 0.25, # Quarter note
"C#": 0.5, # Half note
"D": 0.75, # Dotted quarter note
"D#": 1, # Whole note
"E": 0.125, # Eighth note
"F": 0.25,
"F#": 0.5,
"G": 0.75,
"G#": 1,
"A": 0.125,
"A#": 0.25,
"B": 0.5
}
# Define rest lengths for punctuation and spaces
punctuation_rest_mapping = {
".": 1, # Whole rest
",": 0.5, # Half rest
"!": 0.25, # Quarter rest
"?": 0.125,# Eighth rest
" ": 0.25 # Quarter rest for spaces
}
# Create MIDI file
midi = MIDIFile(1) # One track
track = 0
channel = 0
time = 0 # Start time
volume = 100
tempo = 120
midi.addTempo(track, time, tempo) # Set tempo
for char in text.upper():
if char in note_mapping:
note = note_mapping[char]
pitch_class = note[:-1] # Extract note name without octave
midi_note = convert_note_to_midi(note)
note_length = note_length_mapping[pitch_class] # Get pre-defined length
midi.addNote(track, channel, midi_note, time, note_length, volume)
time += note_length # Advance time by this note's length
elif char in punctuation_rest_mapping:
time += punctuation_rest_mapping[char] # Advance time for rests
# Write the MIDI file
with open(output_file, "wb") as f:
midi.writeFile(f)
print(f"MIDI file saved as {output_file}!")
# Example text
input_text = "ra ta ra ta rata, rata, ratatatata! ua, ua, ua, uuaa, ua ua ua ua, uauauauaua! sehe, sehe, sehe, sehe!!! leilala leilala leilala lei. ho-ho, ho-ho, ho-ho, hooo? ra ta ta ra tata ratatata"
text_to_midi(input_text, "text_to_music_varied_lengths.mid")
Generated lead sheet (with Dorico)
Audio (Midi)
Example with an original poem:
Calypso
Swimming headlessly in the streams
Underneath a pool of night
Pearls and shells reflecting light beams
Radiating white
Siren voices echoing
Guiding through the turbulent tides
Her longing for the surface grows
Numbed by the cold she glides
With the dolphins who arose
From a kingdom
Neptun’s knights
His face already long forgotten
Still lingers on her mind
Her body remembers
When he had forsaken
her to return back to his kind
‘Release me from my pain
Oh, mother of seas
Aphrodite, oh, lover
I’m over feeling shades of blue
Alleviate the one to suffer’
The seagulls laughing mockingly
As her body stranded on the shore
Drowned in the sun
Her skin laced with blisters
Her body forgot
What it was longing for
Generated lead sheet (with Dorico)
Audio (Midi)