comparison org/hearing.org @ 221:7c374c6cfe17

hearing.org rough draft is ready
author Robert McIntyre <rlm@mit.edu>
date Sat, 11 Feb 2012 12:15:07 -0700
parents c5f6d880558b
children 49d0a545a872
comparison
equal deleted inserted replaced
220:c5f6d880558b 221:7c374c6cfe17
786 floats which represent the linear PCM encoded waveform of the 786 floats which represent the linear PCM encoded waveform of the
787 sound. With linear PCM (pulse code modulation) -1.0 represents maximum 787 sound. With linear PCM (pulse code modulation) -1.0 represents maximum
788 rarefaction of the air while 1.0 represents maximum compression of the 788 rarefaction of the air while 1.0 represents maximum compression of the
789 air at a given instant. 789 air at a given instant.
790 790
791 #+name: ears 791 #+name: hearing-pipeline
792 #+begin_src clojure 792 #+begin_src clojure
793 (in-ns 'cortex.hearing) 793 (in-ns 'cortex.hearing)
794 794
795 (defn hearing-pipeline 795 (defn hearing-pipeline
796 "Creates a SoundProcessor which wraps a sound processing 796 "Creates a SoundProcessor which wraps a sound processing
830 object with which it is bound, just as the camera in the [[http://aurellem.localhost/cortex/html/sense.html#sec-4-1][sense binding 830 object with which it is bound, just as the camera in the [[http://aurellem.localhost/cortex/html/sense.html#sec-4-1][sense binding
831 demonstration]]. =OpenAL= simulates the doppler effect for moving 831 demonstration]]. =OpenAL= simulates the doppler effect for moving
832 listeners, =(update-listener-velocity!)= ensures that this velocity 832 listeners, =(update-listener-velocity!)= ensures that this velocity
833 information is always up-to-date. 833 information is always up-to-date.
834 834
835 #+name: hearing-ears
835 #+begin_src clojure 836 #+begin_src clojure
836 (defvar 837 (defvar
837 ^{:arglists '([creature])} 838 ^{:arglists '([creature])}
838 ears 839 ears
839 (sense-nodes "ears") 840 (sense-nodes "ears")
872 (.registerSoundProcessor audio-renderer lis sp))) 873 (.registerSoundProcessor audio-renderer lis sp)))
873 #+end_src 874 #+end_src
874 875
875 ** Ear Creation 876 ** Ear Creation
876 877
878 #+name: hearing-kernel
877 #+begin_src clojure 879 #+begin_src clojure
878 (defn hearing-kernel 880 (defn hearing-kernel
879 "Returns a functon which returns auditory sensory data when called 881 "Returns a functon which returns auditory sensory data when called
880 inside a running simulation." 882 inside a running simulation."
881 [#^Node creature #^Spatial ear] 883 [#^Node creature #^Spatial ear]
918 reported by the simulated sense of hearing. It converts the values 920 reported by the simulated sense of hearing. It converts the values
919 reported in the vector returned by the hearing function from the range 921 reported in the vector returned by the hearing function from the range
920 [-1.0, 1.0] to the range [0 255], converts to integer, and displays 922 [-1.0, 1.0] to the range [0 255], converts to integer, and displays
921 the number as a greyscale pixel. 923 the number as a greyscale pixel.
922 924
925 #+name: hearing-display
923 #+begin_src clojure 926 #+begin_src clojure
927 (in-ns 'cortex.hearing)
928
924 (defn view-hearing 929 (defn view-hearing
925 "Creates a function which accepts a list of auditory data and 930 "Creates a function which accepts a list of auditory data and
926 display each element of the list to the screen as an image." 931 display each element of the list to the screen as an image."
927 [] 932 []
928 (view-sense 933 (view-sense
931 (vec 936 (vec
932 (map 937 (map
933 #(rem (int (* 255 (/ (+ 1 %) 2))) 256) 938 #(rem (int (* 255 (/ (+ 1 %) 2))) 256)
934 sensor-data)) 939 sensor-data))
935 height 50 940 height 50
936 image (BufferedImage. (count coords) height 941 image (BufferedImage. (max 1 (count coords)) height
937 BufferedImage/TYPE_INT_RGB)] 942 BufferedImage/TYPE_INT_RGB)]
938 (dorun 943 (dorun
939 (for [x (range (count coords))] 944 (for [x (range (count coords))]
940 (dorun 945 (dorun
941 (for [y (range height)] 946 (for [y (range height)]
966 <p>The blue ball is emitting a constant sound. Each blue box is 971 <p>The blue ball is emitting a constant sound. Each blue box is
967 listening for sound, and will change color from blue to green if it 972 listening for sound, and will change color from blue to green if it
968 detects sound which is louder than a certain threshold. As the blue 973 detects sound which is louder than a certain threshold. As the blue
969 sphere travels along the path, it excites each of the cubes in turn.</p> 974 sphere travels along the path, it excites each of the cubes in turn.</p>
970 </div> 975 </div>
971
972 #+end_html 976 #+end_html
973 977
974 #+include "../../jmeCapture/src/com/aurellem/capture/examples/Advanced.java" src java 978 #+include "../../jmeCapture/src/com/aurellem/capture/examples/Advanced.java" src java
975 979
976 Here is a small clojure program to drive the java program and make it 980 Here is a small clojure program to drive the java program and make it
977 available as part of my test suite. 981 available as part of my test suite.
978 982
979 #+name: test-hearing 983 #+name: test-hearing-1
980 #+begin_src clojure 984 #+begin_src clojure
981 (in-ns 'cortex.test.hearing) 985 (in-ns 'cortex.test.hearing)
982 986
983 (defn test-java-hearing 987 (defn test-java-hearing
984 "Testing hearing: 988 "Testing hearing:
992 (.setAudioRenderer "Send"))) 996 (.setAudioRenderer "Send")))
993 (.setShowSettings false) 997 (.setShowSettings false)
994 (.setPauseOnLostFocus false))) 998 (.setPauseOnLostFocus false)))
995 #+end_src 999 #+end_src
996 1000
1001
1002
1003
997 ** Adding Hearing to the Worm 1004 ** Adding Hearing to the Worm
998 1005
999 1006 To the worm, I add a new node called "ears" with one child which
1007 represents the worm's single ear.
1008
1009 #+attr_html: width=755
1010 #+caption: The Worm with a newly added nodes describing an ear.
1011 [[../images/worm-with-ear.png]]
1012
1013 The node highlighted in yellow it the top-level "ears" node. It's
1014 child, highlighted in orange, represents a the single ear the creature
1015 has. The ear will be localized right above the curved part of the
1016 worm's lower hemispherical region opposite the eye.
1017
1018 The other empty nodes represent the worm's single joint and eye and are
1019 described in [[./body.org][body]] and [[./vision.org][vision]].
1020
1021 #+name: test-hearing-2
1022 #+begin_src clojure
1023 (in-ns 'cortex.test.hearing)
1024
1025 (cortex.import/mega-import-jme3)
1026 (import java.io.File)
1027
1028 (use 'cortex.body)
1029
1030 (defn test-worm-hearing []
1031 (let [the-worm (doto (worm) (body!))
1032 hearing (hearing! the-worm)
1033 hearing-display (view-hearing)
1034
1035 tone (AudioNode. (asset-manager)
1036 "Sounds/pure.wav" false)
1037
1038 hymn (AudioNode. (asset-manager)
1039 "Sounds/ear-and-eye.wav" false)]
1040 (world
1041 (nodify [the-worm (floor)])
1042 (merge standard-debug-controls
1043 {"key-return"
1044 (fn [_ value]
1045 (if value (.play tone)))
1046 "key-l"
1047 (fn [_ value]
1048 (if value (.play hymn)))})
1049 (fn [world]
1050 (light-up-everything world)
1051 (com.aurellem.capture.Capture/captureVideo
1052 world
1053 (File."/home/r/proj/cortex/render/worm-audio/frames"))
1054 (com.aurellem.capture.Capture/captureAudio
1055 world
1056 (File."/home/r/proj/cortex/render/worm-audio/audio.wav")))
1057
1058 (fn [world tpf]
1059 (hearing-display
1060 (map #(% world) hearing)
1061 (File. "/home/r/proj/cortex/render/worm-audio/hearing-data"))))))
1062 #+end_src
1063
1064 In this test, I load the worm with its newly formed ear and let it
1065 hear sounds. The sound the worm is hearing is localized to the origin
1066 of the world, and you can see that as the worm moves farther away from
1067 the origin when it is hit by balls, it hears the sound less intensely.
1068
1069 The sound you hear in the video is from the worm's perspective. Notice
1070 how the pure tone becomes fainter and the visual display of the
1071 auditory data becomes less pronounced as the worm falls farther away
1072 from the source of the sound.
1073
1074 #+begin_html
1075 <div class="figure">
1076 <center>
1077 <video controls="controls" width="600">
1078 <source src="../video/worm-hearing.ogg" type="video/ogg"
1079 preload="none" poster="../images/aurellem-1280x480.png" />
1080 </video>
1081 </center>
1082 <p>The worm can now hear the sound pulses produced from the
1083 hymn. Notice the strikingly different pattern that human speech
1084 makes compared to the insturments. Once the worm is pushed off the
1085 floor, the sound it hears is attenuated, and the display of the
1086 sound it hears beomes fainter. This shows the 3D localization of
1087 sound in this world.</p>
1088 </div>
1089
1090 #+end_html
1091
1092 *** Creating the Ear Video
1093 #+name: magick-3
1094 #+begin_src clojure
1095 (ns cortex.video.magick3
1096 (:import java.io.File)
1097 (:use clojure.contrib.shell-out))
1098
1099 (defn images [path]
1100 (sort (rest (file-seq (File. path)))))
1101
1102 (def base "/home/r/proj/cortex/render/worm-audio/")
1103
1104 (defn pics [file]
1105 (images (str base file)))
1106
1107 (defn combine-images []
1108 (let [main-view (pics "frames")
1109 hearing (pics "hearing-data")
1110 background (repeat 9001 (File. (str base "background.png")))
1111 targets (map
1112 #(File. (str base "out/" (format "%07d.png" %)))
1113 (range 0 (count main-view)))]
1114 (dorun
1115 (pmap
1116 (comp
1117 (fn [[background main-view hearing target]]
1118 (println target)
1119 (sh "convert"
1120 background
1121 main-view "-geometry" "+66+21" "-composite"
1122 hearing "-geometry" "+21+526" "-composite"
1123 target))
1124 (fn [& args] (map #(.getCanonicalPath %) args)))
1125 background main-view hearing targets))))
1126 #+end_src
1127
1128 #+begin_src sh
1129 cd /home/r/proj/cortex/render/worm-audio
1130 ffmpeg -r 60 -i out/%07d.png -i audio.wav \
1131 -b:a 128k -b:v 9001k \
1132 -acodec libvorbis -vcodec libtheora worm-hearing.ogg
1133 #+end_src
1000 1134
1001 * Headers 1135 * Headers
1002 1136
1003 #+name: hearing-header 1137 #+name: hearing-header
1004 #+begin_src clojure 1138 #+begin_src clojure
1005 (ns cortex.hearing 1139 (ns cortex.hearing
1006 "Simulate the sense of hearing in jMonkeyEngine3. Enables multiple 1140 "Simulate the sense of hearing in jMonkeyEngine3. Enables multiple
1007 listeners at different positions in the same world. Automatically 1141 listeners at different positions in the same world. Automatically
1008 reads ear-nodes from specially prepared blender files and 1142 reads ear-nodes from specially prepared blender files and
1009 instantiates them in the world as actual ears." 1143 instantiates them in the world as simulated ears."
1010 {:author "Robert McIntyre"} 1144 {:author "Robert McIntyre"}
1011 (:use (cortex world util sense)) 1145 (:use (cortex world util sense))
1012 (:use clojure.contrib.def) 1146 (:use clojure.contrib.def)
1013 (:import java.nio.ByteBuffer) 1147 (:import java.nio.ByteBuffer)
1014 (:import java.awt.image.BufferedImage) 1148 (:import java.awt.image.BufferedImage)
1020 (:import com.jme3.audio.Listener) 1154 (:import com.jme3.audio.Listener)
1021 (:import com.jme3.app.Application) 1155 (:import com.jme3.app.Application)
1022 (:import com.jme3.scene.control.AbstractControl)) 1156 (:import com.jme3.scene.control.AbstractControl))
1023 #+end_src 1157 #+end_src
1024 1158
1159 #+name: test-header
1025 #+begin_src clojure 1160 #+begin_src clojure
1026 (ns cortex.test.hearing 1161 (ns cortex.test.hearing
1027 (:use (cortex world util hearing)) 1162 (:use (cortex world util hearing))
1163 (:use cortex.test.body)
1028 (:import (com.jme3.audio AudioNode Listener)) 1164 (:import (com.jme3.audio AudioNode Listener))
1029 (:import com.jme3.scene.Node 1165 (:import com.jme3.scene.Node
1030 com.jme3.system.AppSettings)) 1166 com.jme3.system.AppSettings))
1031 #+end_src 1167 #+end_src
1032 1168
1040 1176
1041 * COMMENT Code Generation 1177 * COMMENT Code Generation
1042 1178
1043 #+begin_src clojure :tangle ../src/cortex/hearing.clj 1179 #+begin_src clojure :tangle ../src/cortex/hearing.clj
1044 <<hearing-header>> 1180 <<hearing-header>>
1045 <<ears>> 1181 <<hearing-pipeline>>
1182 <<hearing-ears>>
1183 <<hearing-kernel>>
1184 <<hearing-display>>
1046 #+end_src 1185 #+end_src
1047 1186
1048 #+begin_src clojure :tangle ../src/cortex/test/hearing.clj 1187 #+begin_src clojure :tangle ../src/cortex/test/hearing.clj
1049 <<test-hearing>> 1188 <<test-header>>
1189 <<test-hearing-1>>
1190 <<test-hearing-2>>
1191 #+end_src
1192
1193 #+begin_src clojure :tangle ../src/cortex/video/magick3.clj
1194 <<magick-3>>
1050 #+end_src 1195 #+end_src
1051 1196
1052 #+begin_src C :tangle ../../audio-send/Alc/backends/send.c 1197 #+begin_src C :tangle ../../audio-send/Alc/backends/send.c
1053 <<send-header>> 1198 <<send-header>>
1054 <<send-state>> 1199 <<send-state>>