Kofi / Illestpreacha
Code is Poetry & Data is Poetry

Follow

Code is Poetry & Data is Poetry

Follow
Genuary2023_Learning

Genuary2023_Learning

HammingSonification

Kofi / Illestpreacha's photo
Kofi / Illestpreacha
·Jan 14, 2023·

4 min read

The prompt for Genuary 2023 Day 13 is

Do something You want to Learn

  • I decided to include a modified Hamming Distance Algorithm within my code. Since I tend to merge poetry/writing in my code, an algorithm that measures the edit distance(differences between two strings) is something I am interested in embedding. This will be done with the aid of SonicPi and LiveCodeLab

  • Hamming Distance: "Hamming distance is a metric for comparing two binary data strings. While comparing two binary strings of equal length, Hamming distance is the number of bit positions in which the two bits are different.

    The Hamming distance between two strings, a and b is denoted as d(a,b).

    It is used for error detection or error correction when data is transmitted over computer networks. It is also using in coding theory for comparing equal length data words." - https://www.tutorialspoint.com/what-is-hamming-distance

  • I called this a modified version since it can work when the strings aren't equalled

  • Using the hamming distance algorithm within a sonification of two texts coded with python for NanoGenMo and then using it again for three poems, I wrote. Then I overlayed them and that is the sound you hear

  • Also overlayed the same Livecodelab sketch twice with different temporal properities

First Hamming Sonification

#Audio slowed down by 11%

#required elements

require 'uri'
require 'open-uri'

#the url

uri = URI.parse("https://raw.githubusercontent.com/IllestPreacha/NanoGenMo/main/November%2025th/Nov%2025th/Doctor_LostInTranslation.txt")
uri2 = URI.parse("https://raw.githubusercontent.com/IllestPreacha/NanoGenMo/main/November%2024th/Output/AlreadyKnown_LostInTranslation.txt")

puts uri
puts uri2

#gsub replaces a substring, in this case the left over "r"
poetry1 = uri.read.gsub("\r","") #reads the file
poetry2 = uri2.read.gsub("\r","") #reads the file

#splits the above file into lines
Wordy = poetry1.split("\n")
Wordy2 = poetry2.split("\n")

#functions of hamming_distance
def hamming_distance(str1, str2)
  distance = 0
  str1.each_char.with_index do |char, i|
    distance += 1 if char != str2[i]
  end
  distance
end

def WordThru(looping,text,synthing)

  i = 0

  poem = text.split("\n") #split into lines, not words

  live_loop looping do  #while loop


    use_synth synthing
    play poem[dice(i)].length * 1.25  #string length

    puts poem[dice(i)]
    puts poem[dice(i)].length * 1.25
    puts hamming_distance(Wordy[dice(i)],Wordy2[dice(i)])

    play hamming_distance(Wordy[dice(i)],Wordy2[dice(i)])
    play hamming_distance(Wordy[i],Wordy2[i])


    #checking base on what string it starts of with d
    if poem[i].start_with?("D") or poem[i].start_with?("d","c")
      with_fx :ixi_techno, mix: [0.5,0.25].choose do
        use_synth :dark_ambience
        play [75,50,25,50,14,80].choose
        play hamming_distance(Wordy[dice(i)],Wordy2[dice(i)])
      end
    end

    #decay sound when sentence starts with W
    if poem[dice(i)].start_with?("w", "s","a","d") or poem[i].start_with?("W")
      with_fx :vowel, mix: [0.5,0.25].choose do
        sample :ambi_choir ,beat_stretch: [0.001,1.25].tick, decay: 2
        play hamming_distance(Wordy[dice(i)],Wordy2[dice(i)])
      end
    end

    #decay sound when sentence starts with W
    if poem[i].start_with?("L","b","c","e","g","t")
      with_fx [:whammy,:flanger].choose, mix: [0.5,0.25,0.125].choose do
        sample [:loop_3d_printer,:ambi_choir,:ambi_glass_hum,:ambi_glass_hum].choose, decay: dice(2)
        play hamming_distance(Wordy[dice(i)],Wordy2[dice(i)])
      end
    end

    i += 1 #increment

    if i == poem.length #make the loop nonstop
      i = 0
    end

    sleep [0.25,0.5,1,2].choose

  end
