Text to sound translator

I want to convert text to sound.

I took the 108 basic beeps and assigns them to the 27 words in the English Latin alphabet with intervals of 3. Starting A at 30 and therefor Z is 105. I then made functions for each of the words and now if I want to hear, for example, “Hello World” I write it up like

[h, e, l, l, o]
sleep 0.5
[w, o, r, l, d]

Is there a closer way to writing it without the [ and commas? I would like to write it closer to how we write–this message as an example. Any ideas would be very much appreciated!

1 Like
define :beepit do |s|
  play s.chars.map {|c| c.upcase.ord-"A".ord+30+12 }
end

sss = "hello there Sonic Pi"
sss.split.each { |s| beepit s; sleep 0.5 }

Anyway, you can modify as needed…

1 Like

WOW!!! This is amazing! Thanks for the help. I am new to Sonic Pi and was wondering if you could somehow walk me through it… Is :beepit a predefined function that you are calling? I am not sure of how all the code is structured. Any links to references or definitions can help me out. Thank you so much for your time and help, really appreciate it

Hi @MSJ123

:beepit is not a pre-defined function. In Sonic Pi terms,

define :beepit do
[...]
end

is what defines such a function. It takes 1 argument, which is supposed to be a string like "hello", then it chops it up into an array of characters, converts each one to a number, and passes the resulting array to the built-in function play.

On a separate line, we take a string like "hello there" and split it into words using the built-in split method, and play each one of those using the function we just defined. Note that punctuation has not been taken into account.

Not claiming this is the epitome of computer science; obviously there are more elegant ways to structure this. Sonic Pi actually runs a Ruby interpreter, if you are familiar with that.

If you have any questions, please do not hesitate to ask!

1 Like

Hi @shemp

Thank you so much for explaining it, I have been fidleing around with it for two days and very interesting explorations have come up… I duplicated the function with diferent input to create paragraphs.

At the moment I am figuring out how to change the “instrument”… I see scale is at the end of the play function, but cant seem to change it to sound less harmonious… more synth… eventhough I add synth filters in and out of the :beepit loop. Could you give me some light into this?

Thank you so much for all your time and help!

I did this fun thing some time ago:

workspace = Thread.current.__system_thread_locals.get(:sonic_pi_spider_job_info)[:workspace]
buffer = project_path+workspace+".spi"
text = File.read(buffer)

pitches = {} # For storing pitch / note & duration for each char

pitch_key = :e
pitch_scale = :minor_pentatonic

text.chars.each do |char|
  if !pitches[char]
    pitches[char] = {pitch: rrand_i(1,10), sleep: [0.25,0.5].choose }
  end
  with_fx :ping_pong, feedback: 0.5, phase: 0.25  do
    note = degree pitches[char][:pitch], pitch_key, pitch_scale
    synth :mod_beep, note: note
  end
  sleep pitches[char][:sleep]
end

It plays the code in current buffer as music character by character … but you can of course change text to anything else :slight_smile:

1 Like

Can you explain what you mean by “less harmonious”? Would it be enough to change the synth used, which you can do by inserting a couple of lines, e.g.:

define :beepit do |s|
  play s.chars.map {|c| c.upcase.ord-"A".ord+30+12 }
end

use_synth :piano
use_synth_defaults vel: 0.5, hard: 0.7
sss = "hello there Sonic Pi"
sss += " let us make the string longer"
sss.split.each { |s| beepit s; sleep 0.5 }

Or do you mean to change the scale used from a equally-tempered 12-tone scale to one that maximizes the perceived dissonance? That requires a bit of thought, but for some quick sourness you could change the definition of :beepit to something like

define :beepit do |s|
  play s.chars.map {|c| c.upcase.ord-"A".ord+30+12+rrand(-0.5,0.5) }
end