HQPTuner: an improved configuration interface for HQPlayer Embedded

Can you please describe what you mean here? I must be missing something as I don’t understand this part…

I was referencing the fact that 1/2 and 2/2 ratings were not shown in the manual, only 3/5 and up… but I just checked and all filters are, actually, rated in the manual. So either “only 3/5 and up are shown rated in the manual, 1s and 2s are left unrated” was a feature of older v5 manuals that I never updated my mental model for, or I’m losing my mind.

I just checked the v5 manual I have on hand and it also shows 1/2 and 2/2 ratings. I might be losing my mind. :grimacing:

The idea was to let people know that I hadn’t just invented the 1 or 2 star ratings. But in light of the fact that everything is, actually, clearly printed in the manual, that paragraph can be ignored. :man_facepalming:

1 Like

Another new version is up, v1.11.1, but this one is limited to :beta for now. If you want to try it out, change compose.yaml to image: oh💩gorillas/hqptuner:beta then re-pull and re-build. But replace the emoji with… y’know :wink:

Two big changes:

Simplified option mode extended to DSD Sources

Yes, now you can read the DSD sources features in plain English as well!

In my opinion, these are some of the most baffling settings in the entire program and some of the most difficult to suss out how to use… so they needed this treatment badly.

The reason this release is in beta is because I am waiting on Jussi to confirm the accuracy of the language, if he so chooses. I have pretty tightly hugged the manual with the descriptions, but there’s always the chance that some wording needs tightened up or changed to maintain full accuracy. Take these with a grain of salt for now.

Example:

I modified the filter descriptions

Yes, I went there. Before you grab your pitchforks, take a look at a couple of examples:

Before:

Minimum phase variant of poly-sinc-shrt. Otherwise similar to poly-sinc-mp, but shorter post-ringing. Most optimal transient reproduction.

Technically good steep “brickwall” filter, but might have some side effects (pre-ringing) on material containing strong transients. This filter is similar to FIR, but it is applied in frequency-domain and is quite efficient from performance point of view while having rather long impulse response. Length of this filter can be configured separately in Settings dialog.

After

A minimum phase variant of poly-sinc-short. It is otherwise similar to poly-sinc-mp, but has shorter post-ringing. Most optimal transient reproduction.

A technically good steep "brickwall" filter, but it might have some side effects (pre-ringing) on material containing strong transients. This filter is similar to FIR, but it is applied in the frequency domain and is quite efficient from a performance point of view while having a rather long impulse response. The length of this filter can be configured separately in the FFT filter length setting.

That’s it. Mostly just adding missing articles. fixing typos and prepositions, and correcting references to settings. File this under “reducing the mental load required to parse options.”

The other signal chain setting descriptions (everything now covered by Simplified mode) got the same treatment.

I’ve resisted the part of me that wants to take this even further (“A minimum phase variant of poly-sinc-short, otherwise similar to poly-sinc-mp, but with shorter post-ringing and optimal transient reproduction”)… for now.

Misc changes

I renamed “Direct SDM” to “DSD Playback” with a switch [ Processed | Direct ].

I centered carets with the text and made a few other things more visually consistent.

I reorganized some filter families.


Thanks everyone, and don’t be shy about feedback and bug reports :wink:

1 Like

Again, great work, I use this every day. Question, is it possibly to scale this to work with mobile devices, like a Samsung Z-Fold?

Ok, v1.11.2 is now up on :latest!

Changes

DSD Source options in plain English

As with v1.11.1, Simplified option mode now extends to DSD Source settings with approved sorting and names (thanks, Jussi!).

Renamed features (traditional names are always printed below the new name):

  • SDM to PCM conversion is now “Decimation filter”
  • Integrator is now “Remodulator structure”
  • SDM to SDM conversion is now “Rate conversion”

A shot of the PCM and SDM chain cards in Simplified mode:

Option copy edits (again)

I’ve peeled back some of the more aggressive changes I made to the option descriptions. It occurred to me that

Otherwise similar to poly-sinc-mp, but shorter post-ringing.

is perfectly valid English. “It is” and “has” add nothing. Bad idea on my part, and mostly reverted: I’ve kept the grammatical error fixes but restored the original register. Most of the changes left, then, are just consistency, e.g., “greater than or equal to” becomes “≥”, “hires” becomes “hi-res”, etc.

I said I haven’t changed anything that could alter the meaning, however, there is one case in v1.11.2, which is the two-stage note:

… first stage rate conversion is performed by at least a factor of 8 using the selected algorithm, then further converted to the final rate using an algorithm optimized for content already processed to at least 8x rate.

The clause after the comma reads as if the conversion itself is the thing being converted, so I clarified:

…the first stage rate conversion is performed by at least a factor of 8 using the selected algorithm, then the signal is further converted to the final rate using an algorithm optimized for content already processed to at least 8x rate.

Also, to maintain full transparency (or in case Jussi wants to incorporate some of these into the manual), I’ve added a “before and after” file so that uses can see exactly what was changed: docs/copy-before-and-after.md.

1 Like

Not anytime soon, unfortunately. I don’t own anything similar to test with, so there would be obnoxious back-and-forth. I have a friend interested in contributing to converting it to a proper app (HQPTuner could hit the App/Play Stores if that pans out!), but that’s not happening anytime soon.

Works great on tablets, though! On my 13" iPad Air in portrait mode, cards stack single column so the pages get long, but it’s otherwise all good. YMMV depending on screen size, obviously.

1 Like

I’ve got to say, this is such an amazing project that I’m eagerly following from the sidelines even though I only own the desktop version of HQPlayer.

I will definitely be switching over to the embedded version next time there’s a version bump or meaningful promotion. I love HQPlayer but this is taking it to the next level and is my dream come true.

1 Like

Thank you so much!

Actually, in a post on AudiophileStyle, Jussi mentioned that older versions of Desktop had an XML loading feature. If he brought that back, HQPTuner could at least in theory work with Desktop as well. Just email Jussi and let him know you want HQPTuner to work with Desktop (or, he’ll probably see this post :slight_smile: ).

That said, it would take a lot of time and finagling on my end, since I’d need to then start distributing HQPTuner as executables. Specifically, executables should be digitally signed, and the cheapest digital certificates cost over $100/yr… the alternative is every time you install HQPTuner, you’d have to click through an “Are you sure you trust the source of this software?” warning. And that’s to say nothing of the cost of getting Nuitka to compile executables that pass, e.g., VirusTotal. This project already consumes a good chunk of my time, I draw the line at letting it consume my finances as well.

Going through Docker lets me bypass all that for now and distribute for free. But Docker Desktop on Windows and Mac doesn’t work the same as “real” Docker on Linux, and anyway I’m not asking people to install a multi-gigabyte resource intensive program alongside HQPlayer Dekstop just to run my little web interface.

If anyone sees a better (cheaper) way forward, please do let me know.

1 Like

Another update :slight_smile: v1.11.3

Tooltip revisions complete

I’ve finished revising the tooltips and manual guidance to fix the English. Once again, I’ve tried to be as minimal as possible and resist my urge to go further than simple fixes.

(Personal side note: I never judge someone over English mistakes; it’s a weird, silly language and if I didn’t grow up a native speaker, I doubt I’d be able to wrap my head around it myself, so kudos to anyone who manages it as a second language.)

Once again, the full list of changes can be found in docs/copy-before-and-after.md.

Filter narrowing improvements

I’ve added an “Unspecified” selection to the Length dropdown in the Filter Narrowing card, so now you can see only filters whose lengths are unspecified. The other day I wanted to see everything EXCEPT short filters, but narrowing by any length cut out everything without a length, which I also wanted to keep.

I also changed the similar option under the Phase dropdown from “No phase” to “Unspecified”, as that’s more accurate.

Lastly, I grayed out options that leave the filter list unchanged or empty. For example, selecting “minimum” and “intermediate” phases leaves no medium or extra-long filters, so now those checkboxes in the Length dropdown would be grayed out.

Misc

The app was written for the Inter font, which I have installed on my system, so it always showed up “correct” to me… but if you don’t have Inter installed, you were seeing your browser’s default font, not Inter. Fixed so the app now shows up in Inter (and JetBrains Mono) as intended.

Yes, I pushed another new version through before going to bed, v1.12.0!

More idiot-proofing

Fifth-order 1024+ modulators (AHM5EC*) are suboptimal with HQPlayer’s volume control, so now HQPTuner will ask if you’re sure you want to proceed with that modulator when using HQPlayer’s volume and vice-versa, alerting users to the suboptimal pairing.

