-
Notifications
You must be signed in to change notification settings - Fork 172
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
Working on Implementation of Panning #1061
Conversation
Is it still work in progress? If so, you can also convert it into a "draft" (via the right column under the heading "Reviewers") |
It is in progress if we decide to add other pan features... |
src/core/Sampler/Sampler.cpp
Outdated
/// functions for pan parameters and laws----------------- | ||
float Sampler::getRatioPan( float fPan_L, float fPan_R ) { | ||
// returns the single pan parameter in [-1,1] from the L,R gains | ||
// It doesn't return ERROR if (L,R) = (0,0) nor if they are negative!!!!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the errors in those two functions: If there is no straight forward default value one can return/set, the C++ way of implementing errors would be an exception. But in Hydrogen it's almost never used (and introducing it would make the code most probably harder to maintain).
I would suggest to introduce these limits to Instrument::set_pan
and Note::set_pan
instead. If > 0, 0
will be assigned and a WARNINGLOG triggered and the same for 1 from above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to introduce these limits to Instrument::set_pan and Note::set_pan instead. If > 0, 0 will be assigned and a WARNINGLOG triggered and the same for 1 from above.
Ok, I keep it for the final version. please don't resolve this conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to introduce these limits to Instrument::set_pan and Note::set_pan instead.
There is already a check for negative pan:
void Note::set_pan_l( float pan )
{
__pan_l = check_boundary( pan, PAN_MIN, PAN_MAX );
}
In this way H2 one can set both pan_L = pan_R = 0. In this case there is a problem to reconvert back to the pan parameter. It could happen importing a bad song.
src/core/Sampler/Sampler.cpp
Outdated
// use Straight pol pan law. | ||
// TODO a new song member, set in preferences, must point the desired pan law Sampler member function | ||
float (*panLaw)( float ); | ||
panLaw = &this->ratioStraightPolPanLaw; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making a single Sampler::panLaw( float, enum)
and an enum class for the different pan laws? Inside this function you could use switch-case statement to distinct between the laws.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I preferred to use pointers to bypass the conditions checks and to go straight to the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the addresses of pan law methods depend on the Sampler
object, maybe this pointer should be saved in some form in the song (for example written as an int
or enum
, which type is new to me now), but should live in Sampler
class.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I preferred to use pointers to bypass the conditions checks and to go straight to the function
I see. But I would like to ask you to use switch-case or if statements nevertheless. It's not because I have a personal reference but the code base of Hydrogen does use the former over function pointers. It's more easy to maintain it if there is a consistent coding style. (Admittedly, the one we deal with is not the best but, well, it works. 😉 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the reason.
I would just ask you if you would consider consistent this alternative:
float (*m_pPanLaw)( float )
is a member in Sampler
;
while import the song, or setting the preferences, the corresponding pan law function address is assigned to m_pPanLaw
using if
statements instead of that weird array of addresses introduced in commit 60574be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a programmer, but still helping where I can 😉
I am attaching a songfile to test the pan laws! |
A summary of what is included until the last commit: different pan laws to set in preferences->audio. The type of pan law is already saved in the songfile, but I am not convinced about the way it is saved. |
Hydrogen has two main ways for storing information: within each Regarding storing: I think the options the user is able to alter should be in the |
Since the pan law affects how the project sounds and how it will be mixed, it should be stored in the .h2song in my opinion.
I don't think so |
And what about the way of storing in the file? with an integer number? Maybe I would go with a meaningful string |
I would store it in just one file. Else it will only cause confusion.
I do see your point. But if we store it in the Song file the option must not be set via the |
An |
I will try to explain why I would like to save it in the song
If you use pan note property for a surrealistic effect of instruments moving in the space, this could happen. Otherwise I think that every pan law is equivalent, as you will compensate the gain by ear. |
Yes, you are right. Also when sharing a song the panning law shouldn't be altered by the preferences of the other user. This still leaves the question of where to put the control/widget to alter this setting. Since it just concerns the internal sound generation it might go to the But wait. Does it only concerns the internal sound generation? Doesn't it affect the MIDI export of the notes too? (disclaimer: I have almost no idea about MIDI) |
Ok. I approve putting a new widget in the mixer. I think a button on the right, accordingly with the pull req #525
In MIDI, pan has its dedicated message from 0-127 so it seems that midi does not transmit the information of separate gain_L and gain_R. |
How about introducing 4 headings/categories in the "Select Pan Law" options: linear, polar, ratio, quadratic. Right now it's a little bit hard to get an overview with so much different options densely packed. |
Well I had the same idea but was lazy to set it |
Unfortunately I am not an expert of Qt and this seems complex. |
Well, unfortunately neither am I. First of all I would recommend using the |
The current pan law combobox already uses separators but there is not so much contrast to see them clearly. I used Qt creator to create the dialog, but added the combobox items in |
I found a way |
Are you ok with the current namings? |
Nice! I'll do my best to review the changes during the next days.
Sounds good. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. I like it!
Some minor things but almost done.
Thanks for the check! I did the changes. If you want merge I would add the feature in Changelog |
Any ideas? Files are 2 s long at 44100Hz... |
They were only typo/cosmetic requests. It looks all good from my PoV. |
I modified the c++ file doing the test to print the different samples in the shell:
|
Yeah, two little differences. One in the middle of the song and one at 3/4. I noticed that when diffing the hexdump of these files too. I did place some prints to I will keep digging until I find something |
Thanks @theGreatWhiteShark ! |
Okay. Everything's fine. There is some truncation happening causing very small differences in the resulting output. In principle we could make the pan calculate use Could you take one of these temporary results and replace the |
Ok, done. |
…ligible float differences
See issue #665
I don't want this pull request to be merged now, but just share it.
In Hydrogen the two pan parameters control two separate balances, like a chain, then if they are hard panned to opposite sides, the signal is killed. If there is a reason to mantain this, or somebody likes it, we can add the new feature as option in preferences
What is changed now is, from a user point of view:
note
andinstrument
pan interation:note
pan moves the pan in a smaller pan range centered atinstrument
pan.In this pull req. a resultant pan is calculated then the balance law is called. The signal is never killed.
Of course if the
instrument
pan is set to the left, you cannot move the signal to Hard right with thenote
pan (sincenote
pan range is smaller and centered atinstrument
pan); to achieve this, other strategies would be required as discussed in #665 (for examplenote
pan bypassinginstrument
pan, this could be another option in preferences if somebody likes it).In this pull req, the way hydrogen saves pan is unchanged: pan_L and pan_R for both
note
andinstrument
objects, even if it is now strange and h2 needs to convert them to single parameters and then applies the pan law again.I used some pointers to member functions, in the future hypothesis of different pan laws implementation. Just to test them, but they should become song members.
// Edit: Added many pan law options, set in mixer: new button on top-right