Thursday, June 6, 2013

3D Printed Sound Bites

main pic.jpgAfter 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:
main pic.jpgThe 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).//3d printed sound bites - wav to txt//by Amanda Ghassaei//May 2013//http://www.instructables.com/id/3D-Printed-Sound-Bites//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version.*/import waveimport mathimport structbitDepth = 8#target bitDepthfrate = 44100#target frame ratefileName = "your_file_name_here.wav";#file to be imported (change this)#read file and get dataw = wave.open(fileName, 'r')numframes = w.getnframes()frame = w.readframes(numframes)#w.getnframes()frameInt = map(ord, list(frame))#turn into array#separate left and right channels and merge bytesframeOneChannel = [0]*numframes#initialize list of one channel of wavefor i in range(numframes): frameOneChannel[i] = frameInt[4*i+1]*2**8+frameInt[4*i]#separate channels and store one channel in new list if frameOneChannel[i] > 2**15: frameOneChannel[i] = (frameOneChannel[i]-2**16) elif frameOneChannel[i] == 2**15: frameOneChannel[i] = 0 else: frameOneChannel[i] = frameOneChannel[i]#convert to stringaudioStr = ''for i in range(numframes): audioStr += str(frameOneChannel[i]) audioStr += ","#separate elements with commafileName = fileName[:-3]#remove .wav extensiontext_file = open(fileName+"txt", "w")text_file.write("%s"%audioStr)text_file.close()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.//3d printed sound bites//by Amanda Ghassaei//May 2013//http://www.instructables.com/id/3D-Printed-Sound-Bites//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version.*/import processing.opengl.*;import unlekker.util.*;import unlekker.modelbuilder.*;import ec.util.*;String filename = "amanda.txt";UGeometry geo;//storage for stl geometryUVertexList lastEdge, currentEdge, end1, end2;//storage for conecting one groove to the next//parametersfloat samplingRate = 44100;//(44.1khz audio initially)int rateDivisor;//ensures we pack only as much data into this stl as the resolution of the printer can handlefloat speed = 26;//inches/sec that the data will be "read" from the surfaceboolean invertGroove = true;//false = grove is below surface, true = groove extends above surfacefloat dpi = 300;//objet printer prints at 600 dpibyte micronsPerLayer = 16;//microns per vertical print layer//variable parametersfloat amplitude = 50;//amplitude of signal (in z layers)float sideWidth = 0;//amount of extra space on each side (in pixels)float bevel = 25;//bevel width (bevel on either side of groove (in pixels)float grooveWidth = 450;//in pixelsfloat depth = 1;//measured in z layers, depth of tops of wave in groove from uppermost surface of recordfloat zHeight = 0.075;//thickness in inchesvoid setup(){ //set up storage geo = new UGeometry();//place to store geometery of vertices lastEdge = new UVertexList(); currentEdge = new UVertexList(); end1 = new UVertexList(); end2 = new UVertexList(); setUpVariables();//convert units, initialize etc drawGrooves(processAudioData());//draw in grooves using imported audio data //change extension of file name String name = filename; int dotPos = filename.lastIndexOf("."); if (dotPos > 0) name = filename.substring(0, dotPos); geo.writeSTL(this, name + ".stl");//write stl file from geomtery exit();}float[] processAudioData(){ //get data out of txt file String rawData[] = loadStrings(filename); String rawDataString = rawData[0]; float audioData[] = float(split(rawDataString,','));//separated by commas //normalize audio data to given bitdepth //first find max val float maxval = 0; for(int i=0;imaxval){ maxval = abs(audioData[i]); } } //normalize amplitude to max val for(int i=0;i             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.


View the original article here

No comments:

Post a Comment