FFT Filter Length card eliminated

The most useless card in the program, Filter Length, previously held a single setting: FFT filter length. That card has been eliminated. A new log-scale slider appears when the FFT filter is selected under the chain’s shaper (modulator/dither). This uses up previously dead space while eliminating a card.

Modulator generations

I’ve added the modulator generation information to the tooltips in the dropdown.

1 Like

I made a Discord for HQPTuner in case anyone is interested :slight_smile:

2 Likes

EDIT posted at the top for visibility: Jussi tore this apart :rofl: back to the drawing board! I’ll leave this here for curiosity’s sake, but I wouldn’t put much stock into the recs themselves.

EDIT2: I’ve made some revisions based on Jussi’s feedback, updated below and sent back :crossed_fingers:


OP:

No new version for today, but I wanted to get people’s feedback on an idea I had: a truly easy, simple, plain language system for picking a filter. Something so easy an idiot could do it.

I didn’t think such a thing could be done. I thought it was genuinely impossible. HQPlayer has too many filters/settings with too many variables. You can’t just generally recommend filters beyond the defaults. It’s just too complicated.

…I think I’ve done it.

I call this Easy Mode. The language and settings here are still pending Jussi’s review, however, I also wanted to see if anyone in the community has further suggestions, feedback, criticism, etc. Don’t hesitate to let me know what you think, even if it’s to tell me how bad the idea is.

Constraints: Filter selections should be:

  • Capable of any rate change
  • Apodizing, except when otherwise explicitly noted to the user.
  • 4/5 Quality or better.

There are two non-apodizing choices and one half-apodizing in the list, and only one 3/5 filter—and that option comes from an old comment from Jussi pairing poly-sinc-short-mp(-2s) to old school analog prog recordings.

Without further ado, I am extremely proud to present: HQPlayer Filters for Dummies v2

Playlist mode

Playlist mode is when you’ve got a mix of different material and source rates back-to-back. It only has two settings.

:1st_place_medal: The Perfect Ten

Does everything well, no strings attached. Start here.

1x: poly-sinc-gauss-long
Nx: poly-sinc-gauss-hires-lp

:violin: Lifelike

Puts the focus on natural, realistic timbre.

1x: poly-sinc-ext2-long
Nx: poly-sinc-ext2-hires-lp

Album Mode

Album mode is for when you know what you’re getting and can optimize for a specific recording. Each preset also comes with an Emphasis sub-option for fine-tuning transient performance vs space via either phase or length. It sets both the 1x and Nx filters to the same setting for consistency in albums containing multiple rates (I have a few).

:1st_place_medal: The Perfect Ten

Does everything well, no strings attached. Other presets are trade-offs. Start here.

poly-sinc-gauss-long

Emphasis [ Space | Balanced | Transients ] → gauss-long | gauss-medium | gauss-short
Note: ‘Transients’ corrects errors less aggressively than ‘Balanced’ or ‘Space’; if it sounds harsh, try another setting.

:sparkles: The Perfect Ten: Hi-res Mode

A version of The Perfect Ten optimized for rates 88.2 kHz and up. Also suitable for lossy MQAs and MP3s.

poly-sinc-gauss-hires-lp

Emphasis [ Space | Transients ] → -lp | -mp

:violin: Lifelike

Puts the focus on natural, realistic timbre. Perfect for live performances.

poly-sinc-ext2-long

Emphasis [ Space | Balanced | Transients ] → ext2-long | ext2-medium | ext2-short
Note: ‘Transients’ corrects errors less aggressively than ‘Balanced’ or ‘Space’; if it sounds harsh, try another setting.

:radio: Old School

Excellent with classic-era analog recordings. Less aggressive error correction; if it sounds harsh, try another setting.

poly-sinc-short-mp

Emphasis [ Space | Transients ] → -short-lp | -short-mp
Note: use -2s when available

:droplet: The Purist

Passes the original samples through unchanged. Consumes more resources. No error correction: only recommended for the highest technical quality source material.

poly-sinc-gauss-halfband

Emphasis [ Space | Transients ] → gauss-halfband | -gauss-halfband-s

:ambulance: Damage Control

Aggressive clean-up for loudness war-era and other less-than-good material.

poly-sinc-xtr-short-lp-2s

Emphasis [ Space | Transients ] → -lp- | -mp-

:classical_building: The Concert Hall

Emphasizes the recording’s space at the cost of poorer transient performance more than other presets. For material like live classical with minimal transient content. Consumes heavy resources.

poly-sinc-gauss-xla

Version [ The Perfect Ten | Lifelike ] → gauss-xla | ext2-xla
Error correction [ On | Off ] → -xla | -xl
Disabling error correction reduces resource consumption.

2 Likes

Excellent work. Even though personal tastes certainly vary, I think your list is a very good guide that’s useful even without your program.

Since you asked: You could add an option for filters that emulate DAC filters. For example, Mola Moal with xtr-shortSource: https://audiophilestyle.com/forums/topic/19715-hq-player/?do=findComment&comment=1256534

Or Chord DACs: sinc-L Source: Best native DSD DACs for use with HQPlayer? - #2551 by jussi_laako

It’s a shame that so much knowledge is scattered all over the internet without any organization. Your approach is the right one.

Now all that’s needed is a self-installing version of your software for macOS or Windows. Not everyone wants to use Linux.

1 Like

Ooh, I like the idea in spirit, but a few things holding me back:

  1. I’m hesitant to name actual manufacturers in my software
  2. Jussi specifically told me that he would avoid sinc-Lh (imho, the better of the two) for general recommendation purposes.
  3. xtr-short is already in the list as Damage Control :slight_smile:

That said, he also told me to similarly avoid -xlas, and then gave a (sort of de facto) thumbs up to The Concert Hall. I think the key is just to let users know what they’re getting into, as long as the trade-off is clear it should be passable.

So, on those conditions, I’d be down to put a couple of sincs in there. Do you have any non-manufacturer-specific wording in mind? Cause I got nothing there lol.

The only non-starters would be sinc-S and sinc-M*, which are imho the best of the set, because they’re locked into certain rate integers and I want this to work for people without 48k DSD. sinc-Lh can fall back to sinc-long-h when 48k DSD isn’t supported, but sinc-MGa for example has no equivalent fallback.

Trust me, the irony of a highly simplified interface that only works on Linux is not lost on me… but distributing executables properly is expensive and I am highly resistant to the idea of paying out hundreds or more per year for certificates.

If someone were interested in donating the first year’s worth of digital signing, I’d add the executable option right away… until then, unfortunately, Docker is my best distribution option.

1 Like

I’ve got Easy Mode implemented in my dev container and I’m loving it! Even though I’m perfectly capable of rawdogging the default filter list, thinking about it this way is just so much easier and kind of fun. I should have this ready for release in the next few days!

I find the only thing I really miss in using this list are the sinc filters and maybe IIR2.

If anyone has good language that they could suggest for the sinc family, I’d really appreciate it. The best I can do for a name is :mechanical_arm: The Strong-Arm, but I don’t love that because I feel like it implies strong-arming the signal which isn’t the case.

I take back my previous statement that sinc-S and sinc-M* are out-of-bounds: I can just hide those tiles in DSD mode with no 48k rate family support. That also opens up IIR2 as “Full Analog”. And since these are organized in rows of three, I’d also throw a FIR card in there to make a full row.

These would be “bottom-row curiosities” and would need to be clearly labeled as such; users should feel more encouraged to experiment with the top row before scrolling down. For example, the FIR family would need to say something like “What you’re probably used to; here for the sake of comparison”.

Any suggestions are 100% welcome!

EDIT: working copies… not final

:fire: The Crucible

Trial by fire: maximalist, brute-force signal reconstruction with no shortcuts.

Version: [ The Perfect Ten | Lifelike ] → sinc-S, sinc-Mx | sinc-MG, sinc-MGa

Lifelike:
Load [ Low | High ] → -S | -Mx

The Perfect Ten:
Error correction [ On | Off ] → -MGa | -MG

:book: Textbook

The sound of most standard-issue DAC hardware.

asymFIR

Emphasis [ Space | Balanced | Transients ] → FIR | asymFIR | minphaseFIR

:control_knobs: Full Analog

The smooth and relaxed sound of an analog playback chain.

IIR2

1 Like

I’m getting very close to being able to put v1.14.0 up on :beta, pending Jussi’s blessing of tweaks to Easy Mode.

A teaser:

Some significant changes from above, but the biggest are:

  • It no longer conflates length with phase. The old model gave [ Space | Transients ] toggles to both phase and length adjustments, but that was wrong and confusing. I eliminated length as an axis of control entirely, actually.
  • I managed to work in three sinc filters under The Crucible (-MG, -MGa, and -M), as well as IIR2 and (minphase)FIR.
  • Lifelike went from ext2-long to plain ol’ poly-sinc-ext2, a better all-arounder imho (and currently my favorite filter).

Note that the tile rows also work as tiers: the first three are all-purpose; the second are situationally excellent; the bottom are curiosities for the sake of comparison.

But that might not even be the best feature that the upcoming version has to offer, cause I’ve also added:

  • High-frequency filter (née Playback filter) auto-pilot: HQPTuner engages and disengages the HF filter for you.
  • Live presets can now optionally omit fields, meaning if you only want a live preset to change filters but not the rate/modulator, or vice versa, it can do that now! This one is fabulous, I wasn’t even using live presets myself and I eventually recognized that this was the blocker. So I fixed it :slight_smile: and now I use them constantly!
2 Likes

Before I put v1.14.0 into beta, I’ve run into a nasty bug and I need some feedback on how to proceed, because I don’t really use this feature.

It seems that when I built Live mode, I conflated the output rate limit, which cannot be set live, to the bit/sample rate, which can. As a result, if I tell live mode’s rate setting to give me DSD256, it pins the bit rate at 256x48k. This is incorrect as everything at a 44.1k base is then re-clocked to 48k before oversampling, reducing quality and ensuring that any Integer or 2x filter won’t work.

HQPTuner’s intended behavior is

  • Auto rate family always enforced
  • Bit/sample rate is always auto
  • Rate limit is always pinned to the 48k member

This combo lets the engine (correctly) decide the output rate based on the source’s rate family.

But that doesn’t work for live mode: the rate limit can’t be set live, only the active bitrate, which should always be auto from HQPTuner’s perspective. Changing the rate limit always restarts the engine.

There are two ways forward that I see:

  1. Eliminate rate from Live mode. I’m promising a feature I can’t deliver.
  2. Make it possible to set the output bit/sample rate.

1 is far more user friendly.

2 gives the most flexibility, but it means that I break my “friendly sample rates” promise and makes the UI that much more complex by handing the burden of remembering to switch the base rate to the user. I could have the program generate an alert similar to the junk filter suggestions that alert you when you’re mixing base and output families, but are you really watching HQPTuner that whole time?

So…

How should Live mode handle output rate changes?
  • Remove the rate option from Live mode and keep it friendly. I accept restarting the engine to change output rates.
  • Add the option to pin the bit/sample rate, I don’t mind keeping track of source rates myself.
0 voters

Once this is settled and the solution written in, I’ll ship the new code to :beta.

EDIT: yeah, only two votes, but the more I thought about the alternative, the more awful and complicated it became. There was really only one choice, it just took me time to work that out for myself.

1 Like

There is no quality impact doing that. It annoys me a lot every time such misconception pops up. :sweat_smile:

And with 90+% of the DACs on market, DSD input works correctly only with 44.1k multiples. It is important to verify through measurements that 48k-base DSD works correctly with a particular DAC, before enabling the option and using 48k-base DSD output rates. Way too many DACs play 48k-base DSD using 44.1k clock, which results in about 10% slow down / pitch shift. You don’t usually want that. In better cases, you get either silence or just noise as output for 48k-base DSD.

So in 90+% of the cases for SDM output, the output rate selection would practically select the factor, like 128x, 256x, 512x, etc. Since you would be picking one multiple of 44.1k.

So also in 90+% of the cases, you cannot use integer or power-of-two factor filters…

As I said on AudiophileStyle, but I’ll repeat here for the Roon crowd…

I think there’s some confusion and I haven’t been clear: what HQPTuner does is always pin the 48k family member to the rate limit, and then let the 48k DSD setting decide the output rate. Because the 48k DSD setting overrides the output rate limit being at 48k and correctly steps down to 44.1 anyway, it’s safe to set the limit to the 48k family every time.

My issue is that I conflated the rate limit, which can’t be set live, to the bit rate, which can. So, if a user tries to change their output rate on the fly in Live mode, they always get the 48k member. That’s an error on my part in several ways.

Quality implications aside, the outcome is still undesirable as it locks the user out of tons of filters.

Most of the DACs out there do that anyway…