dylanljones / pyrekordbox

Inofficial Python package for interacting with the database and other files (XML, ANLZ, MySettings) of Pioneers Rekordbox DJ software
https://pyrekordbox.readthedocs.io/en/latest/
MIT License
181 stars 24 forks source link

Deriving gain in dB from gain and peak mixer parameters #88

Closed gsuberland closed 1 year ago

gsuberland commented 1 year ago

I figured out the format for mixer gain parameters in djmdMixerParam. The High and Low values are the upper and lower halves of a packed 32-bit IEEE754 float value. Each value represents a linear voltage gain factor, i.e. 1 = 0dB, 10 = +20dB, 0.1 = -20dB.

Here's a quick script to convert the values:

from pyrekordbox import Rekordbox6Database
import math
import struct

db = Rekordbox6Database()
for t in db.get_mixer_param():
    gain_factor = struct.unpack('!f', ((t.GainHigh << 16) | t.GainLow).to_bytes(4,byteorder='big'))[0]
    gain_dB = 20.0 * math.log10(gain_factor)
    peak_factor = struct.unpack('!f', ((t.PeakHigh << 16) | t.PeakLow).to_bytes(4,byteorder='big'))[0]
    peak_dB = 20.0 * math.log10(peak_factor)
    print("\"" + t.Content.Artist.Name + " - " + t.Content.Title + "\", gain=" + str(round(gain_dB,2)) + "dB, peak=" + str(round(peak_dB,2)) + "dB")

Example output:

"Phaction - Echo", gain=7.18dB, peak=-6.49dB
"Netsky - Come Alive", gain=4.32dB, peak=-7.17dB
"Netsky - Escape", gain=3.47dB, peak=-5.6dB
"Netsky - Everyday", gain=4.34dB, peak=-8.26dB
"Netsky - Eyes Closed", gain=3.32dB, peak=-5.22dB
"Netsky - I Refuse", gain=3.74dB, peak=-5.61dB
"Netsky - Iron Heart", gain=4.41dB, peak=-5.52dB
"Netsky - Let's Leave Tomorrow", gain=6.26dB, peak=-3.62dB
"Netsky - Secret Agent", gain=4.95dB, peak=-3.32dB
"Netsky - Starlight", gain=4.15dB, peak=-5.65dB

The gain value is the value of the auto-gain knob in the Grid Edit panel, which is also set by the analysis process. The peak value doesn't seem to be actually exposed in the UI, but it's the peak amplitude of the track (I've verified that this matches the peak amplitude in Tenacity) and is updated when the waveform is loaded.

You can convert the dB numbers back to linear gain factor by calculating pow(10.0, g/20.0), then re-packing the float to a pair of 16-bit unsigned integers using the same struct.unpack approach.

Would be cool to get this conversion in the API, either as a property or a function on the DjmdMixerParam class.

dylanljones commented 1 year ago

Very nice, thank you so much for the effort! I will add it to the API soon!:) Btw, nice to see a fellow DnB head:D