Muziekveld

17-03-2019

Muziekveld is Dutch for "music field". It's a project that is based around the idea of spatial music playlists. I had noticed that I treat my normal linear playlist as a physical space. I could remember where certain tracks are in relation to others. Thoughts like "the theme song to this game is somewhere near the WALL•E soundtrack" were not uncommon.

After that, I started work on a music player that provides the user with a two-dimensional playlist. Each block contains a set of tracks that share the same category. These could be mood, album, location on disk, etc. Blocks can be played, muted, duplicated, edited, etc. Here are some screenshots in chronological order. The first version (2019), which is not shown, was written in Typescript and ran on Electron. This was a fatal mistake and hasn't been attempted again. The second version was written in C#, input and windowing was done with SFML, and playback was done with libVLCcore. This was the most complete version. The latest version was written in C# using Walgelijk. This version has the nicest codebase and avoids all the pitfalls I previously fell into. It runs fast and is reliable, but it's incomplete. It's since been abandoned, but I still intend to finish it.

There are two main obstacles I keep facing when trying to make a feature-complete Muziekveld. One of them is reliable audio playback. Music comes in so many forms: huge uncompressed WAVE files, extremely complicated Opus files, video files, licensed containers, and even web addresses. All of these should at least be playable, and ideally seekable, previewable, etc. This is incredibly complicated, but has luckily been solved by others already. I decided libVLCcore was a good backend, but since I'm in C# and .NET, the bindings are a little finnicky. I've encountered crashing that is literally impossible to handle safely from within managed code, unexplained errors, hanging, and so on. An alternative would be to use ffmpeg to decode audio, but since there aren't any managed implementations, another binding would be required. Similar problems would plague me.

The second obstacle is text rendering. My personal playlist is immense, consisting of over two thousand tracks. I want the software to be able to display all titles at once, in real-time, at over 120 fps at least. However, my goal is to be able to display hundreds of thousands of track titles at once. For modern systems, this really isn't an issue. Titles could be rendered to a bitmap asynchronously, put into an atlas, and drawn as a quad. This way I could easily render millions of track titles in a single draw call at a thousand frames per second. This is essentially what I implemented in the third screenshot on this page. The bottleneck here is memory. Keeping such an enormous amount of textures in memory is possible, but exceeds the expected memory usage of what is essentially a music player app. The solution is probably to pack these textures into multiple atlases based on their proximity to each other. This way, only the visible subset of textures is kept in memory. I haven't thought any of this out properly yet but I'm excited to implement all of this.

SFML (2020)

SFML (2021)

Custom engine (2023)