Threads for wrl

  1. 4

    Can we stop describing software as “beautiful” already?

    1. 2

      Yeah, every time I see a headline like this, I kind of don’t want to click, because I will be like “meh, nice, but beautiful??”..

      Went through and had a look on these. The popups look nice. Author did a good job.

      1. 1

        I’ve never heard any other software describe itself as beautiful before, but I don’t think calling software beautiful is always bad. For example, I like to think that the code of my Bad Code Rocks contest entry is beautiful in how convoluted it manages to be. However, I agree that when trying the demo of this alerts library, I don’t find the alerts beautiful compared to other modal dialog libraries. Maybe “beautiful” is supposed to be relative to the browser’s built-in alert dialogs?

        1. 0

          Every 2nd app on AppStore says it does the same thing as all other apps in its category, but THIS one is beautiful.

          edit: OK, maybe not exactly every 2nd, but there are a lot of those apps.

        2. 1

          I agree with you. So I changed to “Cool”. Cool is cool? ^^

        1. 8

          I’m hoping that Pipewire will be able to unify the JACK and Pulseaudio models. The fact that we have two separate audio servers on Linux (PA for consumer applications, JACK for pro audio) is a bit unfortunate still.

          Remains to be seen, however. My understanding is that Pipewire is still relatively in its infancy.

          1. 2

            Doesn’t this mean it’s just another layer on top?

            kernel-level ALSA → user-level ALSA → PulseAudio → PipeWire

            (It boggles my mind that projects like PipeWire still get developed in C, by the way.)

            1. 5

              (It boggles my mind that projects like PipeWire still get developed in C, by the way.)

              This kind of code generally requires calling a lot of syscalls (or thin wrappers around them), dealing with raw memory buffers and memory mapped buffers and DMA buffers, and you can’t have a GC pausing you every now and then. I wrote a bunch of code like that for work in C++, but it was really just C++ classes wrapping very C-like code.

              If you wanted to write that kind of code in a language which isn’t C or C++, I’m betting you’d have to write a lot of C anyways and build abstractions on top of that using FFI (and FFI generally has performance costs too).

              1. 1

                Use Rust.

                1. 4

                  Eh. It’s a fairly low-risk component owing to the nature of what it handles and how it handles it. By the time the audio or video data gets to the plumbing layers, it’s all just blocks of raw samples or pixels anyway, so there’s less surface area due to the lack of codecs and whatnot.

                  I use Rust for most of my higher-risk work (file formats, parsing, network services, etc), but I still write my DSP and audio code in C. I’ll move to Rust at some point but for some reason I end up fighting the compiler a lot more when I try to do audio/DSP code compared to parsing or whatever.

                  1. 2


                    1. 1

                      Are there any low level audio APIs written in Rust?

                      1. 1

                        Without C FFI, how do I in Rust open a video device and allocate a DMA buffer, then open another video device (say an encoder) whose input is that DMA buffer and whose output is a memory mapped buffer?

                        With C, you just use the v4l2 ioctls as documented, but I suspect it’s not that easy in Rust.

                    2. 5

                      Most of software like this still gets developed in C, so this one’s too.

                      Regardless relative merits of Rust, this can be mindboggling only if one is thoroughly unfamiliar with realities of system development.

                      1. 3

                        I’m familiar with the realities, the reality is what’s horrifying me.

                        “I don’t write bugs”-people writing software in a language in which pretty much every bug can be security-critical.

                        1. 4

                          The reality is no piece of system software can afford to have Rust as build dependency in 2019.

                          1. 3

                            Do you mean because it needs to support architectures that rust doesn’t, or because packaging is awkward (or something else)?

                            1. 5

                              A thing with system software is your subsystem has to be able to go wherever the rest of userspace goes, or else its adoption is severely handicapped.

                              Yes, you should be available on relatively obscure platforms which yet can count in millions of deliveries.

                              Then, your software can’t be too fussy: insisting that you need llvm instead of gcc to build (or vice versa) is a bad idea. Worse yet when you need a certain version of compiler for that.

                              Your subsystem has to be humble and integrate nicely. System projects have their build environments, and getting along with it is essential. In practice, this means automake or cmake based sybsystems are easy to integrate; bringing your own luggage (or should we say cargo) of a build/package system is unappreicated.

                              Mind you on a product venor/application level you have a lot more leeway as you are constrained by your own needs only, so sure then you can package whatever the hell you want.

                          2. 2

                            The perfect is the enemy of the good. If everything has to be rewritten in Rust, nothing would get done.

                            I asked before about a current or in-progress audio library for Linux implemented in Rust. Does one exist?

                        2. 3

                          The buffer overflows will continue until morale improves.

                          1. 2

                            With circular buffers, they’re called overruns or xruns. Depending on implementation, you’ll hear a segment of old audio or a cut.

                          2. 2

                            PipeWire’s audio functionality is meant to replace PulseAudio and jack.

                            1. 4

                              That’s pretty much what every new audio API said in the beginning.

                              1. 2

                                We had others, remember? Gnome esound? KDE’s arts.

                                Being able to make comparability layers for PA and patches a couple of major projects (mpv, mpd, firefox) to use your new tool can be the start of getting other things rolling … or you could end up with the XKCD comic about 15 competing standards.

                                1. 1

                                  How true. I do remember esd, artsd and even alsa (oss was better).

                            2. 3

                              …and those of us who are still using alsa and don’t see what the fuss is all about.

                              But seriously, I would like a new API; I refuse to use pulse on principle, and jack is just too finicky and lacks support.

                              1. 9

                                JACK is effectively a way to share an audio device between multiple applications each which would otherwise require exclusive access to the audio device. It provides really solid latency guarantees and only a slight increase in overhead compared to accessing the ALSA device directly. For better or worse, though, it was written for an ideal world – one in which audio devices never appear or disappear, one in which there is only one audio device (even though there are workarounds for this case).

                                Pulseaudio I understand less. I run it, but only because so many applications seem to require support for it directly now. I do, however, run it on top of JACK (that is, JACK has the device open exclusively and manages PA as another client). Works well.

                                CoreAudio does a fantastic job of handling all of this stuff seamlessly, and I hope we can get there on Linux someday.

                                1. 6

                                  I use jack for everything. It might not have the conveniences of Pulseaudio, but at least it does work at an acceptable latency (I run it at 5ms), when combined with linux-rt, making it an acceptable all-purpose solution.

                                  Pulseaudio can’t handle acceptably low latency, making it unsuitable for pro audio, and thus not an acceptable all-purpose solution.

                                  As Pulseaudio is unfortunately popular and the default in many Linux distributions, if Pipewire can handle low latency and has enough jack api support to appear as a jack server implementation for pro audio applications, I do welcome it and hope it replaces Pulseaudio everywhere.

                                  PREEMPT_RT is still not in mainline, so most distributions will default to high latencies, meaning the problem will not yet be fully solved. But progress is possible, one step at a time.

                                  1. 2

                                    I use the same setup of pa+jack. I don’t use an rt kernel, since I’ve found it’s a bit of a pain to keep updated. I use a latency of 20ms; anything lower causes a bunch of xruns.

                                    1. 1

                                      I do not use pa at all. My fallback is an alsa loopback device, which is fed into jack via alsa_in.

                                      Arch has linux-rt in the aur, and it’s generally relatively up to date. Current is 5.2.17_rt9-1. That’s not far behind mainline, which is 5.3.x.

                                      I avoid mainline. Its latency peaks make me physically sick.

                              2. 1

                                Pipewire is still relatively in its infancy

                                I’ve learned about it a year ago because of Wim Taymans talk at GUADEC and just checked it out and I was happy to see that the NEWS file just got updated so the project seems to be alive which is awesome :-).

                              1. 45

                                RustTL;DR: It’s a very impressive language with a clear vision and priorities, but the user interface needs a lot of work. Also, the collection library is much better than Scala’s.

                                • Generics with <>. It’s 2017 by now, we know it’s a bad idea. One of the reasons why the language suffers from abominations like the “turbofish” operator ::<>.

                                • Strings don’t offer indexing, because it doesn’t make sense for UTF-8. Correct! But Strings offer slicing … WAT?

                                • Misuse of [] for indexed access. Having both () and [] doing roughly the same thing, especially since [] can be used to do arbitrary things, doesn’t make sense. Pick one, use the other for generics.

                                • Inconsistent naming. str and String, Path and PathBuf etc.

                                • :: vs. . is kind of unnecessary.

                                • Mandatory semicola, but with some exceptions in arbitrary places: struct Foo; vs. struct Foo {}

                                • Arbitrary abbreviations all over the place. It’s 2017, your computer won’t run out of memory just because your compiler’s symbol table stores Buffer instead of Buf.

                                • Can someone decide on a casing rule for types, please, instead of mixing lowercase and uppercase names? Some types being “primitive” is an incredibly poor excuse.

                                • Also, having both CamelCase and methods_with_underscores?

                                • Library stutter: std::option::Option, std::result::Result, std::default::Default

                                • iter(), iter_mut(), into_iter() … decide prefix or postfix style and stick with it.

                                • Coercions do too many things. For instance, they are the default way to convert i32 to i64, instead of just using methods.

                                • Also, converting numbers is still broken. For instance, f32 to i32 might result in either an undefined value or undefined behavior. (Forgotten which one it is.)

                                • Bitcasting integers to floats is unsafe, because the bits could be a signaling NaN, causing the CPU to raise an FP exception if not disabled.

                                • Forward and backward annotations: #[foo] struct Foo {} vs struct Foo { #![foo] }. Also /// for normal documentation, //! for module level documentation. Documentation already uses Markdown, so maybe just let people drop a markdown file in the module dir? That would make documentation much more accessible when browsing through GitHub repositories.

                                • Also, documentation can cause compiler errors … that’s especially fun if you just commented a piece of code for testing/prototyping.

                                • Type alias misuse: In e.g. io crate: type Result<T> = Result<T, io::Error> … just call it IoResult.

                                • Macros are not very good. They are over-used due to the fact that Rust lacks varargs and abused due to the fact that they require special syntax at call-site (some_macro!()).

                                • Pattern matching in macros is also weird. x binds some match to a name in “normal” pattern matching, but matches on a literal “x” in “macro pattern matching”.

                                • println! and format! are very disappointing given that they use macros.

                                • Compiler errors … ugh. So many things. Pet peeve: “Compilation failed due to 2 errors” … 87 compiler errors printed before that.

                                1. 8
                                  • Library stutter: std::option::Option, std::result::Result, std::default::Default
                                  • Type alias misuse: In e.g. io crate: type Result<T> = Result<T, io::Error> … just call it IoResult.

                                  How ya gonna square that circle?

                                  1. 2

                                    I think std::io::IoResult would be fine – it would solve the issue of having vastly different Results flying around, while not having single-use namespaces that are only used by one type.

                                    1. 2

                                      The general pattern is to import Io instead. When doing this, IoResult would be jarring.

                                      use std::io;
                                      fn my_fun() -> io::Result<T> {
                                  2. 14

                                    It’s 2017,

                                    I have some news for you, @soc.

                                    1. 3

                                      Haha, good catch. Now you see how old this list is. :-)

                                      The only thing I got to delete since then was “get rid of extern crate”.

                                    2. 3

                                      What’s your preferred alternative to generics with <>?

                                      1. 6

                                        [], as it was in Rust before it was changed for “familiarity”.

                                        Unlike <>, [] has a track of not being horribly broken in every language that tried to use it.

                                        1. 5

                                          How is <> broken?

                                          1. 16

                                            It complicates parsing due to shift and comparison operators.

                                            1. 2

                                              Ah, yeah, that makes sense.

                                            2. 19

                                              Pretty much no language has ever managed to parse <> without making the language worse. The flaws are inherent in its design, as a compiler author you can only pick where you place the badness; either:

                                              • Add additional syntax to disambiguate (like ::<> vs. <> in Rust).
                                              • Have weird syntax to disambiguate (like instance.<Foo>method(arg1, arg2) in Java).
                                              • Read a potentially unlimited amount of tokens during parsing, then go back and fix the parse tree (like in C#).
                                              • etc.

                                              In comparison, here are the issues with using [] for generics:

                                              • None.

                                              For newly created languages (unlike C++, which had to shoehorn templates/generics into the existing C syntax) it’s a completely unnecessary, self-inflicted wound to use <> for generics.

                                              More words here: Why is [] better than <> for generic types?

                                              1. 2

                                                Those are good reasons to not use <>, but as a Haskeller I personally find either style somewhat noisy. I’d rather just write something like Option Int. Parentheses can be used for grouping if needed, just like with ordinary expressions.

                                                1. 2

                                                  Haskell feels like it is in the same category as D, they both just kicked the can a tiny bit further down the road:

                                                  Both need (), except for a limited special-case.

                                                  1. -1

                                                    I don’t see how Haskell kicked the can down the road. The unit type is useful in any language. Rust has a unit type () just like Haskell. Scala has it too.

                                                    I’m not sure what “special case” you are referring to.

                                                    1. 2

                                                      The fact that you still need () for grouping types in generics as soon as you leave the realm of toy examples – just as it is in D.

                                                      (Not sure what’s the comment on the unit type is about…)

                                                      1. 4

                                                        Ah, I understand what you’re saying now. But that’s already true for expressions at the value level in most programming languages, so personally I find it cleaner to use the same grouping mechanism for types (which are also a form of expressions). This is especially applicable in dependently typed languages where terms and types are actually part of the same language and can be freely mixed.

                                                        However, I can also appreciate your argument for languages with a clear syntactic distinction between value expressions and type expressions.

                                          2. 1

                                            D’s use of !() works pretty well. It emphasizes that compile-time parameters aren’t all that crazy different than ordinary runtime parameters.

                                            1. 1

                                              I prefer my type arguments to be cleanly separated from value arguments (languages that fuse them excepted).

                                              I find D’s approach slightly ugly, especially the special-cases added to it.

                                              1. 1

                                                I prefer my type arguments to be cleanly separated from value arguments

                                                Well, in D they aren’t type vs value arguments, since you can pass values (and symbol aliases) as compile-time arguments as well. That’s part of why I like it using such similar syntax, since it isn’t as restricted as typical type generics.

                                                I find D’s approach slightly ugly, especially the special-cases added to it.

                                                The one special case is you can exclude the parenthesis for a single-token CT argument list and actually I thought I’d hate it when it was first proposed and I voted against it… but now that it is there and I used it, I actually like it a lot.

                                                Sure does lead to a lot first timer questions on the help forums though… it certainly isn’t like any other language I know of.

                                          3. 2

                                            Also, converting numbers is still broken. For instance, f32 to i32 might result in either an undefined value or undefined behavior. (Forgotten which one it is.)

                                            Yeah, I kind of feel the same way. Even with try_from() dealing with number conversions is a pain in Rust.

                                            1. 1

                                              You saved me a lot of typing. 100% agree.

                                              1. 1

                                                Thanks! I’d love to know the reason why someone else voted it down as “troll” – not because I’m salty, but because I’m genuinely interested.

                                              2. 1

                                                2 pains I have with Rust right now:

                                                • I would like to be able to connect to a database (Teradata specifically)
                                                • I want to launch a subprocess with other than the default 3 stdio descriptors (e.g. exec $CMD $FD<>$PIPE in sh)
                                                1. 2

                                                  I know it’s technically unsafe and that might preclude it from your use, but does CommandExt::pre_exec not fit your bill?

                                                  1. 2

                                                    That could work. I’m still new to Rust so I haven’t fully explored the stdlib.

                                                2. 1

                                                  Ahahaha, this is a great list. I’m curious about a couple things though, since you’ve obviously put a lot of thought into it…

                                                  Bitcasting integers to floats is unsafe, because the bits could be a signaling NaN, causing the CPU to raise an FP exception if not disabled.

                                                  The docs for f32::from_bits() and such talk about precisely this, but I considering the misdesign of signaling NaN’s really don’t see how it could possibly be made better. Any ideas?

                                                  …They are over-used due to the fact that Rust lacks varargs…

                                                  What little experience I have with programming language design makes me feel like varargs are a hard problem to deal with in a type-safe language, at least if you want to allow different types for the args (instead of, say, forcing them all to be what Rust would call &dyn Display or something). Do you know of any language which does it Right?

                                                  1. 1

                                                    The docs for f32::from_bits() and such talk about precisely this, but I considering the misdesign of signaling NaN’s really don’t see how it could possibly be made better. Any ideas?

                                                    Rust could have disabled the trapping of signaling NaN’s on start up, but I think Rust fell into the same design mistake of C:

                                                    Scared of making the use-case of the 0.01% (people who want signaling NaN’s to trap) harder to achieve, they made life worse for the 99.99%.

                                                    varargs are a hard problem to deal …

                                                    Agreed, it’s safe to say that language designers hate them. :-)

                                                    … at least if you want to allow different types for the args

                                                    I think this is only partially the reason. You can still have only same-typed varargs at runtime, but allow recovering the individual types of the arguments in macro calls – which is exactly the case for format! and friends.

                                                    Do you know of any language which does it Right?

                                                    I think in the case of format strings, focusing on varargs is the wrong approach. If you imagine how you want an ideal API to look like, you probably want to interpolate things directly inside the string, never having to go through the indirection of some vararg method.

                                                    Instead of having the formatting parameters in one place, and the to-be-interpolated values in a different one, like in …

                                                    let carl = "Carl"
                                                    let num = 1.234567;
                                                    format!("{}'s number is {:.*}, rounded a bit", carl, 2, num)
                                                    // -> "Carl's num is 1.23, rounded a bit"

                                                    … wouldn’t it be much nicer to write (this is Scala):

                                                    val carl = "Carl"
                                                    val num = 1.234567
                                                    f"$carl's num is $num%.2f, rounded a bit"
                                                    // -> "Carl's num is 1.23, rounded a bit"
                                                    1. 1

                                                      Julia has nice string interpolation too. I honestly don’t understand why more programming languages don’t have it. Does everyone just forget how useful it is in bash when they come to design their language?

                                                1. 6

                                                  I don’t see the value of complaints against SPAs anymore. That ship has sailed about a decade ago! The reasons are about as complex as the reasons for the popularity of the web platform itself. It’s not the best solution, but nothing on the web ever is. Instead, it’s providing a particular set of tradeoffs such that many developers prefer it – even while taking user experience into consideration. For example, can anyone suggest how to make an old school web application that works offline?..

                                                  (Although I’ll admit, I’m prone to criticising the web platform myself on occasion. The whole thing, including SPAs, is really a terrible kludge. Nonetheless, I only make SPAs and not old school web applications.)

                                                  (Oh, and it’s also very useful to distinguish between web sites and web applications, but for some reasons these complaints rarely do.)

                                                  1. 21

                                                    I don’t see the value of complaints against SPAs anymore.

                                                    I don’t see the value of this statement specifically. Even though SPAs are a step backward in a multitude of ways, it’s just how the world works now and we should all just accept that the ship has sailed?

                                                    can anyone suggest how to make an old school web application that works offline?

                                                    Look, I’m just trying to be able to still use the web on mobile when my connection is spotty. I think it’s a cool party trick that webapps can be cached entirely in service workers (or whatever) in order to make them work offline, but I’m just trying to read one article and then go about my day. But now, I’m sitting here on the metro waiting 20 seconds for a newspaper site to load.

                                                    Does a content site (like a newspaper or blog) need to work offline? If not, why do people build them with stacks that cause drawbacks in other areas (such as, from TFA, being slower overall).

                                                    (Oh, and it’s also very useful to distinguish between web sites and web applications, but for some reasons these complaints rarely do.)

                                                    It’s because everything is an SPA now. Newspapers, shopping sites, blogs. I think it’s great that rich applications can be built now – I use a fair share of web applications day to day! Mail client, Trello, couple of others. I’ve been in the “SPA haters’ club” for a few years now, consuming plenty of content to confirm my bias, and I’ve never heard anybody say “I sure wish Trello worked with JS turned off.” I’ve experienced a lot of “why do I have a running service worker for this shopping site?” or “why does this page show up blank with JS disabled and then it turns out to just be a blog post with no images once I turn JS on and reload?”

                                                    1. 4

                                                      Well, so you see the value of SPAs, right? Your issue is that content sites use this architecture when they don’t need to, and do it at the expense of UX in some cases. OK, fine, but that’s not the same as saying “SPAs are useless, and we could do anything and everything by loading individual pages from the server”. Well, no, we can’t.

                                                      So my problem is that the complaints like the OP are usually a vague handwavy appeal to how wonderfully simple and fast it is to load pages from the server, usually combined with pointing fingers at a content site like MDN, and without taking the trouble to address any of the use cases for which that approach doesn’t work.

                                                      We shouldn’t just accept things as they are, but I think the specific ship that sailed is for complaints about SPAs vs plain old web pages in the context of web applications. There was a point when things could have gone a different way, but that was in 2004-2008, if memory serves. Now it would be far more productive to frame complaints in the modern context, where we have complex applications all over the web, which can’t be turned into simple web pages.

                                                      I hope this clarifies things.

                                                      1. 16

                                                        Your comment appears to be replying to a point I didn’t make, and I’m frustrated by it, so I will reiterate.

                                                        We’re not talking about Trello and Google Docs. We’re talking about Medium, or any Squarespace or Wix site (which don’t work without JS).

                                                        There’s somebody like you in the comments of every article like this. “Don’t forget about web applications! You know, the ones that absolutely require client-side dynamism!”

                                                        Nobody’s forgotten about them. It’s impossible to. They’re everywhere. Your use-case is handled already. But now, everybody wants to build SPAs by default, even when doing so doesn’t provide any benefit. That’s the problem.

                                                        1. 2

                                                          You’ve conveyed your frustration perfectly. I understand your point, I agree to a degree, and I think it’s fine to criticise this application of SPAs.

                                                          I could still suggest some benefits of SPAs even for content sites on the development side, but I don’t want to exasperate you any further. Thanks for the discussion.

                                                          1. 7

                                                            For many many years I’ve blocked cookies by default, and only opened exceptions for sites I wanted to use in ways that required a cookie.

                                                            In more recent years I’ve also been blocking local storage by default and opening the occasional exception for a site I want to use that has a justifiable reason for needing it. But a staggering percentage of content-oriented things just flat-out break if you deny local storage, because A) they’re actually massive JS applications and B) nobody involved in their development ever considered this case (while people do seem to at least recognize when you disallow cookies).

                                                            For example, the browser I’m in right now does not have an exception for GitLab, so even trying to view a README of a repository in GitLab’s UI will fail with an eternally-spinning “loading” indicator and shows TypeError: localStorage is null in the browser console.

                                                            1. 1

                                                              I guess you’ve considered it, but for this reason self-destructing cookies (aka Cookie AutoDelete for Firefox) is much better at preventing breakage with most of the benefits of compete blocking

                                                              Rather than broken sites, as a European I only have to contend with endlessly confirming GDPR notices for sites I’ve already visited (although thankfully there is also a plugin for that!)

                                                      2. 2

                                                        Does a content site (like a newspaper or blog) need to work offline?

                                                        Would e-readers be better if they required an always-on internet connection? I think there’s a lot of value in not needing an internet connection just to read… (Although many offline SPAs are poorly-written, or loaded with slow trackers, ads, fullscreen modals asking for your email address, etc.)

                                                        1. 3

                                                          It’d be nice if I got to make the decision myself as to whether I want to read an article from the same source again before they cache their entire backlog for me. (slight hyperbole)

                                                          Personally I believe that ATOM is still the best designed way of accessing articles offline, and advancements in that system would be much more beneficial than pushing SPAs. Things like encouraging sites to actually put the full article in, rather than just a link to the website I’m trying to avoid.

                                                      3. 7

                                                        Every old-school website I’ve ever used works just fine offline. “File” -> “Save As”.

                                                        1. 2

                                                          Web application, not site.

                                                          1. 2

                                                            See my sentence above about the distinction between websites and web applications.

                                                            1. 5

                                                              For example, can anyone suggest how to make an old school web application that works offline

                                                              Maybe I’m showing my age here, but an ‘old school web application’ means flash, to me - and those overwhelmingly worked perfectly when you saved the page.

                                                              1. 2

                                                                So do you think we should go back to the good old days of Flash and Java applets? You’ll probably recall that Flash had a bad track record for security and energy efficiency. This critique by Steve Jobs is still pretty good (even if hypocritical).

                                                                I don’t recall that saved .swf files were able to maintain any state either. Were they?

                                                                1. 2

                                                                  So do you think we should go back to the good old days of Flash and Java applets?

                                                                  I know as well as you do how much of a dumpster fire flash security was. Java applets were… less disastrous, but I never saw one that wasn’t deeply unpleasant to use.

                                                                  I don’t recall that saved .swf files were able to maintain any state either. Were they?

                                                                  Very few applications maintain state after you close & reopen them. You could, though - flash applets could work with files on your computer (they had to use the flash builtin filepicker and only got access to files chosen through it).

                                                                  1. 1

                                                                    So in comparison to how things were with Flash and Java applets back then, don’t you think SPAs are an improvement? Sure, they might be overused from the user’s point of view, but that’s not the same as saying they can easily be dispensed with by reimplementing with server-side page rendering.

                                                                    Re state: that also doesn’t seem like a great user experience in comparison to SPAs.

                                                                    1. 2

                                                                      You’ve put words in my mouth two comments in a row.

                                                                      The way you have chosen to communicate does not reflect well upon you, and I’m not interested in engaging further.

                                                                      1. 1

                                                                        I’m sorry if it came across that way, that’s not how I meant it. I was just asking questions to understand what you think. The comment re “they can easily be dispensed with” was more an interpretation of the OP, which is what I thought we were talking about.

                                                                2. -1

                                                                  It’s kinda sad that you read “old-school website” and your brain instantly auto-corrects it to “old-school web application”.

                                                                  EDIT: I missed a message from the thread there.

                                                                  1. 2

                                                                    Did… did you read the thread, or just reply to one comment in isolation?

                                                                    1. 0

                                                                      Yep, I missed a message in the middle there. Sorry!

                                                                      1. 1

                                                                        No worries than :)

                                                          1. 6

                                                            Please, please, please don’t use a GUI toolkit like this, that draws its own widgets rather than using platform standard ones, when developing a plugin for a digital audio workstation (e.g. VST or Audio Unit), as this author is apparently doing. Unless someone puts in all the extra effort to implement platform-specific accessibility APIs for said toolkit. Inaccessible DAW plugins are a problem for blind musicians and audio engineers because of GUI toolkits like this one. Maybe screen readers will eventually use some kind of machine learning to provide access to otherwise inaccessible GUIs, but that’s probably still a long way off. So for now, we need application developers to do their part.

                                                            I don’t actually know what the best cross-platform solution is. Is wxWidgets fully functional in a context where it doesn’t own the event loop? I suspect not on Windows in particular. Yes, yes, I know it’s ugly 90s C++, but really, what’s more important, code aesthetics or usability?

                                                            1. 5

                                                              Unfortunately, there’s no way to make platform standard widgets work in audio plugin UIs on Linux. On Mac and Windows, yes, you can do this, but I’m not aware of any company that does. Perhaps Sinevibes ships their Mac plugins with some custom skinning on top of AppKit widgets. On Linux, by the way, this is a combination of event loop issues and dynamic linking. Trying to run a GTK2 UI inside of a GTK3 app is apparently completely broken on account of this.

                                                              Aesthetics matter in these applications, and there are plugin companies that have built reputations on the back of their user interfaces (Fabfilter in particular comes to mind).

                                                              Say, for example, that I’ve developed a UI engine like this and I’d like to implement the platform-specific accessibility APIs for it. Do you have any good resources for what that code should look like?

                                                              1. 2

                                                                Isn’t this just a matter of adding the necessary accessibility hooks in the widgets? No saying it is easy but surely there is a way to write a GUI library that draws directly to the screen and has good accessibility features.

                                                                1. 2

                                                                  In principle, yes. In practice it seems it’s a ton of work to DIY the integration with every platform’s hooks, and nobody has sufficiently abstracted the various a11y APIs to provide a simpler cross-platform library that you could plug into. As a result I believe the only non-native GUIs that have managed to produce decent cross-platform support for mapping their GUI widgets to the platform’s a11y systems are the major browsers, which are obviously huge codebases with a lot of dev resources.

                                                                  There are some initial attempts in other toolkits, but I don’t think any of them work well on more than one platform. GNOME is cross-platform but has a good a11y story only on Linux, with a very basic start at porting any of it to Windows. Mono at various points had a start at hooking into things on multiple platforms, but I’m not sure what the current state of things in the post-Mono .NET world is.

                                                              1. 22

                                                                This seems like a good set of things that I’d like to regularly check in on. Posting it here in case anyone is of a similar mind after watching the video. (I had to scrub back through it - maybe item 0 should be: I take notes when watching presentations?)

                                                                1. I can articulate precisely what problem I am trying to solve.
                                                                2. I have articulated precisely what problem I am trying to solve.
                                                                3. I have confirmed that someone else can articulate what problem I am trying to solve.
                                                                4. I can articulate why my problem is important to solve.
                                                                5. I can articulate how much my problem is worth solving.
                                                                6. I have a Plan B in case my solution to my current problem doesn’t work.
                                                                7. I have already implemented my Plan B in case my solution to my current problem doesn’t work.
                                                                8. I can articulate the steps required to solve my current problem.
                                                                9. I can clearly articulate unknowns and risks associated with my current problem.
                                                                10. I have not thought or said “I can just make up the time” without immediately talking to someone.
                                                                11. I write a “framework” and have used it multiple times to actually solve a problem it was intended to solve.
                                                                12. I can articulate what the test for completion of my current is.
                                                                13. I can articulate the hypothesis related to my problem and how I could falsify it.
                                                                14. I can articulate the (various) latency requirements for my current problem.
                                                                15. I can articulate the (various) throughput requirements for my current problem.
                                                                16. I can articulate the most common concrete use case of the system I am developing.
                                                                17. I know the most common actual, real-life values of the data I am transforming.
                                                                18. I know the acceptable ranges of values of all the data I am transforming.
                                                                19. I can articulate what will happen when (somehow) data outside that range enters the system.
                                                                20. I can articulate a list of input data into my system roughly sorted by likelihood.
                                                                21. I know the frequency of change of the actual, real-life values of the data I am transforming.
                                                                22. I have (at least partially) read the (available) documentation for the hardware, platform, and tools I use most commonly.
                                                                23. I have sat and watched an actual user of my system.
                                                                24. I know the slowest part of the users of my system’s workflow with high confidence.
                                                                25. I know what information users of my system will need to make effective use of the solution.
                                                                26. I can articulate the finite set of hardware I am designing my solution to work for.
                                                                27. I can articulate how that set of hardware specifically affects the design of my system.
                                                                28. I have recently profiled the performance of my system.
                                                                29. I have recently profiled the memory usage of my system.
                                                                30. I have used multiple different profiling methods to measure the performance of my system.
                                                                31. I know how to significantly improve the performance of my system without changing the input/output interface of the system.
                                                                32. I know specifically how I can and will debug live release builds of my work when they fail.
                                                                33. I know what data I am reading as part of my solution and where it comes from.
                                                                34. I know how often I am reading data I do not need as part of my solution.
                                                                35. I know what data I am writing as part of my solution and where it is used.
                                                                36. I know how often I am writing data I do not need to as part of my solution.
                                                                37. I can articulate how all the data I use is laid out in memory.
                                                                38. I never use the phrase “platform independent” when referring to my work.
                                                                39. I never use the phrase “future proof” when referring to my work.
                                                                40. I can schedule my own time well.
                                                                41. I am vigilant about not wasting others’ time.
                                                                42. I actively seek constructive feedback and take it seriously.
                                                                43. I am not actively avoiding any uncomfortable (professional) conversations.
                                                                44. I am not actively avoiding any (professional) conflicts.
                                                                45. I consistently interact with other professionals, professionally.
                                                                46. I can articulate what I believe others should expect from me.
                                                                47. I do not require multiple reminders to respond to a request or complete work.
                                                                48. I pursue opportunities to return value to the commons (when appropriate.)
                                                                49. I actively work to bring value to the people I work with.
                                                                50. I actively work to ensure underrepresented voices are heard.
                                                                1. 2

                                                                  Thanks for compiling the list. For checking back regularly, I’d prefer to have a copy of the list with the game development related bullets removed. I think this level of obsession with performance is relevant to only certain domains. I’m not saying it’s ever unimportant, but the focus in this list is too much.

                                                                  1. 7

                                                                    People thinking performance only matters in games is why browsers keep getting slower, why Word takes as long to start now as it does, and why having Slack desktop app open keep you from running anything else.

                                                                    We can’t ignore that and still treat ourselves as serious developers.

                                                                    1. 1

                                                                      As I’ve already indicated, I think performance is important. But as a paid engineer, your first objective is to maximize the metrics that make the business succeed. As a back-end developer I already have to juggle a lot of complexity, and I won’t let performance concerns complicate the code and make the problem exponentially worse. No more than absolutely necessary, at least.

                                                                      1. 0

                                                                        So, select star order by random limit one then since it’s easier to maintain?

                                                                    2. 2

                                                                      There’s nothing in the list that’s game development specific. On the subject of the performance related items, there’s nothing saying “I will write fast code and optimise it to within an inch of its life (or my own life).” Just “I measure it” and “I know how to make it faster if I need to.”

                                                                      That’s too much?

                                                                      1. 2

                                                                        I’ve just made peace with the fact that I have to repeat I don’t think it’s unimportant.

                                                                        I’m just saying it’s given too much focus. Look at how many of those bullet points are about performance, while there’s only one that’s partially about architecture.

                                                                        In some problem domains, your business competes on performance (among other things). In those domains (like game development) you spare a big chunk of your brain to constantly evaluate every decision you take on its performance implications.

                                                                        In some other domains (like web applications), performance affects the business only when it’s very costly on the servers or when it degrades the user experience. Businesses compete on their ability to change and adapt. In those domains, you know performance can become an issue if you screw up, but you’re not constantly thinking about it. What you’re thinking about all the time is the architecture.

                                                                        And you can turn the argument around. The architecture is important in game development as well, but less so than web, because you spend years building a game, and any change in requirements is a fault of your own. And when you release, most games don’t even try to stay compatible with the save files produced with the previous versions. And the players are OK with it.

                                                                        Please don’t turn this into a black and white thing.

                                                                  1. 4

                                                                    Very much in support.

                                                                    DSP is going to be more general (image processing, radio stuff), but that’s all still quite interesting.

                                                                    1. 5

                                                                      Any relation to actual wavelets?

                                                                      Also, I think it’s a bit disrespectful to create a protocol called Noise while there’s already a Noise protocol which is modern, actively developed, and already in use. Was the team simply unaware?

                                                                      Sorry to bikeshed on the names, but it irks me when projects pop up that haven’t done that small amount of due diligence (“is there anything else called this already?”).

                                                                      1. 1

                                                                        To be fair, naming things is hard.

                                                                        I’m moderately confident all this stuff will be forgotten in 6 months, unless the developers exit scam with all the funds.

                                                                      1. 2

                                                                        I’d just like to say how happy I am to see a VST, and other VST authors, here on my front page of :)

                                                                        1. 1

                                                                          Hey, happy to be here! :D

                                                                        1. 2

                                                                          I love classic FM synthesis, as well as analog synthesis in the west coast tradition of Buchla and Serge.

                                                                          One thing they have in common is that they don’t rely on filters to control harmonics, like in classic analog subtractive synthesis. It’s a fun and different way to think about sound sculpting.

                                                                          You instrument is really cool, and the demos sound great! They also lean pretty heavily on the analog-style filter (at least that’s what it sounds like), and I’d really like to hear some demos that show off this other style of expression.

                                                                          I’m playing around with the demo as I write this, trying to get a feel for it. :)

                                                                          1. 3

                                                                            Yeah I can see how the filter can seem like it isn’t necessary – to be honest, I’ve been using Cadmium in my own tracks since long before I got the filter in. For me, the filter serves the same purpose that the filter in the Mutable Instruments Shruthi-1, in which the oscillators are 8-bit and come from an Arduino, but there’s anan analog filter board attached, and it helps smooth the sound and make it more versatile.

                                                                            Cadmium’s oscillators are unabashedly digital, and VPS is hard to anti-alias. I did a pretty admirable job (IMHO) but things can definitely still get out of control. For me, the filter adds versatility and character, especially in those instances.

                                                                            Still, you’re right – I could see about adding some “raw VPS” presets that have the filter turned off.

                                                                            1. 1

                                                                              For me, the filter serves the same purpose that the filter in the Mutable Instruments Shruthi-1

                                                                              Absolutely. I think it’s a great feature; I love the combination of crude, digital oscillators and analog filter, like in the SID chip. I was just interested in hearing other aspects of the instrument, too.

                                                                              VPS is hard to anti-alias

                                                                              I can imagine! I made a simple FM synthesizer, and I read a lot of papers about it. I’m not a DSP person, so I ended up just oversampling a lot, and constraining the parameter ranges a bit. Sometimes aliasing and quantisation noise can sound nice though, for that gritty, retro sound.

                                                                              1. 3

                                                                                Actually, it occurred to me that a few of my favourite patches are almost exclusively VPS – it’s the three “WRL hollow/hollower/hollowest lead” ones in the factory bank. The filter is there for a bit of character but you can turn it off to get a better feel for the sources.

                                                                          1. 4

                                                                            You’ve got at least one audio synthesis nerd in your audience here! Looks nice, sounds nice, and I’m glad to see work like this. I’m going over somewhat similar ground, but doing the work in Rust.

                                                                            Do you do the DSP computations using SIMD? That’s one of the areas I’m focused right now. My latest explorations get sinewave generation in under half a nanosecond. That’s without modulation, though the algorithm is designed to be phase-modulable.

                                                                            Regarding other resources, I pointed to three books when a similar question came up. One of those is available online. Interesting how little overlap there was!

                                                                            1. 4

                                                                              Raph, it’s a pleasure to see you here! Long-term I would like to gradually move to Rust as well, but shipping 1.0 has naturally been the priority up until now.

                                                                              I’m doing a fair amount in SIMD, basically all xmmintrin.h. I am in fact using a heavily modified version of your state-space ladder filter, with nonlinearities, and extended to support pole mixing (which was no easy feat). It’s still not as efficient as I’d like, so my next steps are to further unroll the matrix construction (I already assemble them from unrolled versions of your bilinear version). I’m very interested in seeing your accelerated sine work – I’m using somebody’s SSE2 version which is accurate but not particularly fast currently. Oh, and I have an SSE2 implementation of your tanh approximation if you’d like it. :)

                                                                              1. 3

                                                                                Hah, excellent. Glad to see you adapted and extended my stuff, that’s very much what I was hoping for. I can see that pole mixing would be hard with the nonlinearities.

                                                                                Not to be too smug, but I think I’ve got SIMD tanh covered. I was planning on targeting SSE4.2 as a minimum, but I’ll probably have some SSE2 fallbacks in there, as you can absolutely count on it for x86_64 and going all the way to scalar would be quite a hit.

                                                                                1. 2

                                                                                  Not smug at all – and, coming from you, I believe it! Very interested to see what your approach is.

                                                                                2. 2

                                                                                  I would like to gradually move to Rust as well

                                                                                  My colleague will be giving a talk about this at ADC this year that you may be interested in (scroll down to “An introduction to Rust for audio developers” on IIUC this will be live-streamed, but I know ADC puts up past talks online as well.

                                                                                  1. 4

                                                                                    Yeah, I saw that! For context, I’ve actually been using Rust professionally for a few years now, mostly for back-end network services, but I also gave a talk at the first Rustfest back in late 2016 about reverse-engineering USB HIDs, using the NI Maschine as my specimen.

                                                                                    I wanted to start with my UI layer, but I make heavy use of inheritance and sub-classing in Rutabaga, and that’s not going to be easy to port. I could probably find other ways of implementing the kind of toolkit I want, but that’s R&D I just haven’t spent time on yet. Soon, soon (probably).

                                                                                    I’ll check the livestream. Can’t make it out there in an official capacity this year, but perhaps next year. :)

                                                                                    1. 2

                                                                                      Very interesting, I did not know about that. It’s a week after a talk I will give at the SF Rust meetup with somewhat similar goals (“Fearless low-latency audio synthesis”). I’d be more than happy to chat with him about what I’m doing.

                                                                                1. 2

                                                                                  As someone who has no experience with any of this, what should I be listening for in the audio samples?

                                                                                  1. 3

                                                                                    By and large, it’s subjective. In the sound demos on the site, all of the tonal (i.e. not drums) sounds were made with Cadmium, so it serves to give producers and musicians a brief taste of what Cadmium could sound like in their own work.

                                                                                  1. 6

                                                                                    First of all - congratulations on the release! This looks cool and I’ll definitely try it out.

                                                                                    So to ask an audio developer anything: How did you (and how can I) get into DSP/audio programming? I’m thinking mostly resources to learn both the concepts and math of DSP, as well as the tricks of the trade in writing fast DSP code. It seems like if you want to learn ML, or compilers, or OS-design, etc, there are piles of good books, tutorials and videos available – but I’m having trouble finding good resources to learn audio stuff. Do you have any tips?

                                                                                    1. 11

                                                                                      I had my introduction to signal processing with a course at the university. At least I can recommend some books for you:

                                                                                      PS: I think’ needs an dsp tag.

                                                                                      Edit: typos.

                                                                                      1. 1

                                                                                        There’s at least two tags we need that will cover lots of articles that people might filter if we get too specific on application area or arcane internals users of black-box tools don’t need to know. Relevant here is “parallel:” techniques for parallel programming. It’s already a huge field that HPC draws on. It can cover DSP, SIMD, multicore, NUMA, ways of stringing hardware together, parallel languages, parallelizing protocols, macros/libraries that parallelize, and so on. I plan to ask the community about the other one after I collect relevant data. Mentioning this one here since you already brought it up.

                                                                                      2. 4

                                                                                        Hey, thanks! Do feel free to reach out and let me know what you think.

                                                                                        With regards to DSP literature – klingtnet has provided some great resources already, so I’ll just talk a little about my path. My background has always just been in development, and my math has always been weak. Hence, the best resources for me were studying other people’s code (for which github is a particularly great resource) and figuring out enough math to implement research papers in code.

                                                                                        Audio DSP has this weird thing going on still where companies in the space are generally incredibly guarded about their algorithms and approaches, but there’s a few places where they’ll talk a little more openly. For me, those have been the music-dsp mailing list and the KVR audio DSP forum. The KVR forum in particular has some deep knowledge corralled away – I always search thorough there when I start implementing something to see how others have done it.

                                                                                        And, one final little tidbit about DSP: in real-time, determinism is key. An algorithm which is brutally fast but occasionally is very slow could be less useful than one slower but more consistent in its performance. Always assume you’re going to hit the pessimal case right when it’s the most damaging, and in this industry those moments are when a user is playing to a crowd of tens of thousands.

                                                                                        That being said, I’d encourage just jumping in! Having a good ear and taste in sound will get you further than a perfect math background will.

                                                                                        1. 4

                                                                                 is a really well done interactive intro to the basics (note that the top part is the table of contents, you’ll have to click there to navigate).

                                                                                          1. 1

                                                                                            Thanks a lot for this, I just finished and felt like I finally got some basic things that eluded me in the past. Good intro!

                                                                                        1. 7

                                                                                          Late last week I did a soft launch of my synthesizer VST plugin slightly ahead of schedule due to a high-profile electronic musician using it on a Twitch stream for several hours. It was unexpected, but served to force my hand somewhat in regard to putting the website and final 1.0 builds up.

                                                                                          Next steps for me are finishing up the user manual and then doing a PR push of some sort – posting on forums, making a bit of noise about it. It’s my first time releasing a product on my own, and a B2C one at that, so there’s a lot of learning to be done still, but, hey, on the home stretch of the home stretch now.

                                                                                          1. 3

                                                                                            Could you give a bit more information on the performance? Who exactly has used the plugin, and is there a recording of it? Thanks!

                                                                                            1. 2

                                                                                              Of course! It was Deadmau5, and there’s an archive of the stream on his Twitch channel.

                                                                                              1. 1

                                                                                                That indeed is as high-profile as they get! Congratulations!

                                                                                          1. 2

                                                                                            As memory (hah) serves, this is useful when doing things that require low-latency stuff like signal and audio processing.

                                                                                            1. 1

                                                                                              Circular buffers are definitely used all the time in audio, but actually not for the performance – they’re used because they’re lock-free as long as there’s only one writer and one reader. Any sort of blocking operation in the audio/realtime thread is verboten, so circular buffers provide safe ways of message passing or buffering audio to/from other threads.

                                                                                            1. 4

                                                                                              Red author here, feel free to ask any question about it.

                                                                                              1. 2

                                                                                                Hey, I’m interested in potentially using Red as an embedded glue language in a multimedia application. Am I correct in thinking that the next release (coming sometime in July?) is going to focus on the embedding use-case?

                                                                                                edit: Unrelated follow-up: is there any roadmap for 64bit support?

                                                                                                1. 3

                                                                                                  You’re correct, next release will allow properly wrapping of the whole runtime and user apps in a shared library, for all our supported platforms (including cross-compilation), and expose a C-level API (so, callable from any other language with FFI support).

                                                                                                  For 64-bit, it’s not yet in the roadmap, as we need first to make some design decisions with regard to our memory model, we would like not to double the size of the current 128-bit cells size we rely on for boxed types. Once that done, we’ll need to add a 64-bit emitter for our code backends, and finally extend the linker for 64-bit support. So, as our short-term roadmap is very dense already, it’s unlikely we’ll be able to complete all that this year (though, iOS support requirements might push that work higher in our priority list).

                                                                                              1. 5

                                                                                                So, this is my first post in one of these threads. My primary project at the moment is a software synthesizer as a VST plug-in.

                                                                                                This past weekend, I got another beta/alpha built and distributed to a small pool of testers, and this week I’m handling the ensuing bug-reports (which include null pointer derefs, various openGL platform issues, and just a wonderful smörgåsbord of smaller things). I’ve brought a designer on, so I’m looking forward to the UI (which currently looks like this) becoming less perfunctory and nicer both to look at and use.

                                                                                                1. 1

                                                                                                  I’m an amateur synth buff, so if you have an OSX VST or AU available I’d be happy to help you test!

                                                                                                  1. 1

                                                                                                    Sure, I’ll drop you an email. Always good to have more people kicking the tires.

                                                                                                  2. 1

                                                                                                    a VST plug-in.

                                                                                                    Does it crash every 5 minutes, taking down the host application? Just kidding :) In my company’s experience that seems to be a common problem with 3rd party VST plugins. IIRC we now start a separate process for every call to a VST plugin so that it doesn’t take down our whole application when it inevitably crashes.

                                                                                                    1. 1

                                                                                                      I’m curious as to what your company does!

                                                                                                      It’s definitely been my experience that not all VST plugins are well-behaved. I suspect I have one that subtly corrupts memory in the host and leads to random crashes when loading plugins.

                                                                                                      That said, my synth has been rather stable. I have received very few bug reports of crashing (compared to other issies), and I’m valgrind-clean to boot.

                                                                                                      1. 1

                                                                                                        We just make audio and video editors. I’m not in the audio team, but I hear stories about the pain of dealing with 3rd party VST plugins that are essentially a black box but are potentially lethal to the host application :)

                                                                                                        Running valgrind or even just knowing what it is probably puts you in the top 1% of VST programmers :)

                                                                                                  1. 4

                                                                                                    For those who aren’t in the know, 64k means that this entire intro is distributed as an executable that is 64 kilobytes or less in size. The executable must be entirely self-contained, so it has to include the graphical code, the audio synthesizer, the music itself, and then any additional assets.

                                                                                                    The entire 64k compo this year was massive. Also worth a watch are the runners-up: mercury’s on and approximate’s Small matters of the heart.

                                                                                                    1. 2

                                                                                                      Considering the trend, I was surprised to see so many entries (so many good entries, nonetheless). 64k is a category that’s being abandoned by demoparties since it’s got a lot easy nowdays and people go “just do a demo instead”, even Revision joked on that.

                                                                                                      On the other hand, I found the PC Demo compo to be quite boring. (thank god for all the funny demos like Hackers' and “We Have Accidentally Your Whole Audience”, which at least made me laugh a lot)

                                                                                                      Although it was already posted, the most impressive demo of Revision 2015 was probably 8088 MPH

                                                                                                      PS: I wonder if they’ll make a “Invitation compo” next year.

                                                                                                      1. 2

                                                                                                        This is the second year in a row that the 64k outshined the PC demo compo by a considerable margin. In fact, I don’t even remember what won the PC demo comp last year (though I remember that “new” by still was a really interesting concept and the music was dope).

                                                                                                        I personally think 64k is interesting because of the limitations it imposes on the music. It’s cool to see people managing to sneak samples in regardless of the size constraint, but I feel like there’s some space left there to explore in general. There have been some interesting changes in the DSP world in the past few years (particularly with regards to filter implementation) and I’ve been experimenting to see how small I can get the code.

                                                                                                        1. 2

                                                                                                          From a music perspective I guess it can still give a challenge, but from a graphical point of view 64k is more than plenty when you use raymarching, which I guess is why some people don’t see the point of 64k anymore.

                                                                                                          I love Revision’s idea of a 8k compo, I think (and I hope) we will see some really complex stuff in there as more people get into that.

                                                                                                          1. 3

                                                                                                            There’s a long-standing discussion in the scene as to what categories a party should accommodate. Assembly offers 1K and 4K, but the 1K productions are almost universally fractal explorers with hideous bleeping in the background. 4K is more interesting to me, and every now and then you get real shockers like Elevated.

                                                                                                            I, too, think 8K is a good compromise. You have enough room for decent music and something other than fractals, and still have to work hard to get all your assets in the provided space. Revision was a real treat this year.