Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of the panning #665

Closed
theGreatWhiteShark opened this issue Oct 14, 2018 · 19 comments
Closed

Implementation of the panning #665

theGreatWhiteShark opened this issue Oct 14, 2018 · 19 comments
Labels

Comments

@theGreatWhiteShark
Copy link
Contributor

I have a quite general question about the implementation of the panning.

In Hydrogen the panning is realized by introducing one volume for the right channel pan_R and one for the left pan_L, with both of them ranging from 0 to 0.5. If the sound is positioned in the center, both of them are set to 0.5 and if the source moves in either direction, the volume of the opposite channel is reduced.

But in this way the loudness of a sample depends on its location. It is the loudest in the middle and the quietest at either far right or far left. Wouldn't it make more sense to have it at the same level all the time? After all we are adjusting the panning and not the distance. This could be done by keeping the total level of a sample constant for all pannings and expressing it as a combination of the volumes of the two channels. Depending on how they are added, like a 1 = pan_R + pan_L or 1 = sqrt( pan_R^2 + pan_R^2), the scaling between perceived location and panning value can be altered. I'm not a hundred percent sure about which one to use, but from intuition I would guess the second one will lead to a linear scaling of the perceived location since ears and loudspeakers do form a plane. But textbooks will tell us.

@quasart
Copy link
Contributor

quasart commented Feb 6, 2019

I think there is no optimal curve for this "pan law". Some DAW just provide a parameter to let user choose : https://www.soundonsound.com/sound-advice/q-what-pan-law-setting-should-use

@trebmuh
Copy link
Member

trebmuh commented Mar 28, 2019

FWIW, I've got no particular point of view on this.

@thijz thijz added the question label Mar 19, 2020
@oddtime
Copy link
Contributor

oddtime commented Dec 15, 2020

Yes, I like the idea and could collaborate on it.

For what I've read the optimal parameter depends on the room in which you are hearing, that's why some manufacturers use -4.5dB compensation at center and others -3dB.
https://en.wikipedia.org/wiki/Pan_law
We could add a parameter in preferences for the desired pan law

@theGreatWhiteShark Are you working on it?

@theGreatWhiteShark
Copy link
Contributor Author

We could add a parameter in preferences for the desired pan law

Although I like the idea of giving the user control over internal algorithms, adding a parameter for the pan law is probably a little bit over the top. For proper audio production people will most likely use the JACK per track outputs and some dedicated software mixing and mastering tools and ambisonics incorporating the characteristics of the room. (At least I think so #1027).

But nevertheless some attenuation would seem reasonable. @oddtime you can of course implement it yourself if you want to

@oddtime
Copy link
Contributor

oddtime commented Dec 18, 2020

I am doing personal studies on the matter and I really would like to do some experiments!
So it would not be a problem for me to spend work on it.

Good point #1027

What do you think if we deprecate pan_R and pan_L in Note and Instrument classes and introduce a single pan member?
At the rendering, note would be panned according with the desired pan law.
I suppose that this would make easier different implementations. It would be good in case we decide to have more than one pan law options, the current one and another one for example.
I guess this is how pan properties is saved in daws, because there user can switch pan laws.
It would require additional work but as I said I am up to try it

@oddtime
Copy link
Contributor

oddtime commented Dec 18, 2020

Especially if we want use the Jack per track outputs, one only pan member and a proper (adjustable) pan law is needed at least for the note Pan property automation, while the instrument pan should be decided by the external dedicated software.
In my opinion

@theGreatWhiteShark
Copy link
Contributor Author

It would be good in case we decide to have more than one pan law options, the current one and another one for example.

The panning law could be a static member function of maybe the Sampler or the AudioEngine taking both pan_L and pan_R and returning the weights for the left and right channel. Different pan laws could be different static functions or an input argument choosing the corresponding law.

I haven't looked into the implementation of the panning yet and does not really understand right now why there needs to be both pan properties in the Note and Instrument while both are applied as weights in Sampler::renderNote. I would expect the one in Note supersedes the one in Instrument.

What do you think if we deprecate pan_R and pan_L in Note and Instrument classes and introduce a single pan member?

That will require some extended rewriting in the code base + it will affect all drumkit files. As this will only affect working and internal code with no perceived changes for the users I'm not quite sure whether rewriting the pan implementation is required here

@oddtime
Copy link
Contributor

oddtime commented Dec 19, 2020

does not really understand right now why there needs to be both pan properties in the Note and Instrument

It's because you can use note pan like an automation for the notes and an instrument pan to determine the "stereo extension" of the instrument, but I think that the pan automation should bypass the instrument pan.
note and instrument pan (of the same channel) are simply multiplied in note render (like two gains).

That will require some extended rewriting in the code base + it will affect all drumkit files. As this will only affect working and internal code with no perceived changes for the users I'm not quite sure whether rewriting the pan implementation is required here

Yes I see the problem. Clearly from pan_R and pan_L you can easily get the single scalar parameter pan with an inverse function. The fact is that having two parameter is a waste of information... Also, importing the current two pans to obtain other two different pans is more complex than it is (from the formulas point of view) and the saved L/R pans represent a (new) less intuitive quantity than L/R gains as now. However the user won't notice the difference

@theGreatWhiteShark
Copy link
Contributor Author

It's because you can use note pan like an automation for the notes and an instrument pan to determine the "stereo extension" of the instrument, but I think that the pan automation should bypass the instrument pan.
note and instrument pan (of the same channel) are simply multiplied in note render (like two gains).

Yeah. I sometimes wonder why Hydrogen offers such a general behavior. After all, I would consider a drumkit something static and e.g. the snare not moving positions between individual beats. Anyway. I think it's fine the way it's implemented right now and I added some lines to the doc.

The fact is that having two parameter is a waste of information... Also, importing the current two pans to obtain other two different pans is more complex than it is (from the formulas point of view) and the saved L/R pans represent a (new) less intuitive quantity than L/R gains as now. However the user won't notice the difference

Sure. But deprecating existing parameters stored in the drumkit file is a little more invasive than adding a new ones. Instead of using a default parameter when not existing - as in your pitch offset PR - one needs to regard the drumkits as legacy ones, load them with a different function, and ensure the old pan information will be mapped to the new one. Chances that something breaks in there without noticing are not negligible. But in general you are of course right. It adds unnecessary complexity to have a redundant parameter.

@oddtime
Copy link
Contributor

oddtime commented Dec 22, 2020

Yeah. I sometimes wonder why Hydrogen offers such a general behavior. After all, I would consider a drumkit something static and e.g. the snare not moving positions between individual beats. Anyway. I think it's fine the way it's implemented right now and I added some lines to the doc.

It depends probably if you use Hydrogen only as drum machine or as a general sequencer.
Ps I realized now that past versions had a "drumset/piano" toggle button in the pattern editor panel, which allowed to hear the samples at different pitches with the pc keyboard (qwerty...). I don't know if there was midi input at that time. Do you know why it has been removed?

@oddtime
Copy link
Contributor

oddtime commented Dec 26, 2020

Maybe the new pan member can be introduced without deprecating pan_L and pan_R in both songfiles and classes.
After all there is a computational advantage: saving pan_L and pan_R is good for skipping the pan law computation at every note rendering.
On the other hand the new pan member is good to switch between different pan laws and for skipping the "inverse pan law" computation while updating the pan rotary widgets in mixer.
Current drumkits and songs volumes have been probably mixed by ear, listening to the current ("straight polygonal") pan law, so I think we should maintain the current pan law option, and adding other ones.

@oddtime
Copy link
Contributor

oddtime commented Dec 26, 2020

Another point that should be considered is that the current implementation of panning acts like a "balance" if the sample is dual channel. I.e. it sets just the gains of L/R channels (right?)

I mean: generally dual channel tracks in daws have the option to adjust the pan with a single pan parameter (which I think is like the hydrogen, a "balance") or a pan for each separate channel. In the second way you can really "move" the sample in the stereo space (it may cause loss of volume in the channel if L/R signals are out of phase).

In dual-channel track, sometimes most of the dry sound is in one channel, and changing the balance to the opposite side causes a different effect than actual panning.

Instead, if the sample is mono, the current implementation of pan "moves" the signal in the stereo virtual space without collateral effects.

@oddtime
Copy link
Contributor

oddtime commented Dec 28, 2020

Further considerations about the future possible implementation
While switching pan law, all the pan_L and pan_R members would be rewritten for all instruments and notes, according to their pan members (which remain constant). This seems quite a lot of operations, but if they are skipped they would be performed during every playback.

pan members are not saved in the song, but they are calculated from (pan_L, pan_R) during the drumkit or song import using an 'inverse pan law' or (better) an homogeneous relation p(pan_L, pan_R) that is independent of the type of pan law, but depends only on the ratio pan_L/pan_R (or pan_R/pan_L if pan_R=0...).

Actually there are various possible relations between pan and (pan_L, pan_R) being used in common pan laws. We could continue using the current one in hydrogen which is
image
(actually hydrogen pan doesn't go from -1 to 1 but scaled and translated into [0,1])

or decide a new relation, for example
image
which is used in the so called "linear panning" and always generates a more lateral virtual stereo location for the same value of the pan parameter. This would be a good occasion to test by ear which is the relation that describes the perceived horizontal angle of a panned (mono) signal more linearly.

@oddtime
Copy link
Contributor

oddtime commented Dec 28, 2020

About the multi parameter pan: note, instrument

Yeah. I sometimes wonder why Hydrogen offers such a general behavior. After all, I would consider a drumkit something static and e.g. the snare not moving positions between individual beats. Anyway. I think it's fine the way it's implemented right now and I added some lines to the doc.

Actually I don't know if this is a good way to deal with "multi parameter" panning because it causes very low (if not killed) volumes when the two parameters are set to opposite sides.
Idea: a definition of the resultant_pan(note_pan, instrument_pan) and then calculating the L/R weights with this resultant_pan, but then I have to rethink the strategy for the implementation.

Furthermore, to bypass the instrument pan when setting a note pan it would be required another note member bool bIsUsingAbsoluteNotePan otherwise all notes would be central because they have a default central note pan... this changes my opinion on the bypass and I would not implement it right now.

@theGreatWhiteShark
Copy link
Contributor Author

It depends probably if you use Hydrogen only as drum machine or as a general sequencer.
Ps I realized now that past versions had a "drumset/piano" toggle button in the pattern editor panel, which allowed to hear the samples at different pitches with the pc keyboard (qwerty...). I don't know if there was midi input at that time. Do you know why it has been removed?

It's still there. You can use this button at the top of the pattern editor to switch to the piano roll. In addition, via the menu you can switch the input mode between drumkit and instrument allowing you to either play the different components of your drumkit using the keyboard or pitch shifted versions of the currently selected one.

After all there is a computational advantage: saving pan_L and pan_R is good for skipping the pan law computation at every note rendering.

We don't have to worry in here. Since there is stuff like pitch-shifting a audio sample going on, applying an analytic function on two numbers is negligible.

Current drumkits and songs volumes have been probably mixed by ear, listening to the current ("straight polygonal") pan law, so I think we should mantain the current pan law option, and adding other ones.

That's an excellent point! Didn't thought about it. Viewed from this angle we have to keep the current panning law at least as default. But then again, this more or less defeats the object of updating the panning implementation. Hydrogen's mixer is not comparable with the ones provided by DAWs since essential things like a position-dependent effect/plugin chain, CV support, aux channels etc. are missing. Having an advanced option that makes all drumkits sound worse - under the assumption they are perfectly mixed - does not sound like an improvement at all.

Actually I don't know if this is a good way to deal with panning because it causes very low (if not killed) volumes when the two parameters are set to opposite sides.
Idea: a definition of the resultant_pan(note_pan, instrument_pan) and then calculating the L/R weights with this resultant_pan, but then I have to rethink the strategy for the implementation.

That's also a good point. It's a potential bug. We should check

@oddtime
Copy link
Contributor

oddtime commented Dec 29, 2020

Thank for the suggestion, I missed the input mode via the menu.

That's also a good point. It's a potential bug. We should check

For this I have some arbitrary ideas:

  1. note pan bypasses instrument pan
  2. note pan locates the signal in a smaller pan range centered at the instrument pan.
  3. weighted mean between note and instrument pans and then apply the pan law.

@theGreatWhiteShark
Copy link
Contributor Author

I would vote for

  1. note pan locates the signal in a smaller pan range centered at the instrument pan.

since this way it behaves like all the other controls found in the NotePropertyRuler

@oddtime
Copy link
Contributor

oddtime commented Jan 3, 2021

@theGreatWhiteShark could you have a look at pull req #1061? Especially for the static member functions, way to define/use them...

@theGreatWhiteShark
Copy link
Contributor Author

Closed with #1061

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants