You are here

Qtractor Normalize

Hi Rui, Having worked with a Pianist on a few songs, that plays in the order of 1500 notes per track. I would like your thoughts on changes to the Midi Normalize function. I have written (crudely) a Python tool to normalize the track with less edit steps.

The program steps are: User sets the desired Max velocity point. Say 95 (95 / 127 possible values). User sets the compression ratio, say 2:1 ratio.

The program: Gets Max Velocity from the track. Apples the formula newVelocity = (velocity / compression) + gain.

I have attached a hacked down version of my python code.

I thank you, for all the great work you have put into qTractor :-)

Regards Dave M. from New Zealand

AttachmentSize
Plain text icon Normalize_Example.txt1.13 KB
Forums: 
rncbc's picture

hi, thanks for your contribution

you know there's already a tool in qtractor for the very same: MIDI Clip > Tools > Normalize

if yes, than what do you think it is lacking or wrong if it is worse than your solution?

cheers

Hi Rui,

I do use your MIDI Clip > Tools > Normalize (many times), however it does not produce the same result.

Your Normalize tool either, sets the notes to an absolute value or a percentage of the original value. When both options are set its seems to do: new_Velocity = (absolute_value * (percentage/100) ).

The net result is different to: new_Velocity = (original_Velocity / compression_ratio) + re_gain.

This is not a criticism, just an observation and discussion.

Regards Dave M.

rncbc's picture

the correct formula is:

normalized_value = value * (param_percent * param_value) / (100 * max_value)

where:
- param_percent, param_value are the respective parameter values entered in the dialog (default 100 and 128 resp. for 7bit note velocities).
- max_value is the maximum value (note velocity) of the whole set (selection) to which the normalization is to apply.

Hi Rui, I took your formula and built an Python script comparing the velocity data against Qtractors normalizer and my alternative normalizer.

What is quickly obvious is Qtractor does not compress the data range, just re-scales velocity data.

My alternative normalizer does compress and normalizes in on step. This in my opinion is more musically desirable. When you find a spare minute, have a play with the attached python script. Please check my maths :-)

PS I had to change the script to a .txt to upload it :-)

Thanks for your time. I have used Rosegarden and Muse. Qtractor is my favourite :-)

Regards Dave M.

File attachments: 
bluebell's picture

But this would be a new feature, a MIDI compressor, not a normalizer.

rncbc's picture

exactly!

thanks

rncbc's picture

your proposed normalize+compress formula seems to be like the following:

compressed_value = param_value + (param_percent * (value - max_value)) / 100

where:
- param_value takes the role of your target value as used to compute gain = param_target - (max_value / compress);
- param_percent is the reciprocal to the compress ratio, ie. param_percent = (100 / compress).

confirm?

if yes then it might see the light as a new option on the (MIDI Clip >) Tools > Normalize tab, aptly named after "Compress" that, when checked, applies this later formula instead of the former one.

cheers

Further thoughts...

To differentiate Compress from Qtr Normalize, I would use "Compression Ratio" and "Target level" as the user inputs. Compression could the a list or values of: 1:1, 2:1, 3:1, etc up to 10:1. I don't see a need to go higher the 10:1

Note: The formula does need the Pre-check, if the user enters 1:1 and a new Target_value of 64 of:

difference = max_value - target_value. if difference > 0 then compress = max_value / target_level.

eg: If the user has a data input range of 1-127 and chooses 1:1 compression, and a new target_level of say: 64. Then the new compressed_values can go negative.

The above Pre_check will add a 'small' amount of compression to span/scale the data over the new velocity range of 1-64

The previous attached compare_normalize.txt has the code I used.

Happy to contribute. Dave M (down under NZ)

"Compression could the a list or values of..."
Better a box with a decimal that admits values ​​between 1.0 and 10.0.
Something like this:
Compress Ratio: [ 1,0 ] : 1

This would admit values ​​like 1.5 : 1

rncbc's picture

to clarify: my idea is the reuse the current Normalize tool page and just add an "Compress" option, like so:

[ x ] Normalize

[ x ] Percentage: [0..150%] - this is the param_percent in the formulas above = (100.0 / compress) (see table below);
[ x ] Value: [0..127] - this is param_value or will be the target value if Compress is turned on;
[ x ] Compress - this will switch to compressed_value (new) formula instead of normalized_value (old).

this way there won't be a need to brand new page of entry fields, just an additional checkbox to an existing tool page.

cheers

UPDATE: Initial implementation in qtractor >= 1.3.0.6git.b00566 [develop].

Compress ratio Percentage
1:1 100.0%
2:1 50.0%
3:1 33.3%
4:1 25.0%
5:1 20.0%
6:1 16.6%
8:1 12.5%
9:1 11.1%
10:1 10.0%

I know this is not an intuitive move at all, regarding the OP contribution, but then open for suggestions; also reminding you that only functional conversions at the UI level are possibly acceptable; the dice have rolled already (ie. alea jacta est ;))

I have tested the solution and I consider it to be very satisfactory :).

I mentioned "Compress Ratio: [ 1,0 ] : 1" simply because I considered it better for the interface than a list, if it finally decided to establish ratios.
But I am really more comfortable with percentage values.

The percentage gives you the proportion value directly, the ratio you have to calculate.

Example:
2:1 = 1/2 = 0.5 = 50%

If you give me the percentage I save myself from doing the division mentally.

On the other hand, I don't know who came up with the idea of ​​reversing the divisor-dividend order to express ratios, which is basically the same concept as a fraction.

And to make things even more confusing, at least in my country, the symbol ":" always meant division.

That is:
2:1 (also represented as 2/1) is not 0.5.

2:1 is 2.

Conclusion:
I like the new feature, and also the way of requesting it without requesting it (disguising it as an improvement) :).

Add new comment