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

AutoDj: New transition mode 'Radio Laneway' #13716

Open
davidlmorris opened this issue Oct 2, 2024 · 12 comments
Open

AutoDj: New transition mode 'Radio Laneway' #13716

davidlmorris opened this issue Oct 2, 2024 · 12 comments

Comments

@davidlmorris
Copy link
Contributor

davidlmorris commented Oct 2, 2024

Edit 2024-10-11: A pull request #13750 has now been created.

Feature Description

This transition mode is designed for social functions, especially playing popular music, and is designed to sound like a commercial radio station. For this purpose, it is vastly superior to existing transmission modes, and for cold endings especially, it consistently performs better than most people I suspect (well, me at least!).

We will need to add two new Cues, FadeIn and FadeOut. (cf analyzersilence.cpp pN60dBSound and kSilenceThreshold.) The FadeIn range is the time from the Main cue point (or first sound if the MainCue is not set) to the first time a track reaches kFadeInThreshold which is set to -27 dBV (or 0.0447f). The distance between these is the fadeInLength. The FadeOut range is from the last time a track was at kFadeOutThreshold which is set to -12 dBV (or 0.2511f), to the last sound. The distance between these is the fadeOutLength. The values are selected based on "sounding good" while reducing the chance of pathological times for fade-ins or outs.

