HN user

wrl

511 karma

https://wrl.sh/

wrl on libera/efnet/oftc

Posts4
Comments151
View on HN

looks like it – compiled as debug (native linux x64 backend) gives me the vector type i've asked for. release modes extend to the "native" width.

this is testing in isolation as well, could be that in the midst of other vector code it changes things. llvm definitely does a great job optimising tightly-written vector code to be even faster.

i don't disagree – i have my own internal vector lib of approximations and whatnot for various tradeoffs of precision and speed, so i just use those. it's just that zig has a pretty strong stance of "no unexpected/obscured code execution" so it was surprising to see a vector-capable function that was just a bunch of scalar functions in a trench coat.

maybe functions that don't actually support actual vector execution just shouldn't work on vector arguments. i also wouldn't expect `@sin()` to expand in-place out to a full cephes-like sin implementation. maybe a function call.

ahaaa, yeah, i don't personally do any runtime switching but i hear that as a deal-breaker from other folks.

it's interesting – i've found that zig tends to extend my vectors to the native width of the platform and then operate on them there. e.g. i had a `@Vector(2, f32)` that i was using as a demo and the generated assembly was promoting it to 256 bits and using avx2 instructions on it!

i was having a conversation with a friend recently about simd in zig (which i have recently picked up and been having a pretty good time with). i find that simd writes decently well, though there's a few weird things:

- some builtins purport to work on simd vectors but actually just unpack the vectors and do their work per-element (e.g. running `@sin()` on a `@Vector(4, f32)` will unpack the vector, run `@sin()` 4 times, and then pack it back into a vector).

- a lot of `std.math` is scalar-only (some functions support vectors, though, and i've got a pr open for one of them and plan to do more).

- i'm certainly missing some intrinsics that i get from xmmintrin.h (rcp, rsqrt, few others).

in general though i'm finding it pretty capable.

mitchell, i know you hang around some of these comments sometimes – i noticed that in ghostty you bring in some c++ libs to do the simd heavy lifting for you. any plans to port that to zig? anything missing from the language or libs that's preventing it?

My impression was that the "ghost" comes less from the formal NDA and more from the fact that somebody else produces/writes the work and is uncredited for doing so. Then, the "author"/"producer" passes it off as their own work.

How about "AI ghostwritten"? That's a much closer parallel, and some commercially successful musicians similarly are "ghost produced".

Ideally the alert would only happen if the comment seemed important but it would readily discard short or nonsensical input. That is really difficult to do in traditional software but is something an LLM could do with low effort.

I read this post yesterday and this specific example kept coming back to me because something about it just didn't sit right. And I finally figured it out: Glancing at the alert box (or the browser-provided "do you want to navigate away from this page" modal) and considering the text that I had entered takes... less than 5 seconds.

Sure, 5 seconds here and there adds up over the course of a day, but I really feel like this example is grasping at straws.

This is really interesting – AU's notion of having separate input and output "elements" (buses, more or less) is one of the worst parts of the whole API.

I understand why historically these design decisions were made, but it's not like they really enable any functionality that the other APIs don't. It's just that since the host can call `Render` more than once per sample block (ideally the host would call it once per sample block per element, but there's nothing saying the host can't call it redundantly), there's additional bookkeeping that plugins have to do surrounding the `AudioTimeStamp`. And for what? There's nothing AU can do that the other formats can't.

If a plugin has multiple fully independent buses, the model mostly works, but if there's any interdependence then things get even more complicated. Say you have two separate stereo elements that don't have any routing between them, but there's MIDI input or sample-accurate parameter changes for the given block. Now you have to keep those events around until the host has moved on to the next block, which means the plugin has to maintain even more internal buffering. This sort of lifetime ambiguity was one of the worst parts of VST2. In VST2, how long does MIDI input last? "Until the next call to `process()`." In AUv2, how long do MIDI input data or parameter change events last? "All of the render calls of the next timestamp, but then not the timestamp after that." Great, thanks.

Modern plugins, upon receiving a `Render` for a new timestamp, will just render all of their elements at the same time, but they'll internally buffer all the outputs and then just copy the buffers out per-element-render call. So, it reduces down to the same thing that other APIs do, just with more pageantry.

And yet, plugin instances having to manage their own input connection types is somehow even worse. Again, I understand why it was done this way – allowing plugins to "pull" their own inputs lets an audio graph basically run itself with very little effort from the host – it can just call `Render` on the final node of the chain, and all of the inputs come along for free.

It's a compelling value proposition, but unfortunately it fully prevents any sort of graph-level multithreading. Modern hosts do all sorts of graph theory to determine which parts of the graph can be executed in parallel, and this means that the host has to be in charge of determining which plugins to render and when. Even Logic does this now. The "pull model" of an AU instance directly calling `Render` on its input connections is relic of the past.

Anyway. VST3, CLAP, even VST2 support multiple input and output buses (hell, one of my plugins has multiple output buses for "main out", "only transients", and "everything other than a transient") – it's just a question of host support and how they're broken out. Ironically, Logic is one of the clunkiest implementations of multi-out I've seen (Bitwig is far and away the best).

Historically, there was an API translation layer that VST2 plugins used (called Symbiosis), but these days the vast majority of plugin devs use a framework like JUCE which has multiple different "client-side" API implementations (of VST2, and VST3, and etc) that all wrap around JUCE's native class hierarchy.

There's a few other frameworks floating around (Dplug for writing in D, a few others in C++), but JUCE is far and away the most common.

Oh I forgot about parameters. In VST3, the parameter changes use linear interpolation. So the DAW can predict how the plugin would interpret parameter value between changes and use this to create the best piece-wise linear approximation for automation curve (not merely sampling the curve every N samples uniformly which is not perfect).

Can you link to any code anywhere that actually correctly uses the VST3 linear interpolation code (other than the "again_sampleaccurate" sample in the VST3 SDK)? AU also supports "ramped" sample-accurate parameter events, but I am not aware of any hosts or plugins that use this functionality.

CLAP has no defined interpolation method, and every plugin would interpolate the values in its own, unique and unpredictable way (and if you don't interpolate, there might be clicks). It is more difficult for a host to create an approximation for an automation curve. So with CLAP "sample-precise" might be not actually sample-precise.

Every plugin does already interpolate values on its own. It's how plugin authors address zipper noise. VST3 would require plugin authors to sometimes use their own smoothing and sometimes use the lerped values. Again, I'm not aware of any plugins that actually implement the linear interpolated method. I think Melda? It certainly requires both building directly on the VST3 SDK and also using the sample-accurate helpers (which only showed up in 2021 with 3.7.3).

Anyway, I maintain that this is a bad design. Plugins are already smoothing their parameters (usually with 1 pole smoothing filters) and switching to this whole interpolated sample accurate VST3 system requires a pretty serious restructuring.

Personally, I would have loved having a parameter event flag in CLAP indicating whether a plugin should smooth a parameter change or snap immediately to it (for better automation sync). Got overruled, oh well.

What is the purpose of this? Why does plugin (unless it is a MIDI effect) need values for all controllers? Also, MIDI2 has more than 128 controllers anyway so this is a poor solution.

Steinberg has been saying exactly this since 2004 when VST3 was first released. Time and time again, plugin developers say that they do need them. For what? Couldn't tell you, honestly. In my case, I would have to migrate a synth plugin from MPE to also be able to use the VST3 note expressions system, and I absolutely cannot be bothered - note expressions look like a nightmare.

And this is the chief problem with VST3. The benefits are either dubious or poorly communicated, and the work required to implement these interfaces is absurd. Again – 3 days to implement CLAP vs 3 weeks to implement VST3 and I'm still finding VST3 host bugs routinely.

The short answer is that there really aren't. All extant audio plugin APIs/formats are basically ways of getting audio data into and out of a `process()` (sometimes called `Render`) function which gets called by the host application whenever it needs more audio from the plugin.

Every API has its own pageantry not just around the details of calling `process()`, but also exposing and manipulating things like parameters, bus configuration, state management, MIDI/note i/o, etc. There are differences in all of these (sometimes big differences), but there aren't any real crazy outliers.

At the end of the day, a plugin instance is a sort of "object", right? And the host calls methods on it. How the calls look varies considerably:

VST2 prescribes a big `switch()` statement in a "dispatcher" function, with different constants for the "command" (or "method", more or less). VST3 uses COM-like vtables and `QueryInterface`. CLAP uses a mechanism where a plugin (or host) is queried for an "extension" (identified by a string), and the query returns a const pointer to a vtable (or NULL if the host/plugin doesn't support the extension). AudioUnits has some spandrels of the old mac "Component Manager", including a `Lookup` method for mapping constants to function pointers (kind of similar to VST2 except it returns a function rather than dispatching to it directly), and then AU also has a "property" system with getters and setters for things like bus configuration, saving/loading state, parameter metadata, etc.

I'm not sure why OP is claiming that AU is somehow unopinionated or less limited. It doesn't support any particular extensibility that the other formats don't too.

"opinionated and limited" in what way? I'm also curious to hear how AU differs appreciably from VST3, mostly at a conceptual level (as I'm already familiar with the low-level details of both APIs).

Clap doesn't allow describing plugin in a manifest (like VST3 and LV2 do). This allows to scan for plugins faster.

VST3 only recently gained the `moduleinfo.json` functionality and support is still materialising. Besides, hosts generally do a much better job about only scanning new plugins or ones that have changed, and hosts like Bitwig even do the scanning in the background. The manifest approach is cool, but in the end, plugin DLLs just shouldn't be doing any heavy lifting until they actually need to create an instance anyway.

Also, CLAP uses 3 or 4 methods to represent MIDI data (MIDI1, MIDI1 + MPE, MIDI2, CLAP events). This requires to write several converters when implementing a host.

I've not done the host-side work, but the plugin-side work isn't too difficult. It's the same data, just represented differently. Disclaimer: I don't support MIDI2 yet, but I support the other 3.

On the other side, VST3 has some very strange design decisions that have led me to a lot of frustration.

Having separate parameter queues for sample-accurate automation requires plugins to treat their parameters in a very specific way (basically, you need audio-rate buffers for your parameter values that are as long as the maximum host block) in order to be written efficiently. Otherwise plugins basically have to "flatten" those queues into a single queue and handle them like MIDI events, or alternately just not handle intra-block parameter values at all. JUCE still doesn't handle these events at all, which leads to situations where a VST2 build of a JUCE plugin will actually handle automation better than the VST3 build (assuming the host is splitting blocks for better automation resolution, which all modern hosts do).

duped's comment about needing to create "dummy" parameters which get mapped to MIDI CCs is spot-on as well. JUCE does this. 2048 additional parameters (128 controllers * 16 channels) just to receive CCs. At least JUCE handles those parameters sample-accurately!

There's other issues too but I've lost track. At one point I sent a PR to Steinberg fixing a bug where their VST3 validator (!!!) was performing invalid (according to their own documentation) state transitions on plugins under test. It took me weeks to get the VST3 implementation in my plugin framework to a shippable state, and I still find more API and host bugs than I ever hit in VST2. VST3 is an absolute sprawl of API "design" and there are footguns in more places than there should be.

On the contrary, CLAP support took me around 2 days, 3 if we're being pedantic. The CLAP API isn't without its share of warts, but it's succinct and well-documented. There's a few little warts (the UI extension in particular should be more clear about when and how a plugin is supposed to actually open a window) but these are surmountable, and anecdotally I have only had to report one (maybe two) host bugs so far.

Again, disclaimer: I was involved in the early CLAP design efforts (largely the parameter extension) and am therefore biased, but if CLAP sucked I wouldn't shy away from saying it.

developers who want to make improvements to the codebase that don't get prioritized

So, to clarify – developers want to make improvements to the codebase, and you want to give that work to AI? Have you never been in the shoes of making an improvement or a suggestion for a project that you want to work on, seeing it given to somebody else, and then being assigned just more slog that you don't want to do?

I mean, I'm no PM, but that certainly seems like a way to kill team morale, if nothing else.

I had a frontend engineer, who, when I could just find a way to give him time to do whatever he wanted, would just constantly make little improvements that would incrementally speed up pageload.

Blows my mind to think that those are the things you want to give to AI. I'd quit.

airports are always a nightmare!

the other important thing to keep in mind is that in the EU in general, there's no added taxes on the bill, and tips are less of a thing here, so there's not a magical 20%+ hidden charge to factor in on everything you order.

No, it's the opposite of that. Third-person pronouns are the ones people use to discuss third persons among themselves. The person who "wants their pronouns used" isn't party to the conversation.

That's also how names work, though. As in, "Are you coming to Billy's barbeque?" when Billy is not in the conversation.

At no point in human history, in any human language I am aware of, has anyone ever gotten to choose their own third-person pronouns. It's absurd and bizarre.

What's the realistic difference between pronouns and nicknames? Like a "Richard" going by a "Rich", or "Rick"? That's their decision, right? Or someone choosing to go by their middle name rather than their first name?

By what mechanism would reducing needle and syringe programs lead to fewer needles being left in public places? It's not like access to needles causes people to take up an injection drug habit.

this is really cool, congratulations on the launch!

i'm definitely in your target market - my daily drivers are an 83mm flat burr grinder and a manual lever machine. don't get me wrong, i love them both, but i'm intrigued both by your grinder and espresso machine and i am strongly considering pre-ordering both.

here's my little laundry list of unanswered questions:

1. workflow/usage video! i know it's come up but i definitely am keen to see the grinder and espresso machine both in use.

2. particle size distribution for the grinder would be really cool. i know that distribution isn't everything, but this is a whole new style of burr and people (myself included) are going to be (or already are) very curious about how they compare to existing conical and flat burrsets. also, any word about retention?

3. can the trefolo do pressure profiling? if so, is that profiling based on pre-set shot profiles, or is it live profiling via the knob input, or both?

4. is the group electrically heated, or does all of the preheat temperature come from the hot water? especially for very light roast espresso, i've found that it's just impossible to brew at 96-98°C without electric heating, and there are some shots that i've only been able to get balanced up at those temperatures (they were just pulling way too acidic even at 94).

5. does velofuso have any social media accounts we could follow? where should i be keeping my eyes out for videos, project updates, etc?

Looks like it, that's new! I tried Linear quite some time ago and it didn't "stick", I'll have to give it another shot.

Thanks for the tip!