-
Notifications
You must be signed in to change notification settings - Fork 26
Peak meters calibrated pull #10
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
base: master
Are you sure you want to change the base?
Conversation
More actions and fixes
Direct track selection in Mixer view w top row buttons
Mixer Mode Track Navigation
Direct API calls for track selection rather than Reaper actions to overcome 99 track limit
Track selection working Non existing tracks in last bank are now properly marked as not available
Bank selection
VU meter data format ok, but: - Need a better hook (update frequency) - VU meter updates not working properly. CMD_SEL_TRACK_PARAMS_CHANGED not fully understood yet
VU: - functionality is there! - some minor tweaks like scaling still open - code cleanup required
native conversion taken from Reaper SDK
- Calibration also valid for other keyboards than S Mk2?
-Meters working -Precise, non linear calibration for KK Mk2 Display Meters
Update niMidi.cpp
- Stub to isolate this pull request from fork master
efficiency improvement
well, the pow() vs exp() efficiency bugged me a little - improved this straight away while at it (not that it really matters.... :-) |
- Use direct linear logarithmic conversion specifc to NI keyboard meter scaling rather than concatenating a calibration frunction after calling Reaper API standard conversions - Speed improvement - Further meter precision improvement
Final code optimizations. The conversion from peak values to MIDI values is now implemented as a direct linear logarithmic transformation without any detour via Reaper API conversions. This delivers the highest precision at lowest CPU costs. |
Requires a fix. The fix will be introduced together with mute and solo implementation.
|
Actually Reaper API Track_GetPeakInfo() seems to be buggy, will raise as a separate issue |
Solved in pull request #18 => issue #17 closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I appreciate these being submitted as separate pull requests. However, because they're on top of other work, it's still difficult to review and merge them in isolation. If possible, please branch from master for each piece of work. That's tricky for a couple of these, since they depend on earlier code, but several of them are largely unrelated (including this one) and could be done in separate branches off master.
A few comments below.
@@ -0,0 +1,17 @@ | |||
#ifndef _WDL_DB2VAL_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this file isn't needed any more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct. can be kicked out.
@@ -1,69 +1,22 @@ | |||
# ReaKontrol | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file shouldn't be included in this PR/branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I was surprised it got in there. don't even know how to exclude it ;-) such a rookie I am with git. need to study the documentation better.
... don't be shocked ... the code itself is (despite of style issues) not as terrible
// A value of 0 will result in stopping to refresh meters further to right. | ||
// The array needs one additional char at peakBank[16] set to 0 as a "end of string" marker. | ||
char peakBank[(BANK_NUM_TRACKS * 2) + 1] = { 0 }; | ||
int j = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have a better name for this variable? outPos
might work.
if (*(bool*)GetSetMediaTrackInfo(track, "B_MUTE", nullptr)) { | ||
peakBank[j] = 1; | ||
peakBank[j+1] = 1; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd prefer } else {
on same line, rather than separated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, better readability. will consider in future edits.
} | ||
else { | ||
peakValue = Track_GetPeakInfo(track, 0); // left channel | ||
if (peakValue < 0.0000000298023223876953125) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please use a named constant for this value. I assume it's the float representation of -150dB?
- I wonder if it makes sense to move this check into peakToChar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup. I did exactly that in later rework of the code (see later pull requests). And yes, sorry for making you read through these ventures with the incremental modifications style....
//----------------------------------------------------------------------------------------------------------------------- | ||
|
||
static unsigned char peakToChar_KkMk2(double peak) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd prefer {
on the same line as the function definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree!
double a = -3.2391538612390192E+01; | ||
double b = 3.0673618643561021E+01; | ||
double c = 8.6720798984917224E+01; | ||
double d = 4.4920143012996103E+00; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do these magic numbers represent? Please use named constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are the result of curve fitting, i.e. reverse engineering to fit Reaper's meters exactly to what is shown on the KK display. The KK display scale is a fixed pixel image. The function calculates the MIDI values that are required to show the bar at exactly the correct height to coincide with the dB value that Reaper reports. I.e. midi = a + b * ln(c * volume +d).
With these parameters the maximum error is 0.3% between Reaper values and display reading at the curve fitting points noted in the comments, i.e. far less then the quantization due to the pixel nature of the display.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should add that this is the most CPU friendly function I found.
@@ -145,6 +145,7 @@ BaseSurface::~BaseSurface() { | |||
} | |||
|
|||
void BaseSurface::Run() { | |||
this->_peakMixerUpdate(); // ToDo: Maybe update only every 2nd call to save CPU? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than putting this in BaseSurface, you could just override Run() in NiMidiSurface and call the superclass: BaseSurface::Run()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, that would look cleaner and is also more logical (I don't even know if Mk1 has meters - do you?)
You are very right about this - sorry for making your merging efforts harder than maybe needed. Originally I had planned to work in this fashion (separating parallel branches from a base commit) but abandoned it when I came to realize that there were more inter-dependencies than I had anticipated. This is also owed to the fact that for me it is like "double reverse engineering": the NI API is not documented at all and Reaper's API is also not documented that extensively... As a result I ventured back and forth with some approaches as you can easily see when you look at the individual pull request. |
PPS: "offline" for the next couple of days, hence I won't be able to change anything for a week or so |
Transport Button Lights working
This pull request implements the Peak Level Meters on the Komplete Kontrol Keyboard. It is based on previous pull requests #7 and #9. It thus shows more changes relative to the current master which has not yet pulled #7 and #9 .
Notes: