After I posted my 3D printed record project, I received an interesting comment from Instructables author rimar2000.  He described an idea he's had for a while about a strip of material that has audio information encoded on it so that it can be played back by quickly sliding a fingernail, credit card, or piece of paper along its surface.  This same basic idea has been implemented in various ways already, here are a few:

talking strip birthday card:

It's even possible to tune rumble strips on a road so that your car turns into a musical instrument as it drives over.  Here is a musical road near MT Fuji, Japan:

another musical road - Lancaster, CA:

The reason rimar2000 suggested this idea to me is because I'd already found a way to convert audio signals into a 3D printable model in my record project.  Using 3D printing it is theoretically possible to convert any piece of audio into a "sound strip," allowing anyone to encode customized messages into this physical format.

I recently found some time to put the code together and print out a few test strips, and unfortunately, I think my process needs a little more refining until it is ready for mass production, but I figured I'd post everything I've started here in case anyone else is interested.  The video below shows the closest I've come so far to reproducing my own voice saying "amanda."  If you know what it's supposed to say, you can kind of make out what's going on here, there are three distinct sections where the sound gets louder - corresponding to the three syllables in the word.

I made this on an Objet Connex500 UV cured resin printer at 300 dpi with 30 micron layers.  It's possible that printing at the max resolution (600dpi with 16 micron layers) might help a little bit, but I haven't had a chance to do it.  It's also possible that other materials or dimensions might help.  I was thinking that tilting the bumps on the surface of the strip so that they are pointing in a 45 degree angle instead of straight up might work better with the angle that the card is hitting them.  If you have any other suggestions please feel free to leave them in the comments.

Step 1: The Code

The main idea behind this project is to take an audio waveform and use it to modulate the height of the surface of a linear strip.  this way, any object passing across the surface will vibrate up and down in the hills and valley of the wave, these vibrations will cause vibrations in the air, which cause us to hear sound.  You will find comments in my code that talk about the specifics of how it works, follow these steps to create your own 3d models:

1.  Download Audacity.

2.  Open an audio file of your choice with Audacity.  Use Effect>Normalize to amplify the signal as much as you can without clipping.  Trim any excess blank space off the beginning an end of the clip, you will want to keep the audio as short as possible.  File>Export this file and save it as a WAV in a folder called "soundBites". 

3.  Download Python 2.5.4.

4.  Copy the Python code below and save it in the soundBites folder, this code converts the information stored in a wav file (audio) into a series of numbers inside a text file (txt).
Copy the file name of the audio file you just saved and paste it into the following line in Python:

             fileName = "your_file_name_here.wav"

Hit Run>RunModule, after a minute or two you will have a .txt file saved in the soundBites folder.

5.  Download Processing.

6.  To export STL from Processing, I used the ModelBuilder Library by Marius Watz.  Download the ModelBuilder library here, I used version 0007a03.

7. Unzip the Modelbuilder library .zip and copy the folder inside called "modelbuilder".  Unzip the processing .zip and go to Processing>modes>java>libraries and paste the "modelbuilder" folder in the "libraries" folder.

8.  Copy the processing sketch below and save it as "soundBites.pde" in the soundBites folder.  You can adjust many parameters in this code: the x/y/z resolution of the printer, the speed that you want to playback, the amplitude of the waves, the thickness of the strip, and more... you can even invert the wave to make it recessed within the strip.
9.  Change the name of the import file in the Processing sketch to match your txt file name:

             String filename = "your_file_name_here.txt";

10.  Hit "Run" in Processing, you should see a file appear in the soundBites folder called "your_file_name.stl", you are now ready for 3d printing.
<p>Thanks for your great project</p><p>I try to play with it, but i got trouble with python like following:</p><p>File &quot;sound.py&quot;, line 21, in &lt;module&gt;<br> frameOneChannel[i] = frameInt[4*i+1]*2**8+frameInt[4*i] #separate channels and store one channel in new list<br>IndexError: list index out of range</p><p>python ver 2.5.4</p><p>any one had this issue??</p><p>Thxxx</p>
<p>It means your file is mono, try using an audio program to add the missing channel, so make your audio file stereo, event if its just the same content on each channel. Here is a way of doing that using audacity which is free: </p><p>https://chacadwa.com/foh/mono-to-stereo-in-audacity</p>
<p>Thanks! I hit the same issue.</p>
commercial way?<br>Best regards, and congratulations on your work!<br><br>Giaccomo Fontanot, Industrial Designer.
printing square waves is the way to go. Are you interested in pursuing this goal in a more
Hi amandaghassaei. Your work is impressive. I am an Industrial Designer, very interested on this issue. I am retina to figure a way to replicate the talking strips from evades ago. I Have a CNC router, and a LOT of interest to see this working. I believe
<p>Hi! </p><p>Great work! I made it, I haven't already print it, but I'm going to do it soon. I've a question: how can I increase the wave's amplitude? Thanks in advance!</p>
<p>The sound-strip idea was used at least as far back as 1955 - I remember an advertising novelty from the Schwinn bicycle company. A ridged red plastic ribbon/strip about 1/8 inch wide was tied to the center of a bicycle-wheel shaped disc (as a resonator). Running your fingernail along the strip clearly played &quot;I like Schwinn bikes.&quot; I wonder how this was made - it sure was not computers encoding the speech.</p>
<p>Hello.</p><p>Thank you for this instructables.</p><p>I am trying to print some words on different objects and find some applications for signaletic projects. So I want to get the wave of my sound, but without the thickness of the strip.</p><p>I have followed all your instructions and the .stl is a 15M file for just one word with 483324 triangles written. to big for my CPU.</p><p>Is there a way to just have the curve ?</p><p>I have tried to change the thickness and different parameters but I still have a big block with more 400.000 triangles, not just the desired curve.</p><p>all the best for your different beautifull project and thank you for your works.</p><p>M.</p>
<p>change this function:</p><p>void drawGrooves(float[] audioData){<br><br> int totalSampleNum = audioData.length -1;<br> float xPosition;<br> float zPosition;<br> <br> //draw outer lower edge of groove<br> for (int sampleNum=0;sampleNum&lt;totalSampleNum;sampleNum++){<br> if (sampleNum%rateDivisor == 0){<br> xPosition = speed/samplingRate*sampleNum;//length/sec * sec/samples * sampleNum<br> zPosition = -depth-amplitude+audioData[sampleNum];<br> if (invertGroove){<br> lastEdge.add(xPosition,sideWidth+bevel,-zPosition);<br> } else {<br> lastEdge.add(xPosition,sideWidth+bevel,zPosition);<br> }<br> }<br> } <br> <br> int lastSampleIndex = 0;<br> float finalZPosition = 0;<br> //draw inner lower edge of groove<br> for (int sampleNum=0;sampleNum&lt;totalSampleNum;sampleNum++){<br> if (sampleNum%rateDivisor == 0){<br> xPosition = speed/samplingRate*sampleNum;//length/sec * sec/samples * sampleNum<br> zPosition = -depth-amplitude+audioData[sampleNum];<br> if (invertGroove){<br> currentEdge.add(xPosition,sideWidth+bevel+grooveWidth,-zPosition);<br> finalZPosition = -zPosition;<br> } else {<br> currentEdge.add(xPosition,sideWidth+bevel+grooveWidth,zPosition);<br> finalZPosition = zPosition;<br> }<br> lastSampleIndex = sampleNum;<br> }<br> }<br> <br> connectVertices();<br> <br> print("total length: ");<br> print(speed/samplingRate*totalSampleNum);<br> println(" inches");<br>}<br></p>
Very interesting, maybe the combination of lowest amplitude and something to make resonate and amplify like string or membrane would improve. I <br>If you still didn't found way to get the audiosample value with Processing without the help of the Python script it is very fast easy with the Minim library (already there with the IDE) : <br> <br>import ddf.minim.*; <br> <br>Minim minim; <br>AudioSample sample; <br>float[] audioDataLeft; <br>float[] audioDataRight; <br> <br>void setup() { <br>minim = new Minim(this); <br>sample = minim.loadSample(&quot;yourFilePathHere&quot;); <br>audioDataLeft = sample.getChannel(BufferedAudio.LEFT); <br>audioDataRight = sample.getChannel(BufferedAudio.RIGHT); <br>//etc ... etc ... <br>} <br> <br>etc ... <br> <br>You'll get the audio data as array of float value between -1 and 1, if I remember well.
yeah I messed around with that, but it seems to only give you a small bit of buffered data at a time. I wasn't able to find a way to pull the whole song in. It's possible I just wasn't using it right though
This is a great start. I remember having a balloon with a talking strip attached - the surface of the balloon acted as the &quot;cone&quot; of a speaker, and since the surface was big, the sound was bigger as well - similar to the greeting card example in the first clip where the paper is the transducer changing the mechanical vibrations into airborne sound waves. You may have better luck keeping the substrate of the strip as low-mass (easy to vibrate) as possible, then attach to a passive &quot;amplifier&quot; surface. It was a long time ago, but I think the strip on my balloon was almost like Mylar. I don't see how (with current technology/materials) you could print that fine, but you might be able to make a &quot;negative&quot; that could stamp the pattern into a thinner vibration strip.
Perhaps it's my brain filling in the phonemes between the schwa - short a - schwa pattern, but I'm pretty sure I heard &quot;Amanda&quot; when scraped at 3/4 speed. Not bad for plastic! Certainly better than poor Ranjit Bhatnagar's attempt at a similar &quot;scraper&quot;(http://moonmilk.com/2010/02/08/instrument-a-day-6-wave-scraper/). This makes me wonder though; Perhaps this medium isn't ideal for reproducing the relatively complex waveforms of actual speech (a larynx-produced carrier signal modulated by the mouth), but may prefer sounds that emulate primitive speech synthesis circa 1989 (Square wave carrier clunkily modulated to produce phonemes). Maybe it would be worth a try to print a synthesized vowel cycle (aeiou) modulated from a single carrier of uniform frequency and amplitude (pulse or square perhaps?), even with some simple consonants thrown in (carefully placed noise). I see below that others have suggested how these strips usually work using cleverly placed notches of uniform depth rather than waves of variable amplitude. Possibly a simple carrier signal, with uniform peaks and unmodulated amplitude (only freq &amp; harmonics modulated) would be a better start than cutting the bit depth of an existing live recording. With clearly adjusted harmonics, I feel you'd have more to convey pronunciation. I'm not sure, but maybe it would be worth a try. Either way, excellent experiment!
Thanks! That's very generous of you, I wish that this project had come out a little better. You might be right about switching to square waves, but I'm not sure I'll ever have time to try!
Hm, did you run the sound through a low-pass filter before printing the waveforms? I would think that a lot of the higher frequences will just result in noise when converted to geometry.<br> <br> In fact, if you assume a &quot;read&quot; speed of 26 inch/s and a resolution of 300dpi, that translates to 7800 dots/s, or 3900 grooves/s=3.9kHz. I.e. any frequency higher than 3.9kHz would be impossible to print with just 300dpi. (All that is assuming I remember some fragment of my signal processing course&nbsp;<em>and</em> that I managed to not screw up my numbers anywhere. A tall order, I know...)<br> <br> Actually, if I were to venture a guess I would think that filtering it down further to just a few distinct frequences using a comb filter may yield even better results.
I think the DPI would represent the sample rate though. If 3.9 k is the sample rate (number of grooves), the higest audio frequency you will be able to reproduce is half that or 1.95 k.
yeah I filtered to 4k
(Okay, now I can't stop thinking about this so I better try to get some more of it out of my system)<br> <br> My idea of using a comb filter may or may not be usable, but here's my thought process behind suggesting it anyway.<br> <br> Since I wouldn't expect the size of the bumps of the printed strip to actually produce much difference in sound amplitude when dragging an edge over it (I would actually expect having sporadic larger bump would cause the edge to jump and skip over grooves, degrading the sound quality), the geometry would probably work better if it was more like how the musical roads works. That is, a waveform that is essentially digital (low or high) and the sound is produced by the distance between the grooves rather than the varying amplitude of a proper waveform.<br> <br> My thinking was that by trimming it down to fewer frequencies, it would be result in a waveform with fewer &quot;overlapping&quot; grooves, leading to a cleaner separation between the grooves. But as I said, it was mostly a guess which may be way off. It might be enough to just remove all frequencies below some limit that is way lower than the theoretical maximum above.
I think this is on the right track, my next tests are going to be lower amp/lower bit depth. Even 1 bit audio can give some good results, this is a 1 bit david bowie edit: <br />http://www.mixcloud.com/amandaghassaei/1-bit-audio-edit/ <br />I think the biggest issue is that I didn't print at 600dpi, I only printed at 300. The difference between 300 and 600 with the 3d printed records was huge
Ooh, how about making your 3d print design match up to a plastic wire tie and use it to play your sound (actually maybe even print something like this). Your sound wave may need to be more saw-tooth like
fantastic, I love your creative use of 3d printing!
Heya, maybe try combine the idea of storing a sound file using 3d printing, with that of using different thicknesses. Shine a precise light through the thing and a light sensor on the other side connected through amp into a speaker! Good luck if you try this
ha that would be pretty cool!
Hmm, that birthday card strip is working almost like a guitar string in that the tension makes the strip vibrate to produce sound. It makes me wonder if your print would make a clearer sound if you secured one end of your printed strip to something and pulled it taught before playing it.
that's an interesting idea, the prints do have some flex to them
Amanda, you have done a great job. Thanks for mention my suggestion. <br> <br>I think your test is good, but if you use a higher pitch the result would be better. Maybe the amplitude of the waves is too large, try to reduce it too. <br>
yes I think lower amplitude will help, I'll have to wait until we set up one of our printers to high res to try that
this sounds pretty violent. i love it.
Awesome job Amanda!!! YOU ARE AWESOME!
The idea reminds me of &quot;wire recordings&quot;, where the sound is indented into a reel of wire, instead of tape, so that it survives crashes and fires etc.

About This Instructable




Bio: I'm a grad student at the Center for Bits and Atoms at MIT Media Lab. Before that I worked at Instructables, writing code for ... More »
More by amandaghassaei:OTCA Metapixel - Conway's Game of Life "9 Degrees of Freedom" IMU Twitter Controlled Pet Feeder 
Add instructable to: