Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER for Spatial Audio

Reply
 
Thread Tools Display Modes
Old 06-14-2023, 07:43 AM   #1
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default Ambisonics Order Angular Resolution and Spherical Harmonics

I've been searching for a table showing the angular resolution of each order of Ambisonics. I've not found such a table. So I set out to figure out how to calculate it myself. This can now be that reference, or at least to see if someone can double check my workings out.

I'll make my examples with the horizontal plane, which is shown as the left and right edges of spherical harmonic diagrams. With the First Order harmonics, the sphere is divided in half on two axis. Left, right, and forward, back. Splitting the plane into 4, 90° quadrants. When a sound source is exactly on a multiple 90 degrees it will have a unity gain in one row and column of the transformation matrix. That is to say, it's stored completely in one harmonic and its energy isn't averaged across neighbors, and will have the most precise positioning that can be directly correlated with one microphone or one speaker.

A little more detail about how energy is positioned using the harmonics. There is the omnidirectional W channel, which is the same as the mid channel of mid-side stereo. It's the sum if all the energy. It's a full sphere, containing all the energy of the 90° quadrants I described above. Each of the first order harmonics also work very similarly to M/S. Each harmonic directs the omnidirectional energy into one of its quadrants. When the omni channel audio signal waveform is positive, and harmonic's channel signal is also positive (it's the difference between them that matters) it'll be in the positive side of the harmonic. Just like M/S decoding.

That's 1st Order, and is relatively intuitive. Two harmonics on the X (left/right), and two on the Y (front/back), for 4 entirely on the horizontal plane. 360°/4 = 90°. You can look at a harmonic series diagram and see that 1st order, left and right columns each have 2 "blobs". In the 2nd order, there are more columns, but left- and right-most still make up the horizontal. They now have 4 harmonic "blobs" each. 2nd*2 = 4. 4*2=8 360°/8 = 45°. Each Order you increase, you get 2 additional harmonics on the left column, and 2 more on the right. That means you can take the Order and multiply it by 4 to figure out how many directions the energy in the next lower order can be divided.

Just as in the way that the 1st Order sort of does a mid-side thing to the 0th omni, the 2nd order M/Ses the 1st "above" it in the triangular diagrams. The positive side of the 2nd harmonic pushes or pulls the 1st order, to create positions in between the harmonics in the lower order. That means that 3rd Order Ambisonics, having 6 harmonics on the left-most group and another 6 on the right, has an angular resolution of 360/12 = 30°.

Assuming all of this I've put together is correct. Let's make the table I went looking for in the first place:

O1A: 90°
O2A: 45°
O3A: 30°
O4A: 22.5°
O5A: 18°
O6A: 15°
O7A: 12.85714286°
O8A: 11.25°
O9A: 10°
O10A: 9°


So when Reaper gets 128-channel tracks, and we can use 121 channels for 10th Order Ambisonics, we'll be able to position sounds precisely into 9 degree increments. Again, this resolution is like if you have the pan-pot at 100% left or 100% right. You have a "channel" dedicated to the sound source. We've been using panning positions between left and right for several decades to place audio between those two extremes. It's just difficult to know the exact level of a signal that's been panned off of one channel. That's what happens when you rotate something at a non-multiple of the precision limit of what ever order you're using, you're "panning" it between the highest energy points of the spherical harmonics.

Oh, and here's a page that has lots of pictures (and tons of math) that might help you visualize some things: https://en.wikipedia.org/wiki/Table_...ical_harmonics

The above has been edited from my initial post. What I had initially calculated wasn't meshing with what I was seeing in diagrams. I think this is more accurate. I also changed to using the horizontal plane instead of the vertical axis, as I think that's clearer. I've gone over this one more time after sleeping on it. I've realized that each additional order divides up the energy of the lower order preceding it. That order's positioning isn't used directly when higher exits. Just like the mono content of M/S encoding. Still open to anyone offering corrections or clarifications. Heck, if you don't understand something, I'd like to see if I can make it more clear, because that'll probably make it more clear to myself.

Last edited by ScuzzyEye; 06-15-2023 at 04:55 AM. Reason: Corrections to initially bad calculations.
ScuzzyEye is offline   Reply With Quote
Old 06-14-2023, 01:23 PM   #2
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

As noted I've made some substantial edits to my post above.

My motivation for trying to figure out the angles where the harmonics are focused is to be able to map them to Atmos panning locations to make a sort of Ambisonics to Atmos converter. Not for a full mix, I think if you're using Atmos, you should still pan objects there. But for things like Ambisonic recordings, or other instruments or effects that output full spherical audio in an Ambisonic format.

I knew that there was a direct A-Format match for 1st Order. O1A can be encoded with 4 channels of audio, and the decoded A-Format expands that requirement to 6. Blue Ripple makes an O3A to A20 (20 "nodes") converter, that uses the vertices of a dodecahedron to equally space those points around a sphere. I was 1) wondering if 20 channels were enough for O3A, and 2) how to calculate the positions of other orders.

Last edited by ScuzzyEye; 06-15-2023 at 05:06 AM.
ScuzzyEye is offline   Reply With Quote
Old 06-15-2023, 05:36 AM   #3
Kewl
Human being with feelings
 
Join Date: Jan 2009
Location: Montreal, Canada
Posts: 172
Default

I'm sorry, but your way of interpreting Ambisonics and spherical harmonics is wrong.

Yes, as we go up orders we gain spatial resolution, but we gain that spatial resolution all over the sphere, not just "where the harmonics are focused".

And if we are talking about the angular difference of horizontal spherical harmonics of the same order:

O1A : 90°
O2A : 45°
O3A : 30°
O4A : 22.5°
O5A : 18°
O6A : 15°
O7A : 12.86°
O8A : 11.25°
O9A : 10°
O10A : 9°

Last edited by Kewl; 06-20-2023 at 02:42 AM.
Kewl is offline   Reply With Quote
Old 06-15-2023, 05:39 AM   #4
Kewl
Human being with feelings
 
Join Date: Jan 2009
Location: Montreal, Canada
Posts: 172
Default

Ah, I see that you edited your initial post.
Kewl is offline   Reply With Quote
Old 06-15-2023, 07:11 AM   #5
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Quote:
Originally Posted by Kewl View Post
Ah, I see that you edited your initial post.
Yes, again. But thanks much, for confirming my current conclusion. It's really difficult to find (non-quantum physics) documentation on spherical harmonics. And if you have anything else to add, please do.
ScuzzyEye is offline   Reply With Quote
Old 06-15-2023, 07:25 AM   #6
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Quote:
Originally Posted by Kewl View Post
Yes, as we go up orders we gain spatial resolution, but we gain that spatial resolution all over the sphere, not just "where the harmonics are focused".
Maybe I should be more clear about my actual goals for figuring this out.

If you take 6 unidirectional inputs, you can encode them as 4 signals (W, X, Z, Y) in an Ambisonic configuration, and the decode that back to 6 outputs. The inputs and outputs should be identical.

Is that possible with higher order Ambisonics? If so, how do you calculate the azimuth and elevation of those inputs, and how many are required? I know with more than required you can get a good representation of the overall spherical audio, but the output might not match the input exactly.

In it's simplest form: If I have an instrument or effect that produces an Ambisonics output, and I want to best represent that in Atmos. How many channels will I need, and where do I put them?
ScuzzyEye is offline   Reply With Quote
Old 06-15-2023, 08:34 AM   #7
plush2
Human being with feelings
 
Join Date: May 2006
Location: Saskatoon, Canada
Posts: 2,115
Default

Quote:
Originally Posted by ScuzzyEye View Post
Maybe I should be more clear about my actual goals for figuring this out.

If you take 6 unidirectional inputs, you can encode them as 4 signals (W, X, Z, Y) in an Ambisonic configuration, and the decode that back to 6 outputs. The inputs and outputs should be identical.

Is that possible with higher order Ambisonics? If so, how do you calculate the azimuth and elevation of those inputs, and how many are required? I know with more than required you can get a good representation of the overall spherical audio, but the output might not match the input exactly.

In it's simplest form: If I have an instrument or effect that produces an Ambisonics output, and I want to best represent that in Atmos. How many channels will I need, and where do I put them?
I always hate it when people answer a question with a question so, apologies. Why do you want to achieve discrete sources from ambisonics anyways? I can understand the mathematical satisfaction of creating something in spherical harmonics and reducing it to cartesian points. One of the largest advantages of ambisonics is all that intermediary stuff, which is very difficult to achieve using an object based panning. Why not just use cartesian (vbap, dbap, whatever) to place those 6 sources rather than running them through the realm of ambisonics on the way? If the goal is to get a greater understanding of ambisonics at higher orders then I am definitely along for the ride and will follow up.
plush2 is offline   Reply With Quote
Old 06-15-2023, 09:11 AM   #8
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

I definitely want a better understanding of Ambisonics, but that's my personality, I want a better understanding of everything.

For this particular goal. I've been experimenting with low order Ambisonics for general stereo mixing (discarding the height, and mixing the depth in with a 90° phase shift, basically UHJ encoding) and really liking the results.

The reason for exporting stereo, is that's basically the only guaranteed-to-work everywhere distribution format. But recently Atmos has gotten popular enough, and tools are available that anyone who puts in a little effort can release music in Atmos too. Distribution for anyone to be able to play back Ambisonics still doesn't seem to be happening (fingers crossed for YouTube Music).

For Atmos I'll pan the discrete audio sources as objects. But I have some instruments, effects, and recordings that natively (or nearly) produce Ambisonics. The 6-to-4-to-6 example was slightly contrived, in that I wouldn't actually do that, but more of an acknowledgement that it's possible to achieve a 1:1 input/output in 1st Order. My real thought was, if I have something that's natively in 1st Order, if I output it as Atmos objects at those 6 positions, I should have a pretty good Cartesian reproduction of that sound field. Then it followed: Is it possible to achieve the same at higher orders?
ScuzzyEye is offline   Reply With Quote
Old 06-19-2023, 10:17 AM   #9
plush2
Human being with feelings
 
Join Date: May 2006
Location: Saskatoon, Canada
Posts: 2,115
Default

So here is the thing I wanted to suggest, rather than decomposition to the axial modes of first order you could just flip back into a-format. They have a-format outlined for some of the higher orders as well. They are not uniform layouts (front-back, left-right) but they do perfectly represent the ambisonic order they correspond with and are actual positions in cartesian space.
plush2 is offline   Reply With Quote
Old 06-19-2023, 12:05 PM   #10
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Yeah, that would work. As long as there's a uniform distribution of energy, that makes use of the resolution of what ever order I've selected.

Blue Ripple has O3A to A-20 to O3A utilities. 16 channels of Ambisonics to 20 channels in A-format seems like it's pretty close to preserving all the detail. They gave Cartesian coordinates for the 20 vertices in their documentation. I did the math to convert them into azimuth and elevation and set them up in IEM's AllRADecoder. The calculated energy distribution also looks very good at O3A.

This weekend I picked up Fiedler's Spacelab Interstellar. It supports a 32-channel Full Sphere input/output mode. The angles of each channel are listed in the plug-in, so I entered them in the AllRADecoder decoder too. It shows pretty even distribution at O4A. So 25-channels of Ambisonics covered by 32 "speakers" also seems about right. Going to O5A looks a little "splotchy", and O6A starts showing obvious gaps.

You say "they" have A-format layouts for higher orders. Who's they? That's probably what I've been looking for.
ScuzzyEye is offline   Reply With Quote
Old 06-19-2023, 01:59 PM   #11
plush2
Human being with feelings
 
Join Date: May 2006
Location: Saskatoon, Canada
Posts: 2,115
Default

Quote:
Originally Posted by ScuzzyEye View Post
Blue Ripple has O3A to A-20 to O3A utilities. 16 channels of Ambisonics to 20 channels in A-format seems like it's pretty close to preserving all the detail. They gave Cartesian coordinates for the 20 vertices in their documentation. I did the math to convert them into azimuth and elevation and set them up in IEM's AllRADecoder. The calculated energy distribution also looks very good at O3A.
Would you mind sharing that AllRaDecoder config file?

Quote:
You say "they" have A-format layouts for higher orders. Who's they? That's probably what I've been looking for.
Haha, you got me there. Probably your best source would be to look at the SPS documentation by Angelo Farina (http://www.angelofarina.it/SPS-conversion.htm) or to reverse engineer the shape/coordinates of one of the higher order mics (eigen, etc.). Only the soundfield mics AFAIK were true b-format mics, all since have been a-format which means a composite W channel and evenly distributed capsules on a sphere. Please go easy on me. We are essentially learning together so assume I may be wrong about some of this.
plush2 is offline   Reply With Quote
Old 06-19-2023, 05:23 PM   #12
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Sure, here's the A20 config file that can be loaded into AllRAD. Just save it as a .json file. In this one I've added 12 additional imaginary speakers to the middle of each of the 12 faces of the dodecahedron. This triangulates each pentagon into 5 equilateral triangles. Without it AllRAD seems to randomly split them into 3. Having the imaginary speakers also seems to make the energy distribution more smooth (you can removed them and recalculate to see the difference). You'll need to calculate the decoder for what ever order you want (I'd recommend 3rd) and re-save the whole thing, or just the decoder if you want to use it with SimpleDecoder. The layout does work as-is in MultiEncoder.

The channel order follows what's referenced here:
http://www.blueripplesound.com/plugi...ba20_converter
(I made the channel 13 -180° instead of just 180 because that also made for a smoother distribution--at least in the display.)

Code:
{
  "Name": "All-Round Ambisonic decoder (AllRAD) and loudspeaker layout",
  "Description": "This configuration file was created with the IEM AllRADecoder v0.9.4 plug-in. 4 Jun 2023 3:32:53pm",
  "LoudspeakerLayout": {
    "Name": "A loudspeaker layout",
    "Loudspeakers": [
      {
        "Azimuth": 90.0,
        "Elevation": 69.09484100341797,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 1,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": 69.09484100341797,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 2,
        "Gain": 1.0
      },
      {
        "Azimuth": 135.0,
        "Elevation": 35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 3,
        "Gain": 1.0
      },
      {
        "Azimuth": 45.0,
        "Elevation": 35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 4,
        "Gain": 1.0
      },
      {
        "Azimuth": -45.0,
        "Elevation": 35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 5,
        "Gain": 1.0
      },
      {
        "Azimuth": -135.0,
        "Elevation": 35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 6,
        "Gain": 1.0
      },
      {
        "Azimuth": 180.0,
        "Elevation": 20.9051570892334,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 7,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": 20.9051570892334,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 8,
        "Gain": 1.0
      },
      {
        "Azimuth": 110.905158996582,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 9,
        "Gain": 1.0
      },
      {
        "Azimuth": 69.09484100341797,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 10,
        "Gain": 1.0
      },
      {
        "Azimuth": -69.09484100341797,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 11,
        "Gain": 1.0
      },
      {
        "Azimuth": -110.905158996582,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 12,
        "Gain": 1.0
      },
      {
        "Azimuth": -180.0,
        "Elevation": -20.9051570892334,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 13,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -20.9051570892334,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 14,
        "Gain": 1.0
      },
      {
        "Azimuth": 135.0,
        "Elevation": -35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 15,
        "Gain": 1.0
      },
      {
        "Azimuth": 45.0,
        "Elevation": -35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 16,
        "Gain": 1.0
      },
      {
        "Azimuth": -45.0,
        "Elevation": -35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 17,
        "Gain": 1.0
      },
      {
        "Azimuth": -135.0,
        "Elevation": -35.26438903808594,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 18,
        "Gain": 1.0
      },
      {
        "Azimuth": 90.0,
        "Elevation": -69.09484100341797,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 19,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": -69.09484100341797,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 20,
        "Gain": 1.0
      },
      {
        "Azimuth": 180.0,
        "Elevation": 58.28250122070312,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 21,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": 58.28250122070312,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 22,
        "Gain": 1.0
      },
      {
        "Azimuth": 148.2830047607422,
        "Elevation": 0.0,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 23,
        "Gain": 1.0
      },
      {
        "Azimuth": 31.71750068664551,
        "Elevation": 0.0,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 24,
        "Gain": 1.0
      },
      {
        "Azimuth": -31.71750068664551,
        "Elevation": 0.0,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 25,
        "Gain": 1.0
      },
      {
        "Azimuth": -148.2830047607422,
        "Elevation": 0.0,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 26,
        "Gain": 1.0
      },
      {
        "Azimuth": 90.0,
        "Elevation": 31.71750068664551,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 27,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": 31.71750068664551,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 28,
        "Gain": 1.0
      },
      {
        "Azimuth": 90.0,
        "Elevation": -31.71750068664551,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 29,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": -31.71750068664551,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 30,
        "Gain": 1.0
      },
      {
        "Azimuth": -180.0,
        "Elevation": -58.28250122070312,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 31,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -58.28250122070312,
        "Radius": 0.8080000281333923,
        "IsImaginary": true,
        "Channel": 32,
        "Gain": 1.0
      }
    ]
  }
}
ScuzzyEye is offline   Reply With Quote
Old 06-19-2023, 10:14 PM   #13
Dannii
Human being with feelings
 
Dannii's Avatar
 
Join Date: Mar 2010
Location: Adelaide, South Australia (originally from Geelong)
Posts: 5,598
Default

Very interesting discussion this one. I'll have to have a better read but is the aim here to produce Atmos output from Ambisonics complete with object based panning?

I'm a big fan of both Blue Ripple and IEM. Blue Ripple have a decoder for Atmos beds but no object based output.
__________________
Dannii is offline   Reply With Quote
Old 06-20-2023, 04:47 AM   #14
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Quote:
Originally Posted by Dannii View Post
Very interesting discussion this one. I'll have to have a better read but is the aim here to produce Atmos output from Ambisonics complete with object based panning?
It depends on what you're willing to accept as "Atmos". If a very large "bed" is OK, then what I'm looking at here will accomplish that. But actual objects will still have to be panned by an Atmos panner.

The idea is: If I have something that is natively Ambisonics, especially higher order. Would it be possible to decode it to enough virtual speakers as precisely placed Atmos objects to allow for convincing 360° playback?

I think mono/stereo channels are still better directly encoded into Atmos and panned there. But but if I'm working with a sound field, I'd like to keep as much of that signal intact too.
ScuzzyEye is offline   Reply With Quote
Old 07-19-2023, 02:36 PM   #15
Joystick
Human being with feelings
 
Joystick's Avatar
 
Join Date: Jul 2008
Location: Athens / Greece
Posts: 627
Default

Any simplification for understanding ambisonics would be a good step towards popularizing this format. I'm all in for that.

I don't know if it's of any help, but some time ago I captured screenshots of each channel up to the 64th, using noise and the IEM EnergyVisualizer.

Here's a link to my OneDrive with the screenshots: https://1drv.ms/f/s!AoFZ1MP3ewRgguEB...7YqAg?e=ldxDqL

Cheers!
__________________
Pan Athen
SoundFellas Creative Audio Studios www.soundfellas.com
Creator of Echotopia www.soundfellas.com/software/echotopia
Joystick is offline   Reply With Quote
Old 07-20-2023, 08:41 AM   #16
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Before I clicked the link, I was trying to guess what that would look like. I figured it would be the typical spherical harmonic energy plot. https://en.wikipedia.org/wiki/File:C...Polar_Plot.gif

I was right, but that's good, shows that over these months and months of research I'm actually learning something. It is a good example of what I'm trying to do. I'd like to place a "speaker" at each of hottest focus points so that I could map those to Atmos objects, or just channels for non-Ambisonic processing. The problem is, Ambisonics does such a good job of encoding spatial information in a (relatively) small number of channels. That when you want to expand something like even 5th order to speakers you need a whole lot more channels.

I have the 3rd order to 20 speakers, and a 4th order to 32 speakers working pretty well. Good, even coverage. Listening after encoding to Atmos and then back to a 7.1.4 system or binaural sounds nice. Not exactly ready to share my 32 speaker decoding yet, but close.
ScuzzyEye is offline   Reply With Quote
Old 07-21-2023, 11:26 AM   #17
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Actually, if anyone wants to weigh in on what's hanging me up with the 32 point layout...

So, the highest number of equally spaced points one can have around a sphere is 20. The vertices of a dodecahedron. This is what Blue Ripple used, and the points I shared above. Everything higher than will be an approximation, because pi and all that irrational stuff. You can get down to a few decimals of variance, but the dodecahedron is the highest exact division of a sphere.

To get 32 points, you take the 12, pentagon faces of the dodecahedron, and place a point in the middle of them. (The same triangulation I did in the .json I shared, but make them real speakers instead of imaginary.) These points also happen to be vertices of the next higher Platonic solid, the 20-faced icosahedron (D20 to D&D fans). This is also how geodesic spheres are made: triangulate and/or sub-divide the faces of a Platonic solid, and push those new points out to the diameter of the sphere. Repeat until you get the density you want. But that "pushing the points out to the sphere" makes their connecting lines longer than the other sides of the 2D shape. If you go to buy a geodesic dome construction set you’ll see that there are multiple different lengths of bars that go into the triangles, they’re not equilateral.

That finally brings me to what I’m questioning. Finding 32 points by combining the dodecahedron and icosahedron is simple. It’s close to right too. But extending that system above 32 points requires turning each triangle into 4 triangles (subdivision), and that triples the number of points. There’s no small step up. There is another method of (nearly) equally spacing points around a sphere based on the Fibonacci lattice (aka Golden Spiral). That allows any number of points to be calculated. Seems nice, but it throws out the Platonic solids that line up perfectly for 4, 6, 8, 12, and 20 points.

Yet another data point that’s tangled me up. Fiedler’s Spacelab includes a 32 speaker layout. It’s indeed the triangulated dodecahedron, but with a slightly different rotation than what I get when I triangulate Blue Ripple’s layout. One nice thing about this though, is Fielder has a precedent of breaking “standard” speaker layouts (e.g. 5.1 or 7.1.4) for better binaural decoding, and includes an alternative folder of presets just for that use. I have a feeling if I came up with a good set of Ambisonic optimized virtual speaker layouts for Spacelab, Thomas would bundle them with the plug-in. Including the alternative rotation of the “full sphere 32 speaker” preset. Regardless, they’re XML files, and I’d post them here too. (Does anyone else have Spacelab Interstellar?) But before I would send anything for inclusion I’d have to make sure I’m really happy with the layout and have a good justification for where the speakers are located. (I’d make a matching set of IEM decoder .json files too.)

I’m mostly thinking out loud here. Hoping that something I say shakes a good idea loose, but am definitely open to anyone else’s thoughts on the subject. The one idea that I keep coming back to, which is the same one that I had when I started this thread, is that spherical harmonics do sub-divide a sphere, and if they describe more than 20 positions (and higher orders do), there must be some other acceptable spacing that isn’t completely equidistant. I probably should read that AllRAD paper too, because that algorithm seems to be able to compensate for unequal spacings, and it would be good to understand its limitations.
ScuzzyEye is offline   Reply With Quote
Old 07-21-2023, 04:34 PM   #18
Joystick
Human being with feelings
 
Joystick's Avatar
 
Join Date: Jul 2008
Location: Athens / Greece
Posts: 627
Default

The 32 points, as you describe them, make sense to me too. Also, I think this arrangement would cover most cases in film or music audio production. I already use HOA to produce for film and export Dolby Atmos beds, but for the C and LFE channels, I use direct channel-based panners that I route to the render output, so I don't distribute dialog and LFE to the rest of the discrete channels.

The conversion to channel-based that you propose would also be nice for game audio, as many developers struggle with ambisonic spatializers. The support is not good and the tools are open-source and badly maintained, except for the excellent native implementation that was done for ambisonics in Unreal Engine. Unity has big issues with that. So a conversion to a channel-based format for layers that represent the ambience or music, that would be played back from virtual speakers that follow the player character, is something that seasoned sound designers do.

For experiences that don't need head locking and the audience consumes a static sphere, you might want to think of not using the channels in an equal distribution. Using more channels for the horizontal plane, and fewer channels for the top or bottom (if the bottom is needed) is a resource management logic that serves the way we hear and the way we distribute our speakers very well.
__________________
Pan Athen
SoundFellas Creative Audio Studios www.soundfellas.com
Creator of Echotopia www.soundfellas.com/software/echotopia
Joystick is offline   Reply With Quote
Old 07-23-2023, 03:40 PM   #19
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

Been reading technical documentation this weekend. Found something buried in Dolby's description of the actual stream that is delivered for playback on music services (this doesn't apply to UHD Blu-ray, or TrueHD Atmos streaming).

A thought had been sticking in the back of my head this whole time. I was wondering if chasing these higher resolution point decodings of Ambisonics for use in Atmos would have any problems. I knew that Atmos uses a Joint Object Coding, which was taken from MP3's Joint Stereo Coding. Which is to say it tries to find similarities between audio streams (objects for Atmos, channels for MP3), and only stores the differences from the sum (think mid/side for stereo). I knew that. What was bothering me is, what if I took 118 points from decoded Ambisonics, with little correlation between them, wouldn't that take a lot of bandwidth? And what happens if you deliver an ADM, that when streamed, is too big?

Well, the bombshell I found today is that Atmos for streaming music really is only 16 "elements". You only get at most 16 discrete positions in the whole sound field. If you have sound originating from more than 16 different points in space, there is an algorithm in the streaming encoder that groups them together. It takes into account amplitude and frequency, and of course actual location, and does some psychoacoustic modeling to join objects together to get the count down to 16 or less. It then moves those 16 elements to the average position based on the model. As the inputs to the model change, the compositions of objects and their playback position are adjusted.

So there's the hitch, at least for Atmos music production, which is where I'm focusing my energy. A higher number of virtual speakers for Ambisonics decoding will likely present a worse playback image than fewer. At least if there's many more than 16 active at any time. The idea of incorporating dense atmospheric "beds" created as Ambisonics, and then placing mono elements on top of that as a style of production will need a little re-thinking.

I have a 2nd Order to 12-point icosahedron decoder I've already made. That might be better suited to using with Atmos. Or at most the upper hemispheres of the 20- and 32-point layouts The latter, if you're not planning on including any discrete objects. Or as Joystick was just saying, decoding the Ambisonics into more traditional speaker location beds (which really is the intended use for IEM's Simple Decoder).

Anyway, something else for me to incorporate into my designs and testing.

Edited Note: I just found one additional caveat, this doesn't apply to Tidal and Amazon Music on Android devices that support Atmos (basically just Samsung). They use a 2-channel stream (IMS - Immersive Stereo Codec) built from the ADM that doesn't have the 16-element limit, but it's only for 2-channel playback anyway.

Last edited by ScuzzyEye; 07-23-2023 at 05:32 PM. Reason: Note about IMS
ScuzzyEye is offline   Reply With Quote
Old 07-23-2023, 07:21 PM   #20
Joystick
Human being with feelings
 
Joystick's Avatar
 
Join Date: Jul 2008
Location: Athens / Greece
Posts: 627
Default

Ahhh, yes, I forgot to mention the simplification that happens for domestic use. It makes sense as they need to keep computing resources demand low for those systems.

Well, in general, Dolby Atmos is an ok format for use in big cinema theaters for audio material that is made for front-screen media (films, etc.). Dolby's effort to market the Atmos format for use in music and other entertainment media is justified from a commercial point of view, but not so much from a technical point of view.

Object-based audio borrows some nice concepts from the interactive audio sector (games, virtual instruments, etc.), like the use of a bed and individual moving sources, but it fails to support a logical audio production pipeline that includes the use of group processing, summing and sub-summing, a reverberation signal that accurately follows the sources, and master bus processing.

It's up to the artists/creators to choose if Dolby Atmos is a good option for them, by justifying the need for a commercial seal of approval in their design intent.

You also mentioned "density", which is a very interesting element of audio design. In my work on soundscape design and production, I discovered that density is mostly derived from aesthetics, contrast, and the use of sounds that the audience is trained in real life to perceive as dense phenomena in nature. I know that you mentioned density as part of the number of audio streams, I'm just mentioning this because audio can be immersive even in mono.

I find your experiments exciting and I walk a similar path :-)
__________________
Pan Athen
SoundFellas Creative Audio Studios www.soundfellas.com
Creator of Echotopia www.soundfellas.com/software/echotopia
Joystick is offline   Reply With Quote
Old 05-06-2024, 04:23 PM   #21
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

I never did follow up on these. Here's the 12-pointed Icosahedron, to go along with the 20-pointed dodecahedron I posted before. While I had Blue Ripple's ordering for their A20 layout, I just took my best guess and used what made sense to me for this "A12".

Code:
{
  "Name": "All-Round Ambisonic decoder (AllRAD) and loudspeaker layout",
  "Description": "This configuration file was created with the IEM AllRADecoder v0.9.4 plug-in. 29 May 2023 7:51:53pm",
  "LoudspeakerLayout": {
    "Name": "A loudspeaker layout",
    "Loudspeakers": [
      {
        "Azimuth": 180.0,
        "Elevation": 58.28252410888672,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 1,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": 58.28252410888672,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 2,
        "Gain": 1.0
      },
      {
        "Azimuth": 148.2825317382812,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 3,
        "Gain": 1.0
      },
      {
        "Azimuth": 31.71747398376465,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 4,
        "Gain": 1.0
      },
      {
        "Azimuth": -31.71747398376465,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 5,
        "Gain": 1.0
      },
      {
        "Azimuth": -148.2825317382812,
        "Elevation": 0.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 6,
        "Gain": 1.0
      },
      {
        "Azimuth": 90.0,
        "Elevation": 31.71747398376465,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 7,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": 31.71747398376465,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 8,
        "Gain": 1.0
      },
      {
        "Azimuth": 90.0,
        "Elevation": -31.71747398376465,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 9,
        "Gain": 1.0
      },
      {
        "Azimuth": -90.0,
        "Elevation": -31.71747398376465,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 10,
        "Gain": 1.0
      },
      {
        "Azimuth": -180.0,
        "Elevation": -58.28252410888672,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 11,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -58.28252410888672,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 12,
        "Gain": 1.0
      }
    ]
  }
}
ScuzzyEye is offline   Reply With Quote
Old 05-06-2024, 04:28 PM   #22
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

I also mentioned an "A32" layout. This one matches the default 32 speaker "Full Sphere" layout from Fiedler Audio's Spacelab. While not exactly Atmos friendly, it makes for some very convincing sounding spaces when piping Ambisonics into that particular reverb. You can then output it into smaller "bed" for Atmos playback. Matching channel ordering to Spacelab means that even though this is a combination of the vertices of the icosahedron and dodecahedron, they are in a different order.

Code:
{
  "Name": "All-Round Ambisonic decoder (AllRAD) and loudspeaker layout",
  "Description": "This configuration file was created with the IEM AllRADecoder v0.9.4 plug-in. 17 Jun 2023 8:00:05pm",
  "LoudspeakerLayout": {
    "Name": "A loudspeaker layout",
    "Loudspeakers": [
      {
        "Azimuth": 0.0,
        "Elevation": 90.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 1,
        "Gain": 1.0
      },
      {
        "Azimuth": 180.0,
        "Elevation": 53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 2,
        "Gain": 1.0
      },
      {
        "Azimuth": 108.0,
        "Elevation": 53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 3,
        "Gain": 1.0
      },
      {
        "Azimuth": 36.0,
        "Elevation": 53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 4,
        "Gain": 1.0
      },
      {
        "Azimuth": -36.0,
        "Elevation": 53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 5,
        "Gain": 1.0
      },
      {
        "Azimuth": -108.0,
        "Elevation": 53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 6,
        "Gain": 1.0
      },
      {
        "Azimuth": 144.0,
        "Elevation": 27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 7,
        "Gain": 1.0
      },
      {
        "Azimuth": 72.0,
        "Elevation": 27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 8,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": 27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 9,
        "Gain": 1.0
      },
      {
        "Azimuth": -72.0,
        "Elevation": 27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 10,
        "Gain": 1.0
      },
      {
        "Azimuth": -144.0,
        "Elevation": 27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 11,
        "Gain": 1.0
      },
      {
        "Azimuth": 180.0,
        "Elevation": 11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 12,
        "Gain": 1.0
      },
      {
        "Azimuth": 108.0,
        "Elevation": 11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 13,
        "Gain": 1.0
      },
      {
        "Azimuth": 36.0,
        "Elevation": 11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 14,
        "Gain": 1.0
      },
      {
        "Azimuth": -36.0,
        "Elevation": 11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 15,
        "Gain": 1.0
      },
      {
        "Azimuth": -108.0,
        "Elevation": 11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 16,
        "Gain": 1.0
      },
      {
        "Azimuth": 144.0,
        "Elevation": -11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 17,
        "Gain": 1.0
      },
      {
        "Azimuth": 72.0,
        "Elevation": -11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 18,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 19,
        "Gain": 1.0
      },
      {
        "Azimuth": -72.0,
        "Elevation": -11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 20,
        "Gain": 1.0
      },
      {
        "Azimuth": -144.0,
        "Elevation": -11.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 21,
        "Gain": 1.0
      },
      {
        "Azimuth": 180.0,
        "Elevation": -27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 22,
        "Gain": 1.0
      },
      {
        "Azimuth": 108.0,
        "Elevation": -27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 23,
        "Gain": 1.0
      },
      {
        "Azimuth": 36.0,
        "Elevation": -27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 24,
        "Gain": 1.0
      },
      {
        "Azimuth": -36.0,
        "Elevation": -27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 25,
        "Gain": 1.0
      },
      {
        "Azimuth": -108.0,
        "Elevation": -27.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 26,
        "Gain": 1.0
      },
      {
        "Azimuth": 144.0,
        "Elevation": -53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 27,
        "Gain": 1.0
      },
      {
        "Azimuth": 72.0,
        "Elevation": -53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 28,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 29,
        "Gain": 1.0
      },
      {
        "Azimuth": -72.0,
        "Elevation": -53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 30,
        "Gain": 1.0
      },
      {
        "Azimuth": -144.0,
        "Elevation": -53.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 31,
        "Gain": 1.0
      },
      {
        "Azimuth": 0.0,
        "Elevation": -90.0,
        "Radius": 1.0,
        "IsImaginary": false,
        "Channel": 32,
        "Gain": 1.0
      }
    ]
  }
}
ScuzzyEye is offline   Reply With Quote
Old 05-06-2024, 11:03 PM   #23
Joystick
Human being with feelings
 
Joystick's Avatar
 
Join Date: Jul 2008
Location: Athens / Greece
Posts: 627
Default

Those are very useful; thank you for sharing!

I was reading about t-design methods to see if I could make a script that calculates near-perfect equidistant points on a sphere. One proposed method uses the Fibonacci lattice formulas you mentioned above.

My next step is to read the All-Round Ambisonics Panning paper (F. Zotter, M. Frank) again to understand the logic behind the choice of limits and algorithms in the t-design method they used before the VBAP module in the AllRADecoder.

In the past 2 years, we made a lot of critical listening tests at SoundFellas to update our 3D mixing pipeline, and we concluded that a little randomization is a good thing for the final holophonic experience. If you think about it, compositing a sound field using ambisonics is like compositing a CGI scene for use in a movie; you don't want it to be computer-perfect; it needs Wabi-sabi. That's why I believe t-design patterns are even better than precise points around a sphere.

For example, when we create the ambience loops offered in our Ambience Kit sound libraries, we never use perfect round numbers. This philosophy works well when you experience a virtual sound field in VR or games and even better when you feed the signal to a reverb.

Unless I misunderstood the All-Round Ambisonic pipeline and what we're discussing here, I think an extra button that generates a t-design speaker layout according to the decoder order setting would be a nice feature for the AllRADecoder.Together with the respective configuration on the MultiEncoder, they would make an excellent workflow for using traditional effects in an ambisonic pipeline.

I don't know if my hypothesis is correct, but I created an issue on the IEM Suite tracker anyway: https://git.iem.at/audioplugins/IEMP...e/-/issues/203
__________________
Pan Athen
SoundFellas Creative Audio Studios www.soundfellas.com
Creator of Echotopia www.soundfellas.com/software/echotopia
Joystick is offline   Reply With Quote
Old 05-07-2024, 05:35 AM   #24
ScuzzyEye
Human being with feelings
 
ScuzzyEye's Avatar
 
Join Date: Apr 2021
Posts: 579
Default

One reason I didn't follow up is that what I made up to this point works "good enough". I have a couple other projects I'm researching (most related to spatial/immersive audio, all related to exchanging information between formats), and they've occupied my time since.

There are two sort of competing ideas in my head about encoding/decoding Ambisonics. Basically Ambisonics is a method of using sum and differences between signals to encode more precise positioning information in fewer channels then would be required with individual point sources. See the 1st order 4 Ambisonics channels encoding 6 point sources.

There are definite solutions to the point of maximum energy concentration for each increase in spherical harmonics. A "best point" in each harmonic, if you will. These increase with the cube of the order. So my idea about geodesic triangulation wasn't far off. I never got down to writing the code to actually do the math for me. (See "good enough" above.) Also the limitations of consumer Atmos playback put a damper on chasing higher object numbers.

Anyway, the two ideas: All-Round Ambisonics is designed to best encode or decode an Ambisonics sound field when you know the positions of the inputs or outputs (mics or speakers). And yes, it probably works better with a little dithering added to the positions. This is because your mics or speakers aren't going to exactly line up with the highest energy points in the harmonics. So the trade off is to figure out how to best distribute the energy into or out of the field.
The other idea that I was actually chasing, but using AllRA because that was the only "hammer" I had is that it's possible to encode/decode the higher harmonics directly using only sums and differences of the orders below. The signals for the points of highest energy just fall out. The work I didn't do was to figure out where the spherical coordinates of these points are located. I was chasing Platonic solids, because they felt nice, but ultimately don't actually line up with the harmonics. They simply get you equally spaced points that work well with AllRa (in a mathematical sense, not in a real world sense).

Will I come back and actually figure out the math to calculate the coordinates for any order of Ambisonics and make a harmonic M/S encoder/decoder? Probably. It's the kind of thing that just itches in my brain. But right now I'm neck deep in reading/writing: XML schema, PCM streams, and VST3 presets.
ScuzzyEye is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 04:58 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.