This page was automatically generated by NetLogo 4.1beta1.
The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.
In order for this to work, this file, your model file (Sound Machines.nlogo), and the file NetLogoLite.jar must all be in the same directory. (You can copy NetLogoLite.jar from the directory where you installed NetLogo.)
On some systems, you can test the applet locally on your computer before uploading it to a web server. It doesn't work on all systems, though, so if it doesn't work from your hard drive, please try uploading it to a web server.
You don't need to include everything in this file in your page. If you want, you can just take the HTML code beginning with <applet> and ending with </applet>, and paste it into any HTML file you want. It's even OK to put multiple <applet> tags on a single page.
If NetLogoLite.jar and your model are in different directories, you must modify the archive= and value= lines in the HTML code to point to their actual locations. (For example, if you have multiple applets in different directories on the same web server, you may want to put a single copy of NetLogoLite.jar in one central place and change the archive= lines of all the HTML files to point to that one central copy. This will save disk space for you and download time for your users.)
powered by NetLogo
view/download model file: Sound Machines.nlogo
This model shows one way turtles can make interesting and varied sounds, or if you like, music. It uses some simple physics to make "machines" that twist, spin, turn, twitch, and bounce. When a part of the machine touches a wall, ceiling, or floor, it makes a sound. The pitch of the sound depends on the location of the touch.
You can start with a standard machine, or generate a random one. You can change and build machines yourself, by changing the characteristics of each part. You can sit back and let the machines play themselves, or you can use the mouse to move them around to control the sound yourself.
The machines are made up of levers. Levers can be different sizes and are pulled down by gravity (in proportion to their size) and subject to friction.
Each lever has one or two "hooks" to connect it to adjacent levers. Each lever rather simple-mindedly tries to move and rotate to keep its hooks attached (or at least pointing towards) its neighbors' hooks.
Some levers have additional constraints. A lever can be fixed in position so it can't move. It can also rotate, as if powered by a motor.
The rules aren't perfect; for example, sometimes the levers separate. Nonetheless, the behavior is often surprisingly realistic, and is rich enough to generate interesting motion which generates interesting sounds.
Press one of the SETUP... buttons to create a machine. If you want, change NUM-LEVERS first to get more or fewer levers.
Press GO to start the machine going. You should start hearing sounds, although if your machine never touches the wall (or ceiling or floor), you won't hear anything.
You can use the mouse to select a lever by clicking on it, or to move a lever by dragging it. The selected lever has a circle around it.
Once you have selected a lever, a variety of controls on the left let you change that lever's properties. They are not described in detail here; play with him and see for yourself what they do.
Some parameters affecting the entire system are on the bottom left and the right. f is friction, g is gravity. There are also controls for spin.
You can use the INSTRUMENT slider to pick a different musical instrument for the levers to play.
If you make a machine you especially like, you can use Export World and Import World on the File menu to save it out and load it back in again.
The simple rules followed by the levers produce some quite realistic-looking behavior.
Some machines don't do anything. Other machines make simple, repetitive motions. And others are wildly chaotic.
Try all of the different SETUP buttons.
Try all of the lever controls on the left.
Explore the effect of the parameters on the right.
See if you can make machines which are somewhat repetitive, but also somewhat unpredictable and chaotic. Sometimes these make the most pleasing "music".
Using the command center, tell the turtles to put their pens down (using the PEN-DOWN command, abbreviated PD). This generates some pleasing patterns. Use CLEAR-DRAWING (abbreviated CD) to start a new drawing.
There are endless possibilities for how the same basic physics engine could be used to generate sound. The levers could:
- Play different instruments, instead of all the same one.
- Make percussion sounds in addition pitched sounds.
- Make sounds even when they don't hit the wall
- Make sounds that depend on their characteristics
And so on.
How "normal" and "musical" can you make the model sound? Currently the rules of the model aren't based on scales or tonality; by choosing pitches more carefully, you might be able to produce music which is less strange, more like music composed by humans. You could also try to produce more regular rhythms by timing sounds to coincide with a regular beat.
Or, you could take the opposite approach, and see how wild, different, and unusual can you make the sounds. Make something that doesn't sound like anything you've ever heard before!
The model uses NetLogo's sound extension. The sound extension is described in the Sound section of the NetLogo User Manual.
Beatbox
Composer
GasLab With Sound
Sound Workbench
Percussion Workbench
This model is a streamlined variant of the Machines 2005 model created and submitted to the NetLogo User Community Models repository by James Steiner. Machines 2005 is available from http://ccl.northwestern.edu/netlogo/models/community/machines-2005.
Thanks to James for creating an earlier version which was silent; Seth Tisue for first adding sound to it; and James again for his further improvements, and for releasing the model under a Creative Commons License.
extensions [sound] globals [ selected ;; lever that is currently selected dragged ;; lever that is currently being dragged ] breed [levers lever] levers-own [ neighbor1 neighbor2 ;; each holds an adjacent lever (or nobody) fixed? ;; if true, lever only turns, never changes position spin ;; -1, 0, or 1 len ;; this times SCALE slider equals size new-xcor new-ycor ;; next values for xcor and ycor new-heading ;; next value for heading xvel yvel ;; x and y velocities ] ;;; ;;; SETUP PROCEDURES ;;; to setup-begin clear-all set-default-shape levers "lever" create-ordered-levers num-levers [ set heading 180 set new-xcor 0 set ycor ((who / num-levers) * world-height + min-pycor ) * -0.8 set new-ycor ycor set fixed? false set len 0.5 set neighbor1 turtle (who - 1) set neighbor2 turtle (who + 1) ] ask lever 0 [ set fixed? true ] end to setup-dangle setup-begin ask turtle (num-levers - 4) [ set len len * 2 set spin 1 ] setup-finish end to setup-finish set selected last sort levers ;; select last lever ask levers [ lever-display ] end to setup-chaos-tentacle setup-begin ask levers [ set len (num-levers - who) * 0.1 set spin (who mod 2) * 2 - 1 ] ask first sort levers [ set new-xcor 0 set new-ycor 0 setxy 0 0 set fixed? true ] setup-finish end to setup-crazy-machine setup-begin ask levers [ ; choose random location, in the inner area of the world set new-xcor (random-float 1.6 - 0.8) * max-pxcor set new-ycor (random-float 1.6 - 0.8) * max-pycor setxy new-xcor new-ycor set fixed? (random 5 = 0) set spin one-of [-1 0 1] set len precision (0.5 + 0.5 * random 4) 1 lever-display ] setup-finish end ;;; ;;; RUNTIME PROCEDURES ;;; to go ask levers [ monitor-mouse ] ask levers [ lever! ] ask levers [ lever-display ] tick end to lever! ifelse self = dragged [ ; if being dragged, then go there the mouse tells you set new-xcor mouse-xcor set new-ycor mouse-ycor ] [ if not fixed? [ set xvel (xvel * f) + ((n1x2 - x1) + (n2x1 - x2)) * 0.5 set yvel (yvel * f) + ((n1y2 - y1) + (n2y1 - y2)) * 0.5 set yvel yvel - g * len set new-xcor xcor + xvel set new-ycor ycor + yvel if abs new-xcor > max-pxcor [ set xvel xvel * -0.99 set new-xcor max-pxcor * sign new-xcor + xvel bonk! ycor ] if abs new-ycor > max-pycor [ set yvel yvel * -0.99 set new-ycor max-pycor * sign new-ycor + yvel bonk! xcor ] ] ] ; calculate new heading of lever ; if node2 of neighbor1 is overlapping center, keep same heading ; otherwise, find heading to hook 2 of neighbor1 let a 180 + heading let b heading if distancexy n1x2 n1y2 > 0 [ set a 180 + towardsxy n1x2 n1y2 ] ; likewise hook 1 of neighbor2 if distancexy n2x1 n2y1 > 0 [ set b towardsxy n2x1 n2y1 ] ; use trig to take mean of a and b set new-heading atan (sin a + sin b) (cos a + cos b) + spin * spin-speed end to lever-display setxy new-xcor new-ycor set heading new-heading set size 2 * scale * len let -s "" ifelse self = selected [ set -s "-s" let new-label (word "selected: " who " - " (precision len 2) " ") ask patch max-pxcor max-pycor [ set plabel new-label ] set label (word who " - " (precision len 2) " " " ----> ") ] [ set label "" ] set shape (word "lever" ifelse-value fixed? ["-f"] [""] item (spin + 1) ["-ws" "" "-cw"] -s) end ;; lever procedures; these report the x and y coordinates ;; of this lever's hooks to-report x1 report xcor - dx * scale * len end to-report y1 report ycor - dy * scale * len end to-report x2 report xcor + dx * scale * len end to-report y2 report ycor + dy * scale * len end ;; lever procedures; these report the x and y coordinates ;; of our neighbor's hooks. if no neighbor, use own hook. to-report n1x1 ifelse neighbor1 = nobody [ report x2 ] [ report [x1] of neighbor1 ] end to-report n1y1 ifelse neighbor1 = nobody [ report y2 ] [ report [y1] of neighbor1 ] end to-report n1x2 ifelse neighbor1 = nobody [ report x1 ] [ report [x2] of neighbor1 ] end to-report n1y2 ifelse neighbor1 = nobody [ report y1 ] [ report [y2] of neighbor1 ] end to-report n2x1 ifelse neighbor2 = nobody [ report x2 ] [ report [x1] of neighbor2 ] end to-report n2y1 ifelse neighbor2 = nobody [ report y2 ] [ report [y1] of neighbor2 ] end to-report n2x2 ifelse neighbor2 = nobody [ report x1 ] [ report [x2] of neighbor2 ] end to-report n2y2 ifelse neighbor2 = nobody [ report y1 ] [ report [y2] of neighbor2 ] end to-report sign [a] ifelse a = 0 [ report 0 ] [ ifelse a < 0 [ report -1 ] [ report 1 ] ] end ;;; ;;; SELECTION & DRAGGING PROCEDURES ;;; to monitor-mouse let mouse-here? abs (mouse-xcor - xcor) < scale / 2 and abs (mouse-ycor - ycor) < scale / 2 ifelse mouse-here? [ if color != white [ set color white ] ] [ if color = white [ set color item (who mod 14) base-colors ] ] ifelse mouse-down? [ if dragged = nobody and mouse-here? [ set dragged self set selected self ] ] [ set dragged nobody ] end to select-lever [which-lever] let new lever (which-lever + [who] of selected) if new != nobody [ set selected new ] end ;;; ;;; SOUND PROCEDURES ;;; to bonk! [coordinate] sound:play-note my-instrument (pitch coordinate) 90 0.05 end to-report pitch [coordinate] ;; lever procedure report 16 + round (96 * (coordinate + max-pxcor) / world-width) end to-report my-instrument ;; lever procedure report item ((who + instrument) mod length sound:instruments) sound:instruments end