Binaural Sound with the Web Audio API

The simulation

Use headphones and click on any point around the person below to choose a direction for the incoming sound. The blue dots are in perpendicular directions relative to the listener. Try different head-related impulse responses (HRIR). Some of them will work better than others, depending on the individual. Note that the simulation has only been tested on Firefox and Chrome! Also, some people get errors with their web audio context having a different sample rate than the HRIR:s*.

  You need headphones for the following simulation!

http://kaistale.com/blog/141226hrir/

The theory

Head-related transfer functions describe the cues we receive that enable us to determine the direction a sound arrives from. We only have two ears. To be able to determine the direction the sound arrives from in 3D, our brain has to use all the information it can.

For example, the sound will often arrive at the other ear with a small delay. Also, there will often be a difference in the sound level at one ear, as compared to the other (especially at high frequencies). But, additionally, there is a ton of information available for our brain to use. Our shoulders reflect sound. Sound reflects and diffracts around our external ears (pinna). As our features, such as the shape of our pinna, are individual, so is the way our brain perceives sound in 3D.

Still, our heads are often similar enough, which enables us to approximate 3D sound by ready made head-related transfer functions. Once we have a description of how sound arrives at our ears from different angles, we can take any sound and play it back from some direction in 3D.

The simulation in this post uses head-related transfer functions from the CIPIC HRTF database. This paper provides some nice additional information about head-related transfer functions.

The source code

The source code is here: https://github.com/kai5z/hrtf-simulation

*) If your web audio context has a different sample rate as compared to the HRIR:s sample rate (44.1 kHz), the audio won’t work. Apparently the sample rate of the context isn’t definable (please correct me if I’m wrong!), so the HRIR should be resampled for it to work.

Synthesizing thunder using JavaScript

Have you ever considered what actually causes the sound of thunder? The past summer brought with it a few thunder storms, which got me thinking about a topic I find very fascinating and cool: simulating thunder!

The simulation

Note that the simulation can be quite heavy for more complex lightning strikes (some are even unrealistically complex) and for longer distances from the strike. Calculating the result can take quite a bit of time, depending on your computer. A sample frequency of 22 kHz is used and the simulation is monaural. The lightning consists of a single discharge between the cloud and the ground.

http://www.kaistale.com/blog/140809thunder/index.html

If the simulation appears to jam up, please reload the page. Once again, I recommend Chrome for the simulation. Take a look at the source code here – I was somewhat lazy with the commenting of the code!

What is lightning?

Let’s use the definition of lightning given by google:

The occurrence of a natural electrical discharge of very short duration and high voltage between a cloud and the ground or within a cloud, accompanied by a bright flash and typically also thunder.

I believe the geometry of the lightning channel becomes clearer when one considers the part of the following video starting at 1 min 15 s:

Note that the person in the video talks about the lightning consisting of “roughly 50 yard segments”. These segments, referred to as the tortuosity of the lightning channel, are usually between 5 and 70 meters long [Rakov et al. 2003].

In our case, let’s simplify the lightning as consisting of pretty much straight lines, with a random length of 5 to 70 meters. The lines zig-zag constantly, with a random variation of about 16 degrees between each line. Also, we’ll need to add a small statistical deviation in the vertical direction.

What causes thunder?

Ok, so what causes the sound of the lightning? Let’s consider what happens when the discharge happens. We very quickly warm up a channel of air (the orange area in the cut plane image below). As the temperature in the channel rapidly rises to ~24000K [Orville, 1968], the pressure of the air in the channel rises enormously (to about 10^6 Pa). This pushes the the air outwards at speeds exceeding the speed of sound, causing a shock wave expanding at roughly 3000 m/s [Few, 1986].

After this, the air in the channel quickly cools down. The pressure behind the rapidly expanding shock wave will momentarily drop below atmospheric pressure due to the inertia of the outwards traveling air mass. The shock wave will travel some distance (the “relaxation radius”), after which it will dissipate, leaving behind what is called the weak shock wave. This weak shock wave can now be plotted as a function of pressure.

Never mind the scales for now (y-axis represents atmospheric pressure), but note this: the pressure wave will propagate towards you from the lightning so that the “sharp” part of it will reach you first.

What is thunder?

Ok, so now we now that the really hot lightning channel causes a traveling pressure wave. We also know that changes in pressure equals sound. So what we’re hearing is the pressure waves caused by the rapidly heating air in the lightning channel.

But what causes the rumbling sound? Why does the thunder keep on rumbling for many seconds? What makes a close lightning strike sound (sort of) like a clap, while a distant strike can only be heard as rumble?

Here are some of the reasons:

1. The size of the lightning is huge

Consider a lightning strike some distance from you, as in the image above. If you measure the distance to each part of the lightning, you will see that the distance can vary by miles/kilometres! Considering that sound only travels at about 340 m/s (1,125 ft/s), there will be multiple seconds between when the sound from the nearest part of the lightning strike arrives at your position, as compared to the sounds form the more distant parts.

The situation can also be thought of according to Huygens’ principle, which states that any source can be thought of as a series of spherical sources (kind of like in the image above). This is how the simulation, presented at the beginning of this post, works. The lightning is divided into multiple small segments, each modeled as a separate spherical sound source.

2. Sound attenuates by distance

It is, perhaps, obvious that more distant sound sources are quieter. But, additionally, it should be noted that higher frequencies attenuate much faster! Thus, when sound travels a distance, it gets “muffled” by air. Wolfram alpha is a great resource for this, it calculates this attenuation according to ISO 9613-1:1993. This causes distant sounds to “rumble” while the closest sounds are sharp and discernible.

3. Other stuff

There are loads of things at play in real life (for example atmospheric diffraction, which is the reason for the thunder sometimes being completely inaudible even when the lightning strike is clearly visible). If you’re interested in learning more about the topic, I found the following books useful:

  • Vladimir Rakov & Martin Uman – Lightning, physics and effects
  • Geophysics study committee – Earth’s electrical environment
  • Hans Volland – Handbook of Atmospheric Electrodynamics, Volume 2

4. Future ideas

It would be really cool to make the simulation in stereo, so that the sounds from the lightning channel are panned to their respective position  (or even using head related transfer functions!). If someone else is up for the task and has some knowledge of acoustics and DSP, feel free to contact me! 🙂

Simulating cymatics

Due to popular demand I put the source for the script I used here up to github: https://github.com/kai5z/Chladni-patterns

I was browsing around youtube when I stumbled upon this nice video on Chladni patterns (there are quite a few there). Here’s the video, it’s apparently part of some demonstration for students:

Cymatics

Sound propagates in solids, similarly as to how it does in air. If we were to slow down the plate in the video above, we would see it vibrating at the frequency of the sound you can hear being played (check another post of mine).

Just as is the case in air, standing waves can form in solids. In solids, the details are quite different, but the basic principle holds. When a standing wave forms, there are locations where the amplitudes of the vibrations have their maximum values, and locations where the amplitudes of the vibrations are very close to zero.

Imagine placing a lot of small particles on the surface in the image. The particles would be tossed around, until they finally find a resting place close to the red circle. This is how all of the patterns are formed, but the way the plate vibrates varies with frequency.

Simulating cymatics

The experiment setup is very clearly defined; a rectangular steel plate is clamped in the middle. This makes for a perfect case to test out some finite element analysis of plate structures!

I used steel as the material of choice for the simulation and Reissner-Mindlin bilinear plate elements, with a lumped mass matrix. I programmed the simulation using Python. By tweaking around with the material properties and dimensions, I managed to roughly match the frequencies to the experiment from the first video. I think it’s really cool how the simulation matches the patterns you can see in the video (up until a point where it’s apparent that there are some asymmetries in the setup).

I made a gif out of the video too, just for the hell of it.

You might have noticed that there are a whole lot of patterns there, which aren’t visible in the video. The standing waves which create the patterns form much more strongly when the frequency is closer to the modal frequencies of the plate (when the plate resonates). The following plot roughly shows these resonant frequencies. The y-axis doesn’t really mean anything significant here, so just pay attention to the peaks. Also, damping hasn’t been taking into account here, making the peaks unrealistically sharp. When the excitation frequency is close to one of those peaks, Chladni patterns should be clearly visible.

Discussion

The frequencies these patterns form on depends completely on the material properties and dimensions of the plate, if we assume that the basic setup is the same (a rectangular plate is clamped at the middle). There are a lot of structures which can be analysed in a similar way (albeit with a more complex analysis for applicable results): floors, windows, doors, the list goes on and on. In this case, the results were very consistent with the video as the physical problem was very clearly defined.

A tool for solving 2D structural systems

If you’re not that into structural mechanics, feel free to just look at the pictures :-). This post is about a tool that will enable you to calculate how structural systems behave in two dimensions. In the (hopefully not that distant) future, I’ll enable dynamic calculations.

I haven’t shared anything in a while, so I thought I write a status update on this cool (at least I think it is cool!) tool I’ve been working during the last few months, along with other projects. It’s based on an old idea, which I thought I’d finally realize properly. The tool is able to do finite element analysis of simple structural systems in 2D. There are quite a few things I’m planning to do differently as compared to the tools out there. For example, the tool will be able to solve symbolic problems (at least simple ones) along with numerical ones. It works quite well as long as the problem is not huge.

I was thinking of making a very early beta version of the tool available along with this post, but (as is very often the case) things have taken a bit longer than expected, and other projects have been taking up my time. So the very-early-beta release still needs some tweaking. Also, I’m not quite sure about liability issues with releasing a not-so-perfectly working version of a tool such as this, so I might never release it. We’ll see.

Overview

Some theory:

  • I’ve currently implemented basic functionality for solving structural systems consisting of beams (with axial and/or moment loads according to my previous post)
  • A linear elastic problem (static) is solved

The logic has been implemented in such a way that it should be relatively straightforward to extend the functionality to problems involving small amplitude (linear) vibrations, for examining vibrating systems in 2D. I’m really looking forward to getting to play around with that phase of the project. But, first things first, I’ve got to get static problems working properly and without any glitches.

Examples

Here are some examples of simple linear static beam structures the tool is currently able to give the correct symbolic answer to. Some background:

  • The cases have been done using a nifty GUI, which I’m quite happy with
  • L is half of the width of the figures (often the length of the beam)
  • The magnitude of the force is F
  • All cross sectional properties are given by E, I and A
    • Except for the blue bars, which have a cross sectional area of $$2\sqrt{2}A$$
    • The connections are assumed to align with the neutral axis
  • A hollow node represents a hinged connection
  • A filled node represents a stiff connection
  • The positive x-axis points towards the right
  • The positive y-axis points downwards

The nodes are numbered from the left to the right, so just count them from the left if you want to validate the results. There are quite a few analytical formulas available for these situations if you try searching online.

Case 1, $$\begin{Bmatrix}{}x_2\\y_2\\\theta_2\end{Bmatrix}=\begin{Bmatrix}{}0\\\frac{F L^{3}}{192 E I}\\0\end{Bmatrix}$$

Case 2, $$\begin{Bmatrix}{}\theta_1\\a_3\\\theta_3\\x_2\\y_2\\\theta_2\end{Bmatrix}=\begin{Bmatrix}{}\frac{F L^{2}}{16 E I}\\0\\- \frac{F L^{2}}{16 E I}\\0\\\frac{F L^{3}}{48 E I}\\0\end{Bmatrix}$$

Case 3, $$\begin{Bmatrix}{}x_2\\y_2\\\theta_2\end{Bmatrix}=\begin{Bmatrix}{}0\\\frac{F L^{3}}{3 E I}\\\frac{F L^{2}}{2 E I}\end{Bmatrix}$$

Case 4, $$\begin{Bmatrix}{x_3}\\{y_3}\end{Bmatrix}=\begin{Bmatrix}{}- \frac{F L}{3 A E}\\- \frac{2 F L}{3 A E}\end{Bmatrix}$$

Case 5, $$a_3=\frac{\sqrt{2} F L}{A E}$$ (positive to the left)

The future

The results coincide with solutions such as these, which means that everything is working properly (woohoo)!

So far, the GUI has been the most demanding part of the project. There’s still a lot to be done. Static calculations might be something the average structural engineer finds even more useful than dynamic calculations, so those are currently my top priority. Still, the really cool stuff (in my opinion) will be possible once you’ll be able to investigate dynamic systems, which is helpful for both acoustical/vibration consultants and structural engineers alike!

Deformed beams