This transmission mode also separates (on occasions) the start of a crossfade (fadeBeginPos) from the start of the track where the next track starts is sometimes earlier than the start of the crossfade (playNextPos). In all cases the crossfade starts the next track at full volume, meaning that the crossfader is set to the centre position. This requires the code from TransitionMode::FixedStartCenterSkipSilence (Auto dj cross fader center #13628).

This transition mode does the following:

  1. If a playing (from) track has reached the FadeOut cue start, then a crossfade starting center is initiated, with the transmission time taking the fadeOutLength, or value from the spin box (fixed value), whichever is smaller. This fits most cases and provides a smooth crossfade on tracks with a fadeout, and excellent timing when a track has a sharp or cold ending.

  2. If the next (to) track has a fadeInLength greater than 0.25 seconds then the next (to) track starts a fadeInLength value (playNextPos) earlier than the current (from) deck fadeOutStart. This covers the case where we have a slow fade-in of a song, for example, when Boston's "More Than A Feeling", comes next after a song with a cold start, removing the perception of a gap, while preserving the cold ending. (In this example it is about 3 seconds earlier, though the new track is not perceptible during a cold ending). Note that the crossfader holds in the center while the next (to) track starts, and starts moving the fader once fadeOutStart is reached. If the fadeOutLength + playNextPos difference is greater than the spin box, then revert to item 1 above using (fixed value) calculated from fadeOutLength.

  3. If the next (to) track has a duration of less than 15 seconds then this track is likely a jingle or sample. In this case, the fadeInLength is 0 and the fadeOutLength is 1. This way we have a fast neat transition while maximizing the time for the next track to load.

Note the following potential issues:

  • The spin box should be positive (negative values will mean a spacing, better handled by other transmission modes).
  • Pathological tracks for example tracks that never have a volume higher than -27 dBV until at least halfway through the track report a debug message and have the fadeInLength set to 0.
  • Since the cues will be added to the database and only scanned for new tracks changing the kFadeInThreshold and the kFadeOutThreshold values once set will be problematic. It may be better to have multiple FadeIn and FadeOut cues for each track (separated by 3dBV) and have the user select which one to use in AUtoDj preferences. Alternatively, include a test to see if these values have changed (though I suspect this will create too much overhead).

What do you think of this?

Now as you might have guessed from the detail above, I have already implemented this is, and have it running as a mod to version 2.4.1. I've just run it overnight with no stops or issues, and while I only heard the first two hours, it sounded really good, indistinguishable from a commercial radio station. I will test it live in front of an audience next Saturday. (See below for the report).

@daschuer
Copy link
Member

daschuer commented Oct 2, 2024

Sounds great, thank you.

How will this interact with the user adjustable fade in an out regions? Will these new cue points additional hidden cue points, e.g. track properties or adjustable, e.g. user properties?

We had a related discussion that the fixed silence detection point of -60 dB does not fit for some tracks, especially because the replay gain is applied after analysis. At that time we have renamed the -60 dB cue to pN60dBSound. Because it is also used to detect modified samples.

So we probably need a two phase analysis? Or do it on the fly maybe from the waveform data?

Regarding adjustable thresholds: I if we are not able to find a good default for all tracks, the user won't we able to do it either. But there is a demand for fixing problematic track. So maybe it should reuse the existing GUI fade regions?

Regarding the already existing fad-in region, I have the assumption in my collection that it shall end before vocals start and adjusted some tracks for this. Your proposal will do it automatically?

@davidlmorris
Copy link
Contributor Author

davidlmorris commented Oct 2, 2024

Thanks.

These new cue points will be additional hidden cue points, like pN60dBSound, in the first instance. I guess it would be possible to make them user-adjustable, which might help fix any pathological tracks that we come across. (Or just consider it as a future option.)

So we probably need a two phase analysis?

I'm not sure I really understand what you mean here. I discovered the hard way (as one usually does) that pN60dBSound and the new cue points is tested for and added only once. Caused some grief trying to work out the best levels as you can imagine!

In my opinion, the threshold values above work perfectly but others may have a different view, of course.

What are the "the existing GUI fade regions" - do you mean those shown with the outro and intro? I was thinking that if we did make it a usable adjust thing, we could have it like red(=pink?) to contrast with the regions shown in the intro and outro markers (which I still find very useful). Perhaps another reason for just keeping it hidden!

Regarding the already existing fad-in region, I have the assumption in my collection that it shall end before vocals start and adjusted some tracks for this. Your proposal will do it automatically?

Yes! I do set my intros and outros on some tracks to make 'where the vocal starts (and ends)' visible on the track display, but this transition ignores them totally, focusing rather on the first sound at -27dBV (which is pretty low and well before any vocals in any track I have) and the last at -12dBV which is usually well into a fade out, or cold ending. I picked this value because it sounded good, but also didn't want to trample over tracks that deliberately had a quiet(ish) ending. For example, Coldplay's Vivia la Vida will transition at the first uuh ooh, but not linger over the rest.

I did use the MainCue point as the default starting point, so if a user had moved that beyond some sort of awkward start (e.g.The Bloodhound Gangs 'talk' at the start of The Bad Touch) then the track should start there. (Yet to be tested/confirmed)

While reading the Cues I did come across a problem. There are multiple calls to calculateTransition and it seems that the Cues return spurious data (usually way too big) until presumably the last call (is pDeck->rateRatio() correct all the time?), which on short tracks might not happen before the transition. I've worked around this by setting some guards. It is only really an issue for very short tracks.

And, in debugging that problem I've had trouble seeing local variables in the debugger because the debug version has still got optimised code. I'm looking at /Zo (Enhance Optimized Debugging), and I think I have found the correct place to insert this into CmakeLitst.txt. Is this an option that can be added? (Obviously, I am using VS here).

@daschuer
Copy link
Member

daschuer commented Oct 2, 2024

@daschuer
Copy link
Member

daschuer commented Oct 2, 2024

So we probably need a two phase analysis?

I'm not sure I really understand what you mean here.

By default Mixxx anlytzes tha loundess of a track and applyies a replaygain value for equal loudness.
So id you have a track with overall high loudness the. Detected loudness values are no longer comparable (shifted) when playing in a transition with a low loudness track. Therfore it would be optimal to redo the detection after the loudness has been analyzed, taking the replaygain into account.

What are the "the existing GUI fade regions" - do you mean those shown with the outro and intro?

Yes.

Perhaps another reason for just keeping it hidden!

We can go with the hidden version. What are the two use cases we need two regions? Do you have an example transition Track pair in mind? It is best to discuss it with real track.

While reading the Cues I did come across a problem. ...

That's a sore point of auto-DJ we have two units of track position. One is run-time, one is sample/frames and one is percentage of the whole track.

@daschuer
Copy link
Member

daschuer commented Oct 2, 2024

/Zo should be enabled by default.

set_source_files_properties(
        autodj.cpp
        PROPERTIES COMPILE_FLAGS "/Od"
    )

However I don't use it. I use qDebug() statements, which have the side effect that the variable is also kept in the context when debugging.

@davidlmorris
Copy link
Contributor Author

By default Mixxx anlytzes tha loundess of a track and applyies a replaygain value for equal loudness.

When does it do this (is it done as part of normal analysis)?

Therfore it would be optimal to redo the detection after the loudness has been analyzed, taking the replaygain into account.

Yes, I agree. I wonder if my values are/would still be the same. Is there some way to tell what normalisation value has been applied?

What are the two use cases we need two regions? Do you have an example transition Track pair in mind? It is best to discuss it with real track.

Well, I'm of the view that it is probably best hidden... but I am open to it as an option.

So here is an example:
Using Coldplay's Vivia la Vida, I will have marked the intro for talk up to vocals (12 secs). The FadeIn transition will be less than 0.5 seconds. The outro would start at 3:42. And the fade out (I think from memory) around 3:47. Perhaps I want the fadeout transition at 3:42 there, so here I would want to see it and move it to the new position.

@davidlmorris
Copy link
Contributor Author

/Zo should be enabled by default.

I can't find that anywhere. In CmakeLists.txt I found this, which implies very strongly that the debug build is optimised (add_compile_options(/O2) # this implies /Od2). The /O2 option sets the options that create the fastest code in the majority of cases.

    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
      #optimize Debug Builds as well, to have "normal" behaviour of mixxx during development
      string(REPLACE "/Od" "" CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG}")
      string(REPLACE "/Od" "" CMAKE_C_FLAGS_DEBUG  "${CMAKE_C_FLAGS}")
      string(REPLACE "/Ob0" "" CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG}")
      string(REPLACE "/Ob0" "" CMAKE_C_FLAGS_DEBUG  "${CMAKE_C_FLAGS}")

      add_compile_options(/O2) # this implies /Od2
      # Remove /RTC1 flag set by CMAKE by default (conflicts with /O2)
      string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG}")
      string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG  "${CMAKE_C_FLAGS_DEBUG}")

@daschuer
Copy link
Member

daschuer commented Oct 2, 2024

When does it do this (is it done as part of normal analysis)?

Yes.

Yes, I agree. I wonder if my values are/would still be the same. Is there some way to tell what normalisation value has been applied?

Yes, you can show them as ReplayGain library column.

Well, I'm of the view that it is probably best hidden... but I am open to it as an option.

From you example it looks like that the manual outro intro should overwrite the hidden default set by your formula. Sounds reasonable to me. What do you think?

@davidlmorris
Copy link
Contributor Author

From you example it looks like that the manual outro intro should overwrite the hidden default set by your formula. Sounds reasonable to me. What do you think?

Yes, exactly. Though I'm not sure how often I would use it (and who knows maybe lots if it was there).

However, that is an awful lot of GUI for one AutoDj transition. (Even if it would look pretty and be fun to write).

If we go down this path we do it as a separate pull request and as a feature for a future version. Perhaps after we have established the need. After all, many users won't even touch the AutoDj feature, let alone this particular transition.

And as well, if we make it visible, then the next request would be to have an option to change the default options... which would be another project. (Not necessarily a bad thing - but we are building complexity on complexity for diminishing returns).

Are you able to merge #13628?

@davidlmorris
Copy link
Contributor Author

I had a look at the ReplayGain library column. Very interesting. About half have no change (is this because they haven't been played?), and of the rest, almost all of those are gain reductions. The biggest reductions are from an 'Oasis CD' down 13dB of most of the tracks. That is a perceptible drop. Having said that, I haven't heard a bad transition in this mode (apart from short-duration tracks when my guard values are used), so either this difference is not enough to affect the outcome much, or the analysis is being done on already adjusted tracks.

My settings are:
Apply Replay Gain: true
-16 LUFS (adjust by +2dB)
Initial boots without Replay Gain data: 0dB
ReplayGain 2.0 (ITU-R BS. 170)

Can you point to where the code applies a replay gain value for equal loudness?

@davidlmorris
Copy link
Contributor Author

Perhaps in the interim, we should have a reset: 'silence detect' and reset: 'fade cues' right mouse click on the track option.

@davidlmorris davidlmorris changed the title AutoDj: New transmission mode 'Radio Laneway' AutoDj: New transition mode 'Radio Laneway' Oct 9, 2024
davidlmorris added a commit to davidlmorris/mixxx that referenced this issue Oct 10, 2024
Adding RadioLanewayCrossfade transition.
See mixxxdj#13716
@davidlmorris
Copy link
Contributor Author

davidlmorris commented Oct 13, 2024

I will test it live in front of an audience next Saturday (and will report on the results).

It went brilliantly. (Except where I stuffed up a transition when I left the cue on for one... and had to talk over to recover... but that isn't relevant!). The Radio Laneway transition mode was flawless.

So much so, that I did very little DJing and spent most of my time in the audience talking and listening. Very happy.

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

No branches or pull requests

2 participants