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

Cues & Loops upgrade for Stems (& Widget) #13759

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

Eve00000
Copy link
Contributor

@Eve00000 Eve00000 commented Oct 13, 2024

upgrade of cue/loop routines for stems

dbase needs to be updated with 4 fields in cues-table -> REAL + snake_case
alter table cues add stem_1_vol REAL DEFAULT 1.00 NOT NULL
alter table cues add stem_2_vol REAL DEFAULT 1.00 NOT NULL
alter table cues add stem_3_vol REAL DEFAULT 1.00 NOT NULL
alter table cues add stem_4_vol REAL DEFAULT 1.00 NOT NULL

when track has stems the mute and volume settings are saved in the hotcue / loop
else the values are all 1 (default)
volume -> 0-100 (= %) in widget, background double 0.0 .... 1.0
mute -> negative volume value
cue widget adapted to be able to change the stemvolumes after the cue is set.

the serato-markers give me grey hair.
20240913 - StemsCuesLoopsWidget

@acolombier
Copy link
Member

I haven't looked at the code yet as is doesn't seem to be ready to review looking at the CI result. My 2 cents on the overall look is that using integer for a volume that is a double feels redundant, so I would recommend using the same type between backend and persistency layer.

In terms of feature, I am not sure that fitting this usecase on the existing hotcue is a wise idea. Perhaps we could consider another type of cue, eg. stemcue? This could be great as that would allow potentially even more stem customisation (eg FX set/dry-run volume)

Also, please note that to make this feature ready for review, the DB migration will need to be automated.

@Eve00000
Copy link
Contributor Author

CI result.
integer for a volume that is a double

The serato-markers give me grey hair :-( I would like another eye on that. :-)
For a user volume needs to be a clear number, so a % is a clear value. Other double values as position, and length are also converted to integers to save in the cues-table in the dbase. Duration, replaygain are converted and saved as float in the library-table in the dbase.
I didn't want to add the dbase convertions in the pr before dbase names can be agreed.

@daschuer
Copy link
Member

The database should contain full precision, which is double in terms of COs, but float is precise enough for our 32 bit float engine. The representation in the GUI is unrelated. The proposed 0..100 % is OK we may consider to use 0.0 ... 1.00 or a dB scale.

//auto lock = lockMutex(&m_mutex);
// We should get a trackCuesUpdated call anyway, so do nothing.
// auto lock = lockMutex(&m_mutex);
// We should get a trackCuesUpdated call anyway, so do nothing.
Copy link
Member

@daschuer daschuer Oct 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change? Befor clang format we had the rule to use "//" without space for commented code and "// " for information.

Make sure your editor doe not auto-format the whole file to avoid noise in your PRs like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this happens automatically with the pre-commit since the update about 10 days ago (was an update of some minutes)

src/engine/controls/cuecontrol.cpp Outdated Show resolved Hide resolved
// EveCue-Loop
bool TrackStem = false;
if (ControlObject::exists(ConfigKey(getGroup(), "stem_count"))) {
PollingControlProxy proxyStem(getGroup(), "stem_count");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should avoid CO look up during Mixxx runtime, because this is a looking operation. Can you move this into the constructor or somewhere else? Checking for exist already creates the CO half way.
You can instead create the PollingProxy with ControlFlag::AllowMissingOrInvalid flags.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -883,6 +891,54 @@ void CueControl::hotcueSet(HotcueControl* pControl, double value, HotcueSetMode
}
}

// EveCue-Loop
bool TrackStem = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bools should be named for building a "sentences" with if. Like if (hasStems) { or such. And start with a lower case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

if (TrackStem) {
const QString groupBaseName = getGroup().remove("[").remove("]");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you remove the [ her and add it below.

Copy link
Contributor Author

@Eve00000 Eve00000 Oct 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was my best solution to make [ChannelXStemY] from [ChannelX]

@daschuer
Copy link
Member

Perhaps we could consider another type of cue, eg. stemcue?

What are the pros an cons?

Without dedicated stem cues all hot-cues of stem will have volume values.
This means that if you want to use the cue with the current stem layout there is a risk of unwanted volume change.
I can also imagine to use cues after moving a single stem to a second deck. Recalling a cue there will then mess up the moved state. This are my argument for a dedicated cue type.

What are the cons? Is there an alternative solution for a workaround?

@daschuer
Copy link
Member

Oh I have jumped into detailed comments before sharing my opinion about this approach.

I consider this a great feature, than you :-) . It is useful to mark "teaser" parts a track where you want only vocals or another specific layout. It also is helpful to start a stem based transition with a predefined layout, where you for instance bring later the whole track in.

Are there more use cases?

The serato-markers give me grey hair :-( I would like another eye on that. :-)

What do you mean by that? Can you explain it or share an external reference?

@Eve00000
Copy link
Contributor Author

Oh I have jumped into detailed comments before sharing my opinion about this approach.

I consider this a great feature, than you :-) . It is useful to mark "teaser" parts a track where you want only vocals or another specific layout. It also is helpful to start a stem based transition with a predefined layout, where you for instance bring later the whole track in.

Are there more use cases?

The serato-markers give me grey hair :-( I would like another eye on that. :-)

What do you mean by that? Can you explain it or share an external reference?

Other use case: create reMixxxes, narrowing the line between DJ and producer.
example: I used the Daft Punks 'Da funk' drums - loop with the piano of 9 to 5 and the piano of Think (Aretha Franklin), brought in the bassline of another one bites the dust (cue -> loop)
The advantages =

  1. speed in preparing / mixing / switching
  2. cpu load: preparing a cue with pfl takes cpu
  3. creativity boost using all possibilities of digital DJ-ing -> I have the correct sample / loop under my thumbs
  4. fun : you can watch the reactions of the public, not just watching the screen

@Eve00000
Copy link
Contributor Author

Eve00000 commented Oct 13, 2024

The serato-markers give me grey hair :-( I would like another eye on that. :-)

To let the serato cues match the 'adapted' cues, they need to have the 4 stem volumes, but compiler says they are unused. If I remove them compiler says missing ....

@Eve00000
Copy link
Contributor Author

Without dedicated stem cues all hot-cues of stem will have volume values.
-> but they are only used on Stems

This means that if you want to use the cue with the current stem layout there is a risk of unwanted volume change.
-> But it can easily be checked with right click.
-> Volume change of stems fappens immediately (so also in headphone check before mixxxing)
-> Maybe another color?

I can also imagine to use cues after moving a single stem to a second deck.
-> In this case there sould be a 'grey out' of cues where the selected stem is muted or volume = 0

@Eve00000
Copy link
Contributor Author

The database should contain full precision, which is double in terms of COs, but float is precise enough for our 32 bit float engine. The representation in the GUI is unrelated. The proposed 0..100 % is OK we may consider to use 0.0 ... 1.00 or a dB scale.

Do you mean you prefer to have 0.00 to 1.00 in the dbase in stead of 0 - 100 ?

@acolombier
Copy link
Member

acolombier commented Oct 13, 2024

What are the pros an cons?

Another limitation I can think about is the limiting factor of having only stem volume - assuming you want to isolate a vocal sampler, you may also want to add a reverb + 25% dry/run volume.
In the meantime, adding all those parameters may scope creep hotcue usage, but it could also not so I'd be happy with that approach.
My only request would be to use a proto for the hotcue parameter definition, so we can evolve it overtime, and don't need DB migration

Do you mean you prefer to have 0.00 to 1.00 in the dbase in stead of 0 - 100 ?

Yes, I think it would make more sense.

@daschuer
Copy link
Member

The cue table is defined here

CREATE TABLE IF NOT EXISTS cues (

and updated here:
ALTER TABLE cues ADD COLUMN color INTEGER DEFAULT 4294901760 NOT NULL;

In other columns we use sbake_case. so I think "stem_1_vol" does fit better.

We had a discussion around "Spatial Audio", where we may have n channels and aposition in space. This kind of applies partially as well to instuments stored in a stem. I have not any demand here but I just want to bring the question up if these four colums are the right choice or if we need something more generic like a meta data blob.

Something like

  • volume cue
  • effect cue
  • panning cue

What do you think?

@@ -35,6 +35,10 @@ class SeratoMarkersEntry {
bool hasEndPosition,
int endPosition,
SeratoStoredHotcueColor color,
int stem1vol,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are unused here and can be removed.
Can you propose this change and we con look at the missing warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do,

@@ -236,6 +236,10 @@ SeratoMarkersEntryPointer SeratoMarkersEntry::parseID3(const QByteArray& data) {
hasEndPosition,
endPosition,
color,
100,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be probably removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, there was another occurrence that was too much... solved Compiler happy

@daschuer
Copy link
Member

Do you mean you prefer to have 0.00 to 1.00 in the dbase in stead of 0 - 100 ?

yes as a "real" value.

@daschuer
Copy link
Member

My only request would be to use a proto for the hotcue parameter definition, so we can evolve it overtime, and don't need DB migration

Yes that make sense, use a protobuffer to store the volume information and probably a verison number to be backward compatible.

We use it already to store the keys information in the data base:

ALTER TABLE Library ADD COLUMN keys BLOB;

https://github.com/mixxxdj/mixxx/blob/60abf58e20af9e02c6475b0861008d4f074fa6fb/src/proto/keys.proto

@Eve00000
Copy link
Contributor Author

Eve00000 commented Oct 14, 2024

you may also want to add a reverb + 25% dry/run volume.

-> this was indeed something I was thinking of as well, but I was in dubio because sometimes I want to use the FX-rack super in stead of the one fx selected on the stem. On the other hand to be consequent these settings should be saved as well.
Can I interpret your comment as 'add the fx - parameters also to the saved cue' ?

scope creep .... proto for the hotcue parameter definition, so we can evolve it overtime, and don't need DB migration

-> I try to redefine your words in my language (I never adapted to programmers-slang):
With starting to add parameters to the cues we know where we start but we don't know where we'll end. Maybe one day we add more possible settings to the stems that we can't forsee at the moment. To have a way to cope with the future you propose proto (googles memory buffer type, sort of json and xml?)
With proto's you can define a way the needed information is stored in the memory.
So at the moment you would store a 'message' id / track_id / ... / color / stem1vol / ... /stem4vol
but in the future this message can become
id / track_id / ... / color / stem1vol / ... /stem4vol /.... parameterXsettingA / ... / parameterZsettingC/ ....
In order to keep the routines that work on the first parameters working you'll define a new 'message' that uses the new parameters for the new routines and keep the first message for the old routines.
Am I correct? (If so, I agree completely).

I just don't understand why you don't need a dbase migration then.
Is it because you already added a lot of fields at the beginning or is it by reusing fields for other meaning, like a second hotcue record with another 'type' that stores other parameters in the stemxvol fields?

excuse me for my ignorance

@Eve00000
Copy link
Contributor Author

In other columns we use sbake_case. so I think "stem_1_vol" does fit better.
->Top.

We had a discussion around "Spatial Audio"
-> Yes with someone who wanted to create a 'spatial venue'
-> So you would like to add the fields for 'spatial' or use the same fields with another 'proto? I'm still not complete in the proto-system.

I think I asked once (at the beginning of the stems-implementation) to have a pan-knob besides the volume knob.
But I stopped pushing my luck. Fort the record: 'STEMS ARE SUPER'
I would love the addition of pan-settings to a stem-track (and saving/loading it with the cues)
But spatial audio needs a kind of XY vector for the stem-tracks fi drums on 40-40 bass 60 -40 melody 60-60 and vocals 40/60,
I don't want to hear it that way (except when it's an own mastered stem with only voices on the 4 tracks)

@Eve00000
Copy link
Contributor Author

Do you mean you prefer to have 0.00 to 1.00 in the dbase in stead of 0 - 100 ?
Yes, I think it would make more sense.
-->fixed

@Eve00000
Copy link
Contributor Author

@acolombier
Hi Antoine,
I studied he 'proto's 'header, keys and beats' and how they are used (wtracktableviewheader, keys & beats).
I need some help, this is quiet new for me.
What do you exactly want to do with the proto in this case? Do you want to 'translate' the 'use-names' of the stem_x_vol fields in the cuetable' ?

Copy link

This PR is marked as stale because it has been open 90 days with no activity.

@github-actions github-actions bot added the stale Stale issues that haven't been updated for a long time. label Jan 14, 2025
@daschuer
Copy link
Member

daschuer commented Jan 14, 2025

I gave that a second thought and consider how much we want to open padoras box.

Hot cues are points in the track where you like to cue it in, (the whole track). We have one track, with one transport. All effects are NOT related naturally.

We have recently introduced loop cues, used to recall loops. This are not Hot cues in the original terms, but since they are close related to transport it fits somehow mentally.

We have also the use case of jumping around in a track using cues. This can be used to repeat or skip portions of a track or use the cue buttons like a drum pad.

Changing the volume has never be part of cues, but I think here it is more for selecting a certain stem layout, right? Somehow a second dimension of cueing.

On the other hand we may treat the volume changes of stems like EQing, which is also not a part of cues.

You see, opening cues for stem volume may also create demands for EQs and than for the whole effect unit and whole Mixxx.

All this are valid use cases. But I see three different feature:

  • Hot cues
  • Recording (redo) of DJ a performance/setting
  • Create predefined samples

To which category dos the stem volume control belongs to?

To be clear: I do not want to stop the project. I just want to discuss a perfect solution, to make sure that everything we introduce will align with it. Later we can decide if dedicated columns or a protbuf blob is the best fit and if it is am implicit feature of hot-cues or a new layer of controls.

@Eve00000
Copy link
Contributor Author

... the whole track

I understand what you mean, but IMO since the introduction of stems the definition of a (whole) track has changed, else the volume of a stem can also be considered as 'not naturally related' because no part of the whole track, and earlier EQ could have that label as well indeed.
As the definition of a track has changed, the definition of a 'cue' must have changed as well. Other software use something like this under the name 'slicer'. The difference is that in this solution the users can set the 'slice points' themselves.
I am using this for some months now and this is a real stimulation and expansion of my creativity. I can't without it anymore, for me this is the real added value to DJ-ing with stems.
I hace to admit: I am already playing in the next field: saving fx settings in the cues as well (balance shifter, echo, reverb on voicetrack) and I am enjoying it very much. So I am already having a party with Pandora. ;-)
IMHO this is something we can't hide / withhold for the Mixxx-ers, although it's my golden trick at the moment I'd like to share it.
Has nobody else experimented with it?

@daschuer
Copy link
Member

That sounds good. So you actually looking for different thing than an advanced hot cue. It is a "performance cue" or such, right?

Is it more like a recoded performance, or like something you would normally do in a pre recorded sampler from the sampler button?

Do we also need to consider looping? For this new cue type?

@Eve00000
Copy link
Contributor Author

"advanced hot cue" -> "performance cue" or such, right?
"recoded performance" -> sampler from the sampler button?
Do we also need to consider looping? For this new cue type?

You're on track! 😄 ❤️
It's a cue, but a special one. In the development stage of stems I explaned my wish for stem-track-cues (not part of the whole track) that would make it possible to use the stem-track in a sampler with the cues of that track.
In the ideal world, and I'm studying on @ronso0 's "feat: allow swapping hotcues" #13394 I would like to drag the cue (you can call it performance cue) or the stemtrack (with stem-tracks own cues) to a sampler (as mentioned in https://mixxx.zulipchat.com/#narrow/channel/109122-general/topic/Hotcue.20stop.20mode), also with the length of the hotccue.
When a stem-track with it's own cues (volume for other stem-tracks = 0) and fx-settings is loaded in a sampler = slicing
When 1 'performance cue' is opened in a sampler (with defined length), the sampler becomes part of a 'soundboard' (thanks to OSC😄)
Thinking further: as bassdrum-kick / snare / handclap ... can be a 'performance cue' to, combined with loop and rate in the sampler we get a drummachine -> samplermachine (like fi DJS 1000)

@github-actions github-actions bot removed the stale Stale issues that haven't been updated for a long time. label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants