rlm@0
|
1 <?xml version="1.0" encoding="utf-8"?>
|
rlm@0
|
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
rlm@0
|
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
rlm@0
|
4 <html xmlns="http://www.w3.org/1999/xhtml"
|
rlm@0
|
5 lang="en" xml:lang="en">
|
rlm@0
|
6 <head>
|
rlm@0
|
7 <title>The EARS!</title>
|
rlm@0
|
8 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
rlm@0
|
9 <meta name="generator" content="Org-mode"/>
|
rlm@0
|
10 <meta name="generated" content="2011-09-21 16:38:27 MDT"/>
|
rlm@0
|
11 <meta name="author" content="Robert McIntyre"/>
|
rlm@0
|
12 <meta name="description" content="Simulating multiple listeners and the sense of hearing in uMonkeyEngine3"/>
|
rlm@0
|
13 <meta name="keywords" content=""/>
|
rlm@0
|
14 <style type="text/css">
|
rlm@0
|
15 <!--/*--><![CDATA[/*><!--*/
|
rlm@0
|
16 html { font-family: Times, serif; font-size: 12pt; }
|
rlm@0
|
17 .title { text-align: center; }
|
rlm@0
|
18 .todo { color: red; }
|
rlm@0
|
19 .done { color: green; }
|
rlm@0
|
20 .tag { background-color: #add8e6; font-weight:normal }
|
rlm@0
|
21 .target { }
|
rlm@0
|
22 .timestamp { color: #bebebe; }
|
rlm@0
|
23 .timestamp-kwd { color: #5f9ea0; }
|
rlm@0
|
24 .right {margin-left:auto; margin-right:0px; text-align:right;}
|
rlm@0
|
25 .left {margin-left:0px; margin-right:auto; text-align:left;}
|
rlm@0
|
26 .center {margin-left:auto; margin-right:auto; text-align:center;}
|
rlm@0
|
27 p.verse { margin-left: 3% }
|
rlm@0
|
28 pre {
|
rlm@0
|
29 border: 1pt solid #AEBDCC;
|
rlm@0
|
30 background-color: #F3F5F7;
|
rlm@0
|
31 padding: 5pt;
|
rlm@0
|
32 font-family: courier, monospace;
|
rlm@0
|
33 font-size: 90%;
|
rlm@0
|
34 overflow:auto;
|
rlm@0
|
35 }
|
rlm@0
|
36 table { border-collapse: collapse; }
|
rlm@0
|
37 td, th { vertical-align: top; }
|
rlm@0
|
38 th.right { text-align:center; }
|
rlm@0
|
39 th.left { text-align:center; }
|
rlm@0
|
40 th.center { text-align:center; }
|
rlm@0
|
41 td.right { text-align:right; }
|
rlm@0
|
42 td.left { text-align:left; }
|
rlm@0
|
43 td.center { text-align:center; }
|
rlm@0
|
44 dt { font-weight: bold; }
|
rlm@0
|
45 div.figure { padding: 0.5em; }
|
rlm@0
|
46 div.figure p { text-align: center; }
|
rlm@0
|
47 textarea { overflow-x: auto; }
|
rlm@0
|
48 .linenr { font-size:smaller }
|
rlm@0
|
49 .code-highlighted {background-color:#ffff00;}
|
rlm@0
|
50 .org-info-js_info-navigation { border-style:none; }
|
rlm@0
|
51 #org-info-js_console-label { font-size:10px; font-weight:bold;
|
rlm@0
|
52 white-space:nowrap; }
|
rlm@0
|
53 .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
|
rlm@0
|
54 font-weight:bold; }
|
rlm@0
|
55 /*]]>*/-->
|
rlm@0
|
56 </style>
|
rlm@0
|
57 <link rel="stylesheet" type="text/css" href="../aurellem/src/css/aurellem.css"/>
|
rlm@0
|
58 <script type="text/javascript">
|
rlm@0
|
59 <!--/*--><![CDATA[/*><!--*/
|
rlm@0
|
60 function CodeHighlightOn(elem, id)
|
rlm@0
|
61 {
|
rlm@0
|
62 var target = document.getElementById(id);
|
rlm@0
|
63 if(null != target) {
|
rlm@0
|
64 elem.cacheClassElem = elem.className;
|
rlm@0
|
65 elem.cacheClassTarget = target.className;
|
rlm@0
|
66 target.className = "code-highlighted";
|
rlm@0
|
67 elem.className = "code-highlighted";
|
rlm@0
|
68 }
|
rlm@0
|
69 }
|
rlm@0
|
70 function CodeHighlightOff(elem, id)
|
rlm@0
|
71 {
|
rlm@0
|
72 var target = document.getElementById(id);
|
rlm@0
|
73 if(elem.cacheClassElem)
|
rlm@0
|
74 elem.className = elem.cacheClassElem;
|
rlm@0
|
75 if(elem.cacheClassTarget)
|
rlm@0
|
76 target.className = elem.cacheClassTarget;
|
rlm@0
|
77 }
|
rlm@0
|
78 /*]]>*///-->
|
rlm@0
|
79 </script>
|
rlm@0
|
80
|
rlm@0
|
81 </head>
|
rlm@0
|
82 <body>
|
rlm@0
|
83
|
rlm@0
|
84 <div id="content">
|
rlm@0
|
85
|
rlm@0
|
86
|
rlm@0
|
87
|
rlm@0
|
88 <div class="header">
|
rlm@0
|
89 <div class="float-right">
|
rlm@0
|
90 <!--
|
rlm@0
|
91 <form>
|
rlm@0
|
92 <input type="text"/><input type="submit" value="search the blog »"/>
|
rlm@0
|
93 </form>
|
rlm@0
|
94 -->
|
rlm@0
|
95 </div>
|
rlm@0
|
96
|
rlm@0
|
97 <h1>aurellem <em>☉</em></h1>
|
rlm@0
|
98 <ul class="nav">
|
rlm@0
|
99 <li><a href="/">read the blog »</a></li>
|
rlm@0
|
100 <!-- li><a href="#">learn about us »</a></li-->
|
rlm@0
|
101 </ul>
|
rlm@0
|
102 </div>
|
rlm@0
|
103
|
rlm@0
|
104 <h1 class="title">The EARS!</h1>
|
rlm@0
|
105 <div class="author">Written by <author>Robert McIntyre</author></div>
|
rlm@0
|
106
|
rlm@0
|
107
|
rlm@0
|
108
|
rlm@0
|
109
|
rlm@0
|
110
|
rlm@0
|
111
|
rlm@0
|
112
|
rlm@0
|
113
|
rlm@0
|
114
|
rlm@0
|
115
|
rlm@0
|
116 <div id="table-of-contents">
|
rlm@0
|
117 <h2>Table of Contents</h2>
|
rlm@0
|
118 <div id="text-table-of-contents">
|
rlm@0
|
119 <ul>
|
rlm@0
|
120 <li><a href="#sec-1">1 Ears! </a></li>
|
rlm@0
|
121 </ul>
|
rlm@0
|
122 </div>
|
rlm@0
|
123 </div>
|
rlm@0
|
124
|
rlm@0
|
125 <div id="outline-container-1" class="outline-2">
|
rlm@0
|
126 <h2 id="sec-1"><span class="section-number-2">1</span> Ears! </h2>
|
rlm@0
|
127 <div class="outline-text-2" id="text-1">
|
rlm@0
|
128
|
rlm@0
|
129
|
rlm@0
|
130 <p>
|
rlm@0
|
131 I want to be able to place ears in a similiar manner to how I place
|
rlm@0
|
132 the eyes. I want to be able to place ears in a unique spatial
|
rlm@0
|
133 position, and recieve as output at every tick the FFT of whatever
|
rlm@0
|
134 signals are happening at that point.
|
rlm@0
|
135 </p>
|
rlm@0
|
136
|
rlm@0
|
137
|
rlm@0
|
138
|
rlm@0
|
139 <pre class="src src-clojure">(<span style="color: #9b30ff;">ns</span> body.ear)
|
rlm@0
|
140 (<span style="color: #da70d6;">use</span> 'cortex.world)
|
rlm@0
|
141 (<span style="color: #da70d6;">use</span> 'cortex.import)
|
rlm@0
|
142 (<span style="color: #da70d6;">use</span> 'clojure.contrib.def)
|
rlm@0
|
143 (cortex.import/mega-import-jme3)
|
rlm@0
|
144 (rlm.rlm-commands/help)
|
rlm@0
|
145 (<span style="color: #9b30ff;">import</span> java.nio.ByteBuffer)
|
rlm@0
|
146 (<span style="color: #9b30ff;">import</span> java.awt.image.BufferedImage)
|
rlm@0
|
147 (<span style="color: #9b30ff;">import</span> java.awt.Color)
|
rlm@0
|
148 (<span style="color: #9b30ff;">import</span> java.awt.Dimension)
|
rlm@0
|
149 (<span style="color: #9b30ff;">import</span> java.awt.Graphics)
|
rlm@0
|
150 (<span style="color: #9b30ff;">import</span> java.awt.Graphics2D)
|
rlm@0
|
151 (<span style="color: #9b30ff;">import</span> java.awt.event.WindowAdapter)
|
rlm@0
|
152 (<span style="color: #9b30ff;">import</span> java.awt.event.WindowEvent)
|
rlm@0
|
153 (<span style="color: #9b30ff;">import</span> java.awt.image.BufferedImage)
|
rlm@0
|
154 (<span style="color: #9b30ff;">import</span> java.nio.ByteBuffer)
|
rlm@0
|
155 (<span style="color: #9b30ff;">import</span> javax.swing.JFrame)
|
rlm@0
|
156 (<span style="color: #9b30ff;">import</span> javax.swing.JPanel)
|
rlm@0
|
157 (<span style="color: #9b30ff;">import</span> javax.swing.SwingUtilities)
|
rlm@0
|
158 (<span style="color: #9b30ff;">import</span> javax.swing.ImageIcon)
|
rlm@0
|
159 (<span style="color: #9b30ff;">import</span> javax.swing.JOptionPane)
|
rlm@0
|
160 (<span style="color: #9b30ff;">import</span> java.awt.image.ImageObserver)
|
rlm@0
|
161 </pre>
|
rlm@0
|
162
|
rlm@0
|
163
|
rlm@0
|
164
|
rlm@0
|
165
|
rlm@0
|
166 <p>
|
rlm@0
|
167 JMonkeyEngine3's audio system works as follows:
|
rlm@0
|
168 first, an appropiate audio renderer is created during initialization
|
rlm@0
|
169 and depending on the context. On my computer, this is the
|
rlm@0
|
170 LwjglAudioRenderer.
|
rlm@0
|
171 </p>
|
rlm@0
|
172 <p>
|
rlm@0
|
173 The LwjglAudioRenderer sets a few internal state variables depending
|
rlm@0
|
174 on what capabilities the audio system has.
|
rlm@0
|
175 </p>
|
rlm@0
|
176 <p>
|
rlm@0
|
177 may very well need to make my own AudioRenderer
|
rlm@0
|
178 </p>
|
rlm@0
|
179
|
rlm@0
|
180
|
rlm@0
|
181
|
rlm@0
|
182 <pre class="src src-clojure">(<span style="color: #9b30ff;">in-ns</span> 'body.ear)
|
rlm@0
|
183 (<span style="color: #9b30ff;">import</span> 'com.jme3.capture.SoundProcessor)
|
rlm@0
|
184
|
rlm@0
|
185
|
rlm@0
|
186 (<span style="color: #9b30ff;">defn</span> <span style="color: #0000ff;">sound-processor</span>
|
rlm@0
|
187 <span style="color: #EB4264;">"deals with converting ByteBuffers into Arrays of bytes so that the</span>
|
rlm@0
|
188 <span style="color: #EB4264;"> continuation functions can be defined in terms of immutable stuff."</span>
|
rlm@0
|
189 [continuation]
|
rlm@0
|
190 (<span style="color: #da70d6;">proxy</span> [SoundProcessor] []
|
rlm@0
|
191 (cleanup [])
|
rlm@0
|
192 (process
|
rlm@0
|
193 [<span style="color: #228b22;">#^ByteBuffer</span> audioSamples numSamples]
|
rlm@0
|
194 (no-exceptions
|
rlm@0
|
195 (<span style="color: #9b30ff;">let</span> [byte-array (<span style="color: #da70d6;">byte-array</span> numSamples)]
|
rlm@0
|
196 (.get audioSamples byte-array 0 numSamples)
|
rlm@0
|
197 (continuation
|
rlm@0
|
198 (<span style="color: #da70d6;">vec</span> byte-array)))))))
|
rlm@0
|
199
|
rlm@0
|
200
|
rlm@0
|
201 (<span style="color: #9b30ff;">defn</span> <span style="color: #0000ff;">add-ear</span>
|
rlm@0
|
202 <span style="color: #EB4264;">"add an ear to the world. The continuation function will be called</span>
|
rlm@0
|
203 <span style="color: #EB4264;"> on the FFT or the sounds which the ear hears in the given</span>
|
rlm@0
|
204 <span style="color: #EB4264;"> timeframe. Sound is 3D."</span>
|
rlm@0
|
205 [world listener continuation]
|
rlm@0
|
206 (<span style="color: #9b30ff;">let</span> [renderer (.getAudioRenderer world)]
|
rlm@0
|
207 (.addListener renderer listener)
|
rlm@0
|
208 (.registerSoundProcessor renderer listener
|
rlm@0
|
209 (sound-processor continuation))
|
rlm@0
|
210 listener))
|
rlm@0
|
211
|
rlm@0
|
212 </pre>
|
rlm@0
|
213
|
rlm@0
|
214
|
rlm@0
|
215
|
rlm@0
|
216
|
rlm@0
|
217
|
rlm@0
|
218
|
rlm@0
|
219
|
rlm@0
|
220 <pre class="src src-clojure">(<span style="color: #9b30ff;">ns</span> test.hearing)
|
rlm@0
|
221 (<span style="color: #da70d6;">use</span> 'cortex.world)
|
rlm@0
|
222 (<span style="color: #da70d6;">use</span> 'cortex.import)
|
rlm@0
|
223 (<span style="color: #da70d6;">use</span> 'clojure.contrib.def)
|
rlm@0
|
224 (<span style="color: #da70d6;">use</span> 'body.ear)
|
rlm@0
|
225 (cortex.import/mega-import-jme3)
|
rlm@0
|
226 (rlm.rlm-commands/help)
|
rlm@0
|
227
|
rlm@0
|
228 (<span style="color: #9b30ff;">defn</span> <span style="color: #0000ff;">setup-fn</span> [world]
|
rlm@0
|
229 (<span style="color: #9b30ff;">let</span> [listener (Listener.)]
|
rlm@0
|
230 (add-ear world listener #(<span style="color: #da70d6;">println</span> (<span style="color: #da70d6;">nth</span> % 0)))))
|
rlm@0
|
231
|
rlm@0
|
232 (<span style="color: #9b30ff;">defn</span> <span style="color: #0000ff;">play-sound</span> [node world value]
|
rlm@0
|
233 (<span style="color: #9b30ff;">if</span> (<span style="color: #da70d6;">not</span> value)
|
rlm@0
|
234 (<span style="color: #9b30ff;">do</span>
|
rlm@0
|
235 (.playSource (.getAudioRenderer world) node))))
|
rlm@0
|
236
|
rlm@0
|
237 (<span style="color: #9b30ff;">defn</span> <span style="color: #0000ff;">test-world</span> []
|
rlm@0
|
238 (<span style="color: #9b30ff;">let</span> [node1 (AudioNode. (asset-manager) <span style="color: #3AA221;">"Sounds/pure.wav"</span> false false)]
|
rlm@0
|
239 (world
|
rlm@0
|
240 (Node.)
|
rlm@0
|
241 {<span style="color: #3AA221;">"key-space"</span> (<span style="color: #da70d6;">partial</span> play-sound node1)}
|
rlm@0
|
242 setup-fn
|
rlm@0
|
243 no-op
|
rlm@0
|
244 )))
|
rlm@0
|
245
|
rlm@0
|
246
|
rlm@0
|
247 </pre>
|
rlm@0
|
248
|
rlm@0
|
249
|
rlm@0
|
250
|
rlm@0
|
251
|
rlm@0
|
252
|
rlm@0
|
253
|
rlm@0
|
254
|
rlm@0
|
255
|
rlm@0
|
256 </div>
|
rlm@0
|
257 </div>
|
rlm@0
|
258 <div id="postamble">
|
rlm@0
|
259 <p class="date">Date: 2011-09-21 16:38:27 MDT</p>
|
rlm@0
|
260 <p class="author">Author: Robert McIntyre</p>
|
rlm@0
|
261 <p class="creator">Org version 7.6 with Emacs version 23</p>
|
rlm@0
|
262 <a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
|
rlm@0
|
263 </div>
|
rlm@0
|
264 </div>
|
rlm@0
|
265 </body>
|
rlm@0
|
266 </html>
|