end

WordThru(:ticking,poetry1,:piano)
WordThru(:ticking2,poetry2,:bass_foundation)

Second Hamming Sonification Code

#Slowed down by 67%

poetry1 = "text1"

poem = File.readlines(poetry1) #puts line into arrays
puts poem
puts poetry1.length # flow poem size
puts poem.length #should be array size


poetry2 = "text2"

poem2 = File.readlines(poetry2) #puts line into arrays
puts poem2
puts poetry2.length # flow poem size
puts poem2.length #should be array size

poetry3 = "text3"

poem3 = File.readlines(poetry3) #puts line into arrays
puts poem3
puts poetry3.length # flow poem size
puts poem3.length #should be array size



#functions of hamming_distance
def hamming_distance(str1, str2)
  distance = 0
  str1.each_char.with_index do |char, i|
    distance += 1 if char != str2[i]
  end
  distance
end

def hamming_distance2(str1, str2)
  distance = 0
  str1.each_char.with_index do |char, i|
    distance += 1 if char != str2[i]
  end
  distance
end

i = 0

live_loop :ticking do  #while loop


  poetry1 = "txt"

  poem = File.readlines(poetry1) #puts line into arrays
  puts poem
  puts poetry1.length # flow poem size
  puts poem.length #should be array size


  use_synth :bass_foundation
  play poem[i].length * 1.25  #string length

  use_synth :dark_ambience
  play poem[dice(i)].length * 1.3 #random integer length

  i += 1

  if i == poem.length #make the loop nonstop
    i = 0
  end

  sleep [0.5,1,2].choose
end

x = 0

live_loop :ticking2 do  #while loop


  with_fx :distortion, distort: [0.74,0.31,0.1,0.001].choose, mix: rrand(0.1,0.8) do
    play hamming_distance(poem[x],poem2[x]) * 4

    play (hamming_distance2(poem[x],poem2[x]) - hamming_distance(poem[x],poem3[x])).abs * 4 + 1
    play (hamming_distance(poem[x],poem2[x]) + hamming_distance2(poem[x],poem3[x])) * 4

    play hamming_distance(poem[x],poem3[x]) * 4
    play (hamming_distance(poem[x],poem2[x]) * hamming_distance2(poem[x],poem3[x])) / 6 + 1

  end


  puts hamming_distance(poem[x],poem3[x])


  x += 1

  #setting the conditionals for when the poems arent the same length in lines
  if poem.length > poem2.length and poem.length > poem3.length
    if poem2.length < poem3.length
      x = poem2.length
      if x == poem2.length
        x = 0
      end
    else
      x = poem3.length
      if x == poem3.length
        x = 0
      end
    end
  end

  if poem.length < poem2.length and poem.length > poem3.length
    x = poem3.length
    if x == poem3.length
      x = 0
    end
  end

  if x == poem.length #make the loop nonstop
    x = 0
  end

  sleep [0.5,1,2].choose
end

LivecodeLab Code

if time % 15 > 8
    animationStyle motionBlur
    scale wave(0.3)
    simpleGradient salmon, blanchedalmond, hotpink

if time % 15 < 8
    animationStyle paintOver
    scale wave(0.3)/sin(time)
    simpleGradient forestgreen,white,teal

15 times
    move 0, time % 3 + 1, 2.5
    5 times
        rotate time / 3, time / 4, time /3
        move 0.7, 0.1, 0.2
        rect 1, sin(3), sin(2)
        box wave(0.5),sin(0.3),cos(0.5)
        ball wave(0.003),tan(0.1)
 
Share this