spaudiopy icon indicating copy to clipboard operation
spaudiopy copied to clipboard

adds in-phase weights

Open BenjSta opened this issue 3 years ago • 5 comments

Dear Chris,

I recently used spaudiopy in an artistic visualization project, and I found the in-phase weighting (no sidelobes) useful for visualizing spatial energy. It might also be useful for directivity shaping and experimental audio decoding. Do you consider it worth integrating into spaudiopy?

Best, Benjamin Stahl IEM Graz, Austria

BenjSta avatar Jan 12 '22 16:01 BenjSta

Hi Benjamin, Thanks for your contribution! In fact, you discovered a bug. The in-phase weighting should be equivalent with a higher-order cardioid weighting, defined in https://github.com/chris-hld/spaudiopy/blob/e463859c24072a749e01d952a60b1b11196bcb79/spaudiopy/sph.py#L828 However, it seems there is a +1 missing in one of the factorials...

chris-hld avatar Jan 13 '22 13:01 chris-hld

I would propose to merge your PR, and to base cardioid_modal_weights on the in-phase weighting coefficients, normalised for unit amplitude in steering direction (the 4pi factor). Is that ok with you?

chris-hld avatar Jan 13 '22 13:01 chris-hld

Dear Chris,

sorry I haven't found cardioid_modal_weights before submitting the PR, I didn't know the weighting under this name. Your solution sounds perfect!

Best regards, Benjamin

BenjSta avatar Jan 14 '22 12:01 BenjSta

Hey Benjamin, So it seems they are in fact not completely equivalent, but still have the same pattern. Let me explain:

  • Let's assume we define a cardioid pattern in space as (0.5 + (1-0.5) * np.cos(phi))**N, which is an higher order extension of the standard cardioid pattern definition.

  • let's then compare the current cardioid_modal_weights image The solid line is the defined cardioid pattern, the dashed line the output that the modal weighting produces in space. So they do perfectly agree.

  • Now let's look at the in-phase weighting: image Hm, not the same, but it seems like mostly a level offset. Unfortunately it is not just 4pi, as I thought by just looking at the implementation. But when I normalise the pattern in steering direction (e.g. with spa.sph.unity_gain(w_n)), then they become equivalent again! image

So it seems the only difference between the two is the level normalisation. With the factorial rule (n+1)! = (n+1)n!, and the missing 4pi, the two become equivalent with cardioid_weights = 4pi*in_phase_weights/(N+1)

I don't see any problem in adding the in-phase-weights, but I think we should somehow highlight that these are basically an unnormalised cardioid pattern (in my opinion). What do you think?

chris-hld avatar Jan 21 '22 08:01 chris-hld

Dear Chris, so there hasn't been a bug in the cardioid modal weights implementation! I would still add the unnormalized version and base the normalized version on it (so cardioid_modal_weights relates to in_phase_weights like maxre_modal_weights relates to max_rE_weights. I also think the documentation should point out that the in-phase weights, when applied to a (bandlimited) dirac, yield an unnormalized cardioid pattern.

Best regards, Benjamin

BenjSta avatar Jan 25 '22 10:01 BenjSta

Closing in favor of https://github.com/chris-hld/spaudiopy/commit/1ad2f796aa28c1d1b97d24408fbf510cd269b0d6

chris-hld avatar Jan 12 '23 16:01 chris-hld