Conversation
ann0see
left a comment
There was a problem hiding this comment.
Can't say too much here, but have a look at my comments. Also please verify the style.
| } | ||
|
|
||
| // Enable delayed panning on startup ---------------------------------------- | ||
| if ( GetFlagArgument ( argv, |
There was a problem hiding this comment.
Why do we need two cli flags? Wouldn't one be enough?
There was a problem hiding this comment.
Yes one would be enough. I realized this too after I made the PR. Two options would be useful should we change the default in a later release. We’d still need to decide on the default. I’d like on as default in which case you need the —nodelaypan option. With off as default you want the -P/—delayedpan option.
There was a problem hiding this comment.
If switching it on means more processing power, I would not enable it by default (there is and was a lot going on with optimizing server performance and adding something which needs more power is counter productive). You can always switch it on of course.
There was a problem hiding this comment.
I remember that Volker mentioned that this delay pan might not be a better experience for everybody, for example bands. So I also wouldn't enable it per default.
There was a problem hiding this comment.
Maybe someone with a band could try it?
src/server.cpp
Outdated
| } | ||
| else | ||
| vecfIntermProcBuf[k + 1] += vecsData[iRpan]; | ||
| ; |
There was a problem hiding this comment.
What do you mean? The spurious semicolon? That can go of course.
There was a problem hiding this comment.
How would I have to fix this? Push another commit?
And are the lone else's without braces ok?
There was a problem hiding this comment.
I would use a force push. Concerning the else I don't think that's the style used overall. But since we're getting improved code, I'd wait for this before working on more here.
Hk1020
left a comment
There was a problem hiding this comment.
I don’t know what I did here with _review _
src/server.cpp
Outdated
| } | ||
| else | ||
| vecfIntermProcBuf[k + 1] += vecsData[iRpan]; | ||
| ; |
There was a problem hiding this comment.
What do you mean? The spurious semicolon? That can go of course.
|
Hello, I'm in contact with Detlef Hennings who wrote the original code. He improved his code since June 2020 and can provide an updated version in a couple days. It's up to you if you want to merge this now and then do a new pull request when we get the revised version, or if you wait for this update. I am using this delay pan feature for a couple weeks now with my chorus, and it makes a real difference! I'm glad it is finally finding its way into the main branch. |
I'd wait for the update then. No need to rush this. |
|
@Hk1020 This is the latest version of the code of Detlef which he just sent me. I have no idea of the content, but I think you should be able to detect any changes he made and determine if they are good. I used the compiled version of the code with my chorus for a couple weeks now, we had no bugs, the server was running stable, and the sound was good. |
|
@DominikSchaller Excellent, I‘ll have a look later, thank you (and Detlef Hennings). |
|
Can we close this and open a new PR once the new code is available? |
The new code is already available, I posted it here last night. |
I am looking at the new version right now and compare it to this one. |
|
I'd like to keep it here. |
Ok. Thanks. Just saw it (again). |
|
I'm done with analyzing the code. There is no functional difference in the actual panning code except one cut/paste error I introduced. Everything else is just handling of how to turn it on - the new version has fewer options - and a lot of commented code. I'll prepare a new version soon. |
|
I've updated the PR. Where is a good place to discuss the code? Here or in an issue (#567)? |
|
Probably here. You can start reviewing it again |
src/server.cpp
Outdated
| const float fGain = vecvecfGains[iChanCnt][j]; | ||
| const float fPan = vecvecfPannings[iChanCnt][j]; | ||
| const float fPan = bDelayPan ? 0.5f : vecvecfPannings[iChanCnt][j]; | ||
| const int iPanDel = lround( (float)(2 * maxPanDelay - 2) * (vecvecfPannings[iChanCnt][j] - 0.5f) ); |
There was a problem hiding this comment.
I'm not sure about the style here.
| const int iPanDel = lround( (float)(2 * maxPanDelay - 2) * (vecvecfPannings[iChanCnt][j] - 0.5f) ); | |
| const int iPanDel = lround( (float)( 2 * maxPanDelay - 2 ) * ( vecvecfPannings[iChanCnt][j] - 0.5f ) ); |
Does this line calculate the delay between left and right? Sorry if this is obvious ;-).
There was a problem hiding this comment.
I am not sure. There are more places where you could save on temporary variables. So far I haven't really understood what's been done here.
There was a problem hiding this comment.
Hmm. Before merging this, we (or at least one/two of the main developers) have to be exactly sure what each line does (and comment it). If anything goes wrong it should be possible to debug it.
There was a problem hiding this comment.
Having investigated the code more iPanDel is the position and the delay happens later by adding iServerFrameSizeSamples to one of the two channels. Correct me if I’m wrong.
We should also check how maxPanDelay is set. Might be a simple #define.
src/server.cpp
Outdated
| iLpan = iLpan + iServerFrameSizeSamples; // | ||
| vecfIntermProcBuf[k] += vecsData2[iLpan]; | ||
| } | ||
| else |
There was a problem hiding this comment.
I think this doesn't match the style (the else)
|
|
||
| // we always use stereo audio buffers (which is the worst case) | ||
| vecvecsData[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); | ||
| vecvecsData2[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ ); |
There was a problem hiding this comment.
Is this also needed if delayed panning is off? If not, do we need to initialize it (does it have any performance impact)? (also applies to line 345).
There was a problem hiding this comment.
Detlef Hennings is working on being able to operate the delay panning in different modes. This is about the distribution of the singers in the virtual space.
Therefore it would be good to keep the parameter '-P panmode' free for this and similar developments and to use for delay panning only --DelayPan (or similar) for delay panning.
Furthermore, delay panning is so important for singers that it should be possible to activate it via a checkbox.
There was a problem hiding this comment.
Furthermore, delay panning is so important for singers that it should be possible to activate it via a checkbox.
I think this is already part of this PR: https://github.com/jamulussoftware/jamulus/blob/0c6b3fbfc261b1b078bbd43ed939107deb07132e/src/serverdlgbase.ui
There was a problem hiding this comment.
Furthermore, delay panning is so important for singers that it should be possible to activate it via a checkbox.
I think this is already part of this PR: https://github.com/jamulussoftware/jamulus/blob/0c6b3fbfc261b1b078bbd43ed939107deb07132e/src/serverdlgbase.ui
Right now this is a server setting. I'd also prefer this to be a client setting but it isn't yet. If it is we wouldn't need the command line option.
There was a problem hiding this comment.
This would probably need a new protocol message.
There was a problem hiding this comment.
Thought about it once more: it is a good idea after all to make this a client setting. Thanks for asking!
There was a problem hiding this comment.
There would need to be:
- a message from the server saying "I support delay pan if you want it"
- a message from the client saying "I would like delay pan"
- a client method to send the message
- a clientUI mechanism to request the feature only if the server supports it (which would need to take server version and the specific message into account). (I'm not sure if this should be in settings, as it's a user preference, or a on the server mixer, as the choice might vary depending on the jam session.)
I also think maybe get the server support finished and released "as is" before adding the client side. I definitely think it's worth having, though.
There was a problem hiding this comment.
As far as our 9 month experience with vocal ensembles and choirs goes, once the participants have heard the impression of delay panning, they would never want to go back to volume panning. And with acoustic instrumentalists it seems to be similar. I suppose that the preference will mainly depend on the music style. For instance, choir and classical music servers could preferably use delay panning and rock music servers might use volume panning (well, I assume that). Then, at least for a first implementation, the pan type decision can be made on the server side. And public servers may announce which panning type they provide.
If really required, an override option from the client side could be added in a later Jamulus version. But this would complicate server algorithms, because then they need to handle mixed delay and volume panning processing.
There was a problem hiding this comment.
I‘d also like to get this done. The sooner the better. People would benefit immediately. The client part can come later and this should go out right away (3.7.0). But it is not on me to decide. I too can’t imagine anyone wanting to go back to volume panning.
I‘d been entertaining the idea to provide a client setting in a later PR. The grounds are laid and there isn’t much to add to the server logic except the protocol bit. Mixing is per client already so we only need to make bDelayPan a vector, similar to fPan.
There was a problem hiding this comment.
The problem is, because we want to be certain about the quality and fully understand operation of the code that goes into a release, every additional feature causes further delay in the release of 3.7.0, which already is later than we would have liked. That is not to express any doubt about the code quality or its usefulness, it just takes time.
It will definitely be fully reviewed for inclusion in 3.7.1, and hopefully that release will not be too far into the future.
|
I'll run this code on my server and will look for feedback from my choir. I hope that it doesn't require more processing power. Edit: before this gets merged, the commits should be attributed to Detlef Hennings. |
Ok. I first wanted to say that this code is not verbatim of what we got in the zip file from Detlef Hennings. I have another branch locally where I traced everything. Do you somehow want it? This here is based on what Volker did in #332. The only real change is the cli option. The rest is adapting it to master. I compared it to Detlef Hennings' version, which looks quite a bit of work in progress. I compared everything and verified that they are functionally equivalent. There is certainly potential to streamline the code. |
So will I.
From a cursory check via htop on my Pi4 I couldn't see any difference. But I've also been wondering about this optimization in line 1230 (don't know how to directly link here):
This has been there before and leads to a lot of code duplication, especially now. Only to save one multiplication in the end. This if branch is dead and broken in the zip file version.
Do you mean in some comment or somewhere else? |
|
Since I've never done a PR before am I supposed to do something with these comments? What does this |
I‘d do it in the commit message: https://docs.github.com/en/github/committing-changes-to-your-project/creating-a-commit-with-multiple-authors
No. Just leave them open. |
| const int iPanDel = lround( (float)(2 * maxPanDelay - 2) * (vecvecfPannings[iChanCnt][j] - 0.5f) ); | ||
| const int iPanDelL = ( iPanDel > 0 ) ? iPanDel : 0; | ||
| const int iPanDelR = ( iPanDel < 0 ) ? -iPanDel : 0; | ||
|
|
There was a problem hiding this comment.
We now have with bDelayPan = true:
const float fGain = vecvecfGains[iChanCnt][j];
const float fPan = bDelayPan ? 0.5f : vecvecfPannings[iChanCnt][j];
fPan = 0.5
const int iPanDel = lround( (float)(2 * maxPanDelay - 2) * (vecvecfPannings[iChanCnt][j] - 0.5f) );
const int iPanDelL = ( iPanDel > 0 ) ? iPanDel : 0;
const int iPanDelR = ( iPanDel < 0 ) ? -iPanDel : 0;
const float fGainL = MathUtils::GetLeftPan ( fPan, false ) * fGain;
GetLeftPan is 1 for fPan = 0.5 (see util.h), i.e, fGainL = fGain
const float fGainR = MathUtils::GetRightPan ( fPan, false ) * fGain;
Same here, fGainR = fGain.
So we could do away with fGainL and fGainR completely and just use fGain (if bDelayPan==true). Or what am I missing?
If I am right the rest of the code could shrink a lot.
src/server.h
Outdated
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
| * | ||
| \******************************************************************************/ | ||
| //****************************************************************************************** |
There was a problem hiding this comment.
This goes in the Changelog, not the source code.
|
I'll review this and try it out soon. |
|
Hello Everybody! I'm the author of the original delay panning code for Jamulus, and I would like to mention, that this code has been tested since June 2020 and is in use by different vocal groups, choirs and and also by acoustic instrumentalists since then. PS PPS |
Co-authored-by: Detlef Hennings <[email protected]>
Done. |
softins
left a comment
There was a problem hiding this comment.
OK, I have read through the code, and compared with the branch point, although I haven't tried running it. I understand what it's doing, and it looks like it should work as intended. I think some of the code could be made more efficient, but compiler optimisation will probably help. It might be worth revisiting that if we see a significant difference in performance, but for now, happy to approve.
|
@gilgongo I think this needs to be documented on the changes branch in the documentation. @DetlefHennings can you give a short description for the documentation so we can add it here: https://jamulus.io/wiki/Command-Line-Options |
|
The short description can be: A bit more detailed description (elsewhere) can be: |
|
Although this has now been merged - thank you - it seems the conversation above #1151 (comment) about defaults got lost. I’d still like to raise it again. |
Ok, see below
I understand your motivation for this, but my view is that we shouldn’t make enabled by default a new behaviour that most people have not tried out and experienced. No problem with highlighting it and promoting the benefits. If there is a lot of positive feedback from people who have tried it, you can be sure that word will spread, and we could consider making it the default in 3.8 |
|
Speaking as someone fairly ignorant of the details of audio tech, I'd be curious as to what the differences are. I've briefly tried this out, but I couldn't notice anything obvious (although having it controlled by command line parameter makes it more difficult to compare side-by-side). |
Actually, if you start the server with the GUI there is a checkbox to turn it on or off on the fly. It makes the difference really obvious. But not with mono! And use the pan knob. The effect is somewhat subtle. |
|
Oh, I was passing the option to the client instead, no wonder I didn't notice any difference. Oops! (maybe passing it to the client should give a warning though, instead of saying In searching for explanations/examples about it I found this youtube video which talks about "the Haas effect". Is that the same as "delay panning"? |
There are actually a lot of server-only options that do not generate a warning when given to a client, although they are then ignored. It would be good to tidy that up a bit! |
From what I could see there isn’t any support in the current command line parsing for further dependency checking. Has to be done manually. |
Delay panning, when used with headphones, simply 'simulates' the runtime difference between the two ears depending on the horizontal angle of sound incidence (it's not the Haas effect). This relation to human hearing makes it sound so natural. BTW, the effekt is lost, when a delay pan is set exactly to center. |
Now you got me curious. How is this not the Haas effect (which I learned about just now)? |
I just watched the video. Really interesting, and a good demonstration of delay panning. Although more than a couple of ms difference is more than the ears would naturally encounter, because sound travels through air at approximately 34cm per ms. I then read about the Haas effect at https://en.wikipedia.org/wiki/Precedence_effect. That seems to be talking about something slightly different: hearing a sound with both ears, followed by an identical sound, again with both ears, a very short delay later (a few ms). Something like a very quick echo. It doesn't appear to be talking about why a single sound's perceived direction is because of the difference in arrival time at each ear. So it seems the guy making the video was mistaken in calling it the Haas effect. |
|
Thanks for merging this feature into master! This stale branch can be deleted now: https://github.com/jamulussoftware/jamulus/tree/feature_hennings_delay_pan2 |
|
I think it's removed now |
Next generation choir serverIt seems that delay panning is going to be delayed (!) by introducing more and more issues into v.3.7.1, or now v.3.8.0. But meanwhile the next generation server for choirs and other acoustic music ensembles is under test. This server arranges all clients in a circle geometry and all (delay) pans are calculated from this geometry and are set automatically. This avoids controlling a large number of pans. Individual client positions on the circle are set either by numeric input or by a pseudo random algorithm. For testing Debian and Ubuntu beta binaries and a short explanation are available under this link. |
|
We're in planning for release now :). |
|
Circle mode sounds awesome. It'd be great if geometry could also be controlled "by group" (without manually assigning numbers to participants' names). But that might be the/a next step, after the feature has been shown to work. |
See #567. This reestablished and aligned #332 with current development.