Mercurial > cortex
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>> |