It's not just about audio quality

Resolution and detail aren't the whole story

There's a lot of things I really enjoy about audio that can't simply be "what's better". All of us want upgrades when we spend money. The next thing that's just better than the last thing. In reality, it's always tradeoffs, and not just "more money is the tradeoff". That applies to everything in life though really. Intagible things like features, be it wireless connection, ANC, or even just look and feel are things that you may want other than just raw performance. Today I wanted to take a look at things that I have spent money on that aren't just about squeezing every last bit of detail out of music, and have given me joy in one way or another to help explain the insanity to a bit.

Why have more than one amp/DAC?

Amps and DACs have a sound, end of story. There are some that may do things differently that you prefer, but it's a lot harder to just say "this source is just better at everything" sometimes even comparing across price ranges. There are different designs out there. Let's look at two catefories of amps first. Tube amps tend to offer you a warmer presentation of audio. Sub bass and the really high highs can roll off in the upper air region, but they tend to be a lot of fun when it comes to classic rock, slower metal, orchestral, acoustic, and several other types of music. They tend to not be so great for really fast music such as metal with high BPM and double base notes, quick or very deep layered electronic music, and a few other places, but those aren't hard and fast rules. They augment the sound and present it in a new way and can shape the sound of headphones that you love already in new ways. Solid states are better for the inverse. Source chains rarely can take a headphone that you hate and make it great, but it gives you a new look at music you feel that you know inside and out, and give you another look at it. I'll cover this in a review, but there are factually exceptions of really picky headphones that can be make or break with source gear, but know that's an exception.

As for DAC's, it's the same story. DAC's are often broken up into categories of delta sigma, which is what you are used to, and R2R. Delta sigma tend to be much more sharp, and give you a sense of more detail, where R2R tend to give you a much more natural sound. R2R excel in similar places that tube amps can, but offer a different presentation all together. R2R are quite the investment to truly start getting into, which is their main drawback. I'd recommend giving one a listen before committing to them before you truly decide it's for you. One goodd exception that presents "R2R-like sound" is the Gashelli Labs Jnog with the AKM4493 DAC chip for those interested in a cheap way in. I'll do a mini review of that at some point, but I'm well off topic at this point. Long and short is that there's reason to look around at source gear to augment your experience as opposed to just "get an upgrade".

Cables. Do they really matter?

Yes. No. Sorta. Once your headphones cost $5000+, we can start debating on if materials really matter, but that's not the topic today. I'm simply talking about if you care about the cable. How it feels, how it looks, what functions cat it offer you. Braided cables are often more flexable and have less chance of stressing connectors. Maybe you care about how thick the cable is because a big cable that's flexable just feels premium to you. Material choice on the outer coating can play a difference as well. Maybe you want a soft material on the outside so when you bump it, it has a nicer feel. This also gets into microphonics. Microphonics are basically the ability for the cable to introduce noise into your headphones/IEM's when they rub on things and that vibration goes up the cable and onto the headphones, or worse, IEM's. That sound doesn't have anything to do with electrical signal, but it's something you end up hearing if it's rubbing on a desk or your clothes in some situations. What about connections? Most of us are used to cables that aren't modular so we don't think about them. Companies like Hart Audio are one to offer you different connectors with their quick connect system. Have the wrong plug for the device you want ot plug your headphone/IEM into? Why buy a new cable when you can just switch out the end. This saves you money if you end up needing more than one cable to plug into, say, a phone with a 3.5mm jack, and a balanced amp at home with XLR. Or if you buy new gear, you don't have to worry about which connectors they offer. The cable will work, and you only need a new end! This also allows you to easily add extensions that work with every end type as you aren't buying new cables. Long cable for the desk, and make it short while on the go, all without buying any extras you may not need later. It's up to you if you feel like a cable will make a sound difference, but to me, it's all about feel and function, and that's worth spending a bit extra on.

The elephant in the room

What about headphones? My DAC/amp arguement holds here even more true for headphones. Those have the greatest impact on sound, and can give you massively difference enjoyment in different tracks. If you have one nice set of headphones, and say, IEM's of any quality, I recommend listening to the same song on both. Each one will not only have different levels of detail, but also a different overall sound. Is one more pleasing to you? Which one is better at everything? Chances are, it's neither. Most of the time, we have different types of headphones for convenience, or comfort, which is itself a great reason to own more than one kind of headphone. Maybe it's as simple as wanting the spacious sound from open back headphones, and sometimes it's loud, so you switch to closed back headphones so you can listen uninterupted without letting everyone else hear what you are listening to. I've often been asked "What's the next headphone up from [insert their audio dewice]?". Most of the time, I can offer suggestions on where to go up, but I've found that many people enjoy having options of sidegrades rather than one really expensive headphone with a huge downside. The higher you go up in price, normally the more you have to spend on supporting gear. If you have a $1600 headphone, you probably don't want a $100 amp or you'll probably be missing out. Same with the DAC. Not to mention that there are parts of audio that you'll learn exist thanks to hov much better your headphone is at doing some things, and then other things just don't improve much, and if that's something that you care about, you may feel like it's lacking. There's no best anything, and there's no rush to the end. If you even think you care about high end audio, either find someone with lots of hardware to listen to, or see if you really care by playing with what you have, or keep it affordable when buying new things to try. Higher end headphones aren't always as much fun as some cheaper ones.

Wrap up

So that was a long unstructured ramble about things that were going around in my head. Hi-fi is true insanity, but it's out of love for music for most people. Hopefully that can give you something at least to think about or help you understand why I take such a seemingly odd stance on reviews of audio gear for those that haven't heard things for themselves. As always, I'm sure I missed something, so feel free to reach out if there's anything else you'd like covered, or if you want to ask about specifics that apply to what you have, ect.

What are these world files?

Enough with "world files are great". What are they?

I only recently realized that I've only talked about using world files, but never really explained their purpose. I'll try to break down what they are used for, and why knoming how they work is a useful thing. World files are a record of everything that is installed on the system explicitly. When you install, say Firefox, it will not be the only thing that needs installed. It uses shared libraries for audio, video, and many other things, but you generally don't care about any of that. You want Firefox, so you explicitly pull that in. All of the other dependencies are the package manager's problem, and are not recorded in a world file. This is a conenient place that you can go to in order to eassily see what's intentionally installed, let you clean out lines of things you don't care about and even things you have forgotten about over the ages.

What else can I do with world files?

Occasional cleanup is a good thing for any mutable system, but world files can also be used to reconstruct a system. If you back that simple text file up, you can transfer it to a new system, and effectively sync to that, and things will be added and removed automatically in order to make the file in sync with the system. Package sets also let you install sets of packages and enable/disable them together. This may be useful if you want to switch audio subsystems from one to another, and possibly even back. All packages can be swapped out at a time to ensure that nothing can be forgotten, and even lets you know after time what packages are used for that task. It's a great organizational tool, especially as systems get older and you forget what's installed, and why it's there. Because world files are almost exclusive to Gentoo and Alpine, I wrote pmm to emulate this behavior on other platforms.

So what about Nix?

Nix takes this concept further. Not only can you treat it like a "normal" package manager, but by default, it has access to generations. This allows you to roll back to previous versions if you decide that you don't like the changes. When paired with add-ons like NixOS, darwin-nix, or home-manager to extend this to your operating system and give you files to define "what the system looks like" similar to a world file. This isn't the limit to Nix however. You can tie other things like configs into the system, allowing Nix to manage not only installed packages, but how they are configured. You can take an nginx server config along with the package and bring it to a new system all in one tool as opposed to having packages and configs not be aware of each other in terms of the package management. Tooling like Nix Flakes is currently marked as unstable as the API is changing rapidly, but this allows you to even version lock packages or dependancies in order to increase stability and reproducability. This all goes far beyond what world files are capable of, but none of it forced on you other than generations, which is hard to complain about if you have a bit of free disk space to store it. It also allows having multiple versions of the same package installed, which is not common on most package managers, and is useful for having multiple versions of libraries, or just testing new versions before switching. Not having that ability has caused a lot of breakage on other systems, and is one of the reasons that projects like Flatpak are trying to solve.

That got quite a bit off the scope of world files, but that's why this has the "ramble" tag. Hopefully this off the wall post helped someone understand why world files are so great, or at least learned something in the ramble.

How I'm using nix

How I'm currently using nix

I've gotten a few questions surrounding how I'm using nix at this point in my workflow. Even without knowing much of it yet, I've managed to work a bit of it into my daily workflow. I'm typing this on my laptop which I rarely need to rely on as a test bed for NixOS. This lets me play with things that I may or may not like on a daily use system, server, ect, all without interrupting my daily workflow. Thus far, it's forced a few changes to my dotfiles, which isn't super uncommon for supporting a new Linux distro. Most notably, I had to remove launching Sway on tty1 login, though it's likely a lack of understanding on how that works.

My primary use thus far for nix has been using it with home-manager to replace my userspace on my Mac Mini and now this laptop. The ultimate intent is to be able to keep all of my userspace portable to my servers as well, or if I end up back on Fedora, I can still have a uniform userspace without touching the core immutable OS underneath it. With home-manager acting as a stand in for world files in the OS/pmm, it keeps it all centralized. I have not decided if I want to use tooling such as nix-darwin due to it's increased chance of breaking on MacOS updates. If my userspace is broken, that's one thing, but I'm not sure how much power it has over the host system and if it would be able to soft brick on updates. Further research and testing will need done.

Because of the lack of nix-darwin, unless I'm missing something, I don't believe that I can get full integration with GUI applications on Mac, which causes some minor inconeniences. The first place that I had noticed this is having emacs installed through homebrew which I tend to do things like compiling and other tasks through. Because it's not tightly integrated into tooling like nix-direnv, it can't see the tooling made avaliable. It's not a deal breaker to me as I'm used to working in an external terminal already, though I do intend to solve it if possible and the gains outweigh any costs associated. Only time will tell.

What's a nix?

What is nix, and why should I care?

This exact question is why I avoid nix for so long. Specifically the "what is nix?" half. Nix is not one thing, but a collection of many things when most people say "nix". I wanted to clarify what things are to the best of my knowledge and give others what I had trouble finding in one convenient location when I was not knowing anything about nix in hopes that you understand better what things are, why I'm so pedantic, and possibly enable you to give things a shot with at least a direction to go that I had such trouble finding. With that out of the way, what the heck is it?!

Nix

Nix seems to be a catch all term for anything related to core tooling, the language, ect. If you are familiar at all with ZFS, it's likewise "a filesystem" but it's also an ecosystem of tooling that you gain massive benefit from using as opposed to using traditional tooling in it's place. Nix is much like that in regards to it being a set of tools that integrate tightly with each other.

The other definition that can be applied to nix is that it's a package manager. It's a declaritive system using Nix Expression Language (covered below). I encourage you to read about the nix package manager even as there is already a great breakdown of why it's great there, and I don't need to rehash that as I can't do a better job.

Nix expression language

Nix expression language is written in a functional style. It's used to describe anything that is in the nix ecosystem. All tools are written in this one style, which allows you to have less languages to learn to create anything that you want to integrate into the system. Because of it's pure functional nature, this means that results are in most cases able to be reproduced bit for bit identical. This reduces the classic "It works on my machine", and hard to debug errors down to almost none. If this sounds similar to what Docker or other OCI containers solve to a point, you would be correct. This extends to much much more than containers though.Nix expression language great for writing build systems, making reproducable containers, creating dev environments, building operating systems that are bit for bit identical on real hardware, the list goes on.

Nixpkgs

This one is simple. It's a list of packages avaliable to the nix package manager. There's several repositories avaliable, it supports something similar to Gentoo's overlays or the AUR from Arch. You can read more about it here.

Home-Manager

I've talked about this on more than one occasion, and never fully defined what it is. home-manager is tooling that allows you to define how user's files, applications, configs, ect are all set up. As opposed to installing packages one by one like you can use nix-env to do, it brings it all together similar to how pmm does for many systems, but gives you all of the power of Nix Expression Language to be able to set up logic instead of doing manual work. It can invoke basically "anything the nix ecosystem can do", but that's the simple answer.

NixOS

NixOS is what happens if you take home manager, and give all of that power to your operating system. Have a fully redeployable operating system on real hardware that can describe not only what's installed, but how it's configured from networking, to system services, to what docker containers will be running. All within Nix Expression Language. It has integrations with home-manager to allow everything to be fully integrated while still offering you portable users. No more installing a distro and then configuring it, worrying about config file changes with updates lingering and breaking over time. It's all written in Nix, and will all work every time, exactly the same way. Even if you try to manually edit config files, they are immutable and regenerated so nothing can really damage the system from the outside as you can simply regenerate everything. Roll back to previous definitions, all without filesystem snapshotting. It's fully extensible and the only limits are what time you are willing to put into it.

Nix-Darwin

While not as integrated as NixOS, this allows you to manage many aspects of MacOS in a similar way. Nix-Darwin has integrations with home-manager so you can get most of the power without leaving all of your Mac specific apps behind.

Nix Flakes

If you ever search Nix, you'll see this being talked about constantly. For the moment, I'm avoiding it until it gets marked as stable, but it looks promising. As I am not using this experimental feature, I'll suggest you go read about it here.

Ok, but what can I do with all of that power?

I can't even begin to pretend like I can understand the full power of what is possible, but I'll list a few things that you may find interesting. These are things that I may play with and I'll document anything that I do and share my thoughts.

  • Nix-Direnv: Portable dev environments
  • Comma: Run ephemeral commands
  • Better PMM:: Manage packages in a central, portable, place.
  • Manage docker: Docker-compose, but not learning a new language
  • Nixified terraform: Why learn terraform when you already know nix?
  • CI/CD: All devs need CI/CD. Why not bring that in too?

Further reading

While all of this sounds insanely appealing, there is a learning curve. Nix doesn't have to be a massive time/effort investment, but it can be if you want to get the most out of it. I believe if I stopped where I am, I would still have massive gains from where I was learning nothing more. If you want to hear some thoughts from someone who's used Nix for many years, and their thoughts on it, I'll link to Hilssner's dotfiles. For those unaware of who that is, they were the creator of Doom Emacs and their content is always a joy and a laugh to read. I highly recommend reading their FAQ as it seems to cover if you should learn nix in a way that's both funny, and brutally honest, yet remaining a nix user. I'll also link their decent into madness as it's yet another good read for anyone new. While they have quite the indepth take on it, they make a lot of good points to think about if you want to take nix seriously, or just use it as a neat toy as I have been. Until the next post, I hope you enjoyed, and were entertained by hilssner even half as much as I am.

nix-direnv

Portable dev environments

In my journey to uncruft my system, I started looking at even uncrufting my user's footprint as well. I found myself bringing in a ton of things for misc dev work. One project I may use Nim, another Python, another I need Zola for this blog, and it started adding up. I knew there had to be a better way. In comes nix-direnv. If you have done development, you may already be familiar with direnv which is great for keeping your system clean in general. I won't repeat everything when there are good links to things, but direnv is built to keep your env vars that are project specific out of your local system, and nix-direnv extends that now to packages! Instead of rambling, I'll show you a simple demo that I actually use on this blog.

You'll need two files for each project.

.envrc

use nix

shell.nix

    { pkgs ? import <nixpkgs> {}}:

    pkgs.mkShell {
      nativeBuildInputs = with pkgs; [
        gnumake
        zola
      ];
    }

You'll obviously want to install direnv and nix-direnv in whatever way you would normally. I simply included them in my home-manager file. Deperinding on how you have your shell installed, you may need to add a hook for your shell to automatically load the environment when you change into the directory. Since I don't allow nix to manage my ZSH configuration, I simply added it to my .zshrc, though it may be more readable to most people with the shown example.

# .zshrc
eval "$(direnv hook zsh)"

If you have a different shell, follow the docs for your specific shell. That should be it in terms of global setup. .envrc files won't be loaded by default for security, so you can run direnv allow . in the directory once and it will be allowed to load from that point on when you cd into the directory, and unload when you leave.

After thoughts

Not only does this allow you to keep your system cleaner by keeping env vars and packages out of the system and user's packages, it allows you to keep that portable for anyone that has a nix system with direnv and nix-direnv so there's no need to guess what packages are missing for nix as they can auto populate. If you want to adventure further into it, you can even do things like fetching remote envs, version locking to keep all users on the same dev environment, and much more, but that's outside of the scope of this. This is just meant to give you something to start with, or it may already do everything you could possibly need. Hope that helps someone understand what it does so you don't have to dig up everything like I had to.