Technical Documentation: clangen/musikcube
โน๏ธ Provenance: Hybrid Fusion:
clangen/musikcube(README + 5 In-Tree Chapters) ยท CodeWiki Reference ยท Recency: Active (< 180 days)
1. Project Overview & Quickstart (clangen/musikcube)
musikcube
a cross-platform, terminal-based audio engine, library, player and server written in c++.
musikcube compiles and runs easily on windows, macos and linux. it also runs well on a raspberry pi with raspbian, and can be setup as a streaming audio server.
check out the installation guide to get up and running.
be sure to also read through a the user guide, which describes app's navigation paradigm and lists all the default keyboard shortcuts.
if you want to build it from source, the instructions are here.
screenshots
it looks something like this on windows:
and this on macos:
and on linux:
here's a demo (made with asciinema):
while the main musikcube app runs in the console, you can also stream audio from (and even remote control) musikcube using the musikdroid android app, which can be downloaded in the releases section above. it looks like this:
installation
binaries are available in the releases page.
while macos binaries are provided, you can also install via homebrew as follows:
brew install musikcube
on freebsd musikcube can be installed as follows:
pkg install musikcube
on openbsd musikcube can be installed as follows:
pkg_add install musikcube
on windows, you can install via chocolatey:
choco install musikcube
then run using shell, Win+R dialog or by typing in Start Menu musikcube or mcube.
raspberry pi
musikcube runs well on a raspberry pi, connected to your home stereo. see here for detailed setup instructions.
compiling
if you'd like to compile the project yourself, you can check out the build instructions.
keyboard shortcuts
a list of all keyboard shortcuts can be found in the user guide
streaming server
musikcube ships with a streaming audio server enabled by default. it runs a websocket server on port 7905, used for metadata retrieval. an http server runs on port 7906, and is used to serve (optionally transcoded) audio data to clients.
it's important to understand that, out of the box, the server (and remote api) should NOT be considered safe for use outside of a local network. the websockets service only supports a simple password challenge, and the audio http server just handles Basic authorization. it does not provide ssl or tls. the server also stores the password in plain text in a settings file on the local machine.
you can fix some of this using a reverse proxy to provide ssl termination. details in the ssl-server-setup section. while this improves things, you should exercise caution exposing these services over the internet.
if you're interested in writing your own frontend, api documentation is available here.
sdk
the musikcube sdk is a set of small, pure-virtual c++ classes and a handful of enums and constants. they're still in the process of being slimmed down. you can see what they currently look like here: https://github.com/clangen/musikcube/tree/master/src/musikcore/sdk
dependencies
musikcube would not be possible without the following excellent free, open source, and (in the case of some macos and win32 APIs) non-free projects and libraries:
| core | decoders | outputs | metadata | networking | miscellaneous | ui |
|---|---|---|---|---|---|---|
| sqlite | ffmpeg | alsa | taglib | websocketpp | rxjava | ncurses |
| utfcpp | libopenmpt | pulseaudio | glide | libmicrohttpd | rxandroid | pdcurses (win32a variant) |
| nlohmann json | libgme | core audio | libcurl | stetho | recycler-fast-scroll | |
| kissfft | exoplayer | wasapi | openssl | fabric | ||
| sigslot | directsound | nv-websocket-client | AndroidVideoCache | |||
| wcwidth.c | waveout | okhttp | ||||
| pipewire |
license
Copyright (c) 2004-2023 musikcube team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of other contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.2. In-Tree Documentation Chapters (clangen/musikcube)
File: README.md
musikcube
a cross-platform, terminal-based audio engine, library, player and server written in c++.
musikcube compiles and runs easily on windows, macos and linux. it also runs well on a raspberry pi with raspbian, and can be setup as a streaming audio server.
check out the installation guide to get up and running.
be sure to also read through a the user guide, which describes app's navigation paradigm and lists all the default keyboard shortcuts.
if you want to build it from source, the instructions are here.
screenshots
it looks something like this on windows:
and this on macos:
and on linux:
here's a demo (made with asciinema):
while the main musikcube app runs in the console, you can also stream audio from (and even remote control) musikcube using the musikdroid android app, which can be downloaded in the releases section above. it looks like this:
installation
binaries are available in the releases page.
while macos binaries are provided, you can also install via homebrew as follows:
brew install musikcube
on freebsd musikcube can be installed as follows:
pkg install musikcube
on openbsd musikcube can be installed as follows:
pkg_add install musikcube
on windows, you can install via chocolatey:
choco install musikcube
then run using shell, Win+R dialog or by typing in Start Menu musikcube or mcube.
raspberry pi
musikcube runs well on a raspberry pi, connected to your home stereo. see here for detailed setup instructions.
compiling
if you'd like to compile the project yourself, you can check out the build instructions.
keyboard shortcuts
a list of all keyboard shortcuts can be found in the user guide
streaming server
musikcube ships with a streaming audio server enabled by default. it runs a websocket server on port 7905, used for metadata retrieval. an http server runs on port 7906, and is used to serve (optionally transcoded) audio data to clients.
it's important to understand that, out of the box, the server (and remote api) should NOT be considered safe for use outside of a local network. the websockets service only supports a simple password challenge, and the audio http server just handles Basic authorization. it does not provide ssl or tls. the server also stores the password in plain text in a settings file on the local machine.
you can fix some of this using a reverse proxy to provide ssl termination. details in the ssl-server-setup section. while this improves things, you should exercise caution exposing these services over the internet.
if you're interested in writing your own frontend, api documentation is available here.
sdk
the musikcube sdk is a set of small, pure-virtual c++ classes and a handful of enums and constants. they're still in the process of being slimmed down. you can see what they currently look like here: https://github.com/clangen/musikcube/tree/master/src/musikcore/sdk
dependencies
musikcube would not be possible without the following excellent free, open source, and (in the case of some macos and win32 APIs) non-free projects and libraries:
| core | decoders | outputs | metadata | networking | miscellaneous | ui |
|---|---|---|---|---|---|---|
| sqlite | ffmpeg | alsa | taglib | websocketpp | rxjava | ncurses |
| utfcpp | libopenmpt | pulseaudio | glide | libmicrohttpd | rxandroid | pdcurses (win32a variant) |
| nlohmann json | libgme | core audio | libcurl | stetho | recycler-fast-scroll | |
| kissfft | exoplayer | wasapi | openssl | fabric | ||
| sigslot | directsound | nv-websocket-client | AndroidVideoCache | |||
| wcwidth.c | waveout | okhttp | ||||
| pipewire |
license
Copyright (c) 2004-2023 musikcube team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of other contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.File: doc/build-standalone-unix.md
Overview
By default when you build musikcube it's almost exclusively tied to your Linux distribution and version. If you try to copy the binaries compiled from Ubuntu to Fedora, for example, they probably won't work.
It turns out that building a single C++ app once that works across many Linux distributions and versions can be very challenging, especially when there are external dependencies involved. The difficulties have been documented and discussed countless times and include, but are not limited to:
- Incompatible
GLIBC/GLIBCXXversions - Incompatible versions of required dependencies
- Incompatible locations of required dependencies (e.g.
/libvs/usr/libvs/usr/local/lib) - Incompatible filenames for required depdencies (eg
libfoo.so.3vslibfoo.so) - General unavailability of required dependencies (i.e. "dependency
foodoesn't exist inUbuntu'sapt")
In an ideal world we wouldn't have to worry about these problems, and musikcube would be available via all major Linux distribution package management systems. In practice, however, it's not. It can take tremendous time and effort to get packages accepted upstream by maintainers. For example, see the DebianMentorsFaq.
So, for now, we've developed a process that allows us to compile "generic" binaries once per CPU architecture that should generally work across most modern Linux distributions without hassle. In short, we do the following:
- Compile using an operating system with versions of
GLIBCandGLIBCXXthat should work on any Linux distribution from 2018 to now. We currently useDebian Buster. - Include modern versions of fundamental dependencies (
openssl,curl,ffmpegand others), compiled from source, omitting any unused/extraneous functionality. - Ensure the app is "relocatable" on the filesystem; all libraries are loaded via relative paths so you can put the
musikcubedirectory wherever you want and it'll still run. This is done by manually rewritingrpathvalues for shared libraries and executables where necessary.
The rest of this document will describe how we produce these builds, which are what we distribute on our Github project page for all releases.
Regular build instructions can be found on the Github project page, here, and have fewer weird prerequisites.
Instructions
Install `Debian Buster`
It's probably easiest to just install a docker image and use that, but an install straight to physical hardware (or a virtual machine) will work just fine.
Install dependencies
From `apt-get`:
sudo apt updatesudo apt dist-upgradesudo apt install build-essential g++ gcc git libasound2-dev libev-dev libncurses-dev libopus-dev libopus-dev libopus0 libpulse-dev libsndio-dev libssl-dev libsystemd-dev libvorbis-dev libvorbis-dev libvorbis0a libvorbisenc2 portaudio19-dev rpm wget zlib1g-dev libdbus-1-dev libudev-dev libglib2.0-dev patchelf libstdc++6-i386-cross nodejs
Compile from source:
Install the following from source, as the distro-provided packages are too old:
cmakev3.27.4+pipewirev0.3.x (optional -- only if you want to usepipewire)- Note:
wireplumber, apipewiresub-project, requires a version ofglib-2.0newer than whatDebian Busterprovides. That's fine because we just need thepipewirelibraries. Just editmeson_options.txtand remove'wireplumber'from thesession-managersoption.
- Note:
Provision your build directory
A couple build steps assume that you'll be building from the /build directory. This can either be a physical directory or a symlink to elsewhere. This is currently a hard-requirement, but may not be in the future. Sorry.
cd /buildgit clone https://github.com/clangen/musikcube.git --recursive
Compile third-party dependencies
As mentioned above, a number of larger third-party dependencies are compiled from source, stripping unused functionality to ensure they are as small and efficient as possible. Doing this manually is really annoying, so it's all been automated behind a script.
cd /build./musikcube/script/build-vendor-libraries.sh
This process may take a while, but when it completes you'll be left with a /build/vendor-${arch} directory that will contain all build artifacts. The musikcube app compile will reference this directory during its build process.
Compile `musikcube`
Now that we have all required dependencies available it's time to compile the app itself. As mentioned above we want the resulting binary to be relocatable on the filesystem, so some special pre- and post-processing must happen. Specifically: we need to gather copies of all dependencies and rewrite their rpaths if necessary. We also need to collect and include resource files like themes and localization files, then create .deb, .rpm, and .tar.bz2 archives for distribution. As in the previous step all of this complexity has been hidden behind a script.
cd /build/musikcube./script/archive-standalone-nix.sh x.y.zx.y.zis the version ofmusikcubewe'd like to appear in the filename. You can use anything you want, e.g.0.0.0- The build process will automatically discover and use the
/build/vendor-${arch}directory created in the previous step.
After the script has completed you should have a set of "relocatable" binaries in /build/musikcube/dist/x.y.z/ that will work on most Linux distributions released in 2018 or later.
File: doc/crosscompile-rpi.md
Prerequisites
Cross compiling depends on:
- A working "standalone" build environment (see here)
- A working Raspberry Pi
Busterenvironment, either viachroot(see here) or on a physical device
Gather dependencies from a Raspbian install
The cross-compile toolchain ships with a minimal system "image" that does not include all of the third-party dependencies we need to compile musikcube.
To obtain these dependencies we need to boot into the chroot environment and execute a script to download and collect the latest versions of the headers and libraries so we can add them to the cross-compile toolchain.
- Enter the
chrootenvironment (or boot your device) apt-get updatesudo apt-get dist-upgradecd /build/sysrootnode /build/musikcube/script/create-crosscompile-sysroot.js
After this process completes you will be left with a file called sysroot.tar.
Install the cross-compile toolchain
The cross-compile toochains that ship with Debian and Ubuntu generally do not fully support armv6, which means we cannot use them to generate builds for older Raspberry Pi devices.
Instead, we'll install a better maintained toolchain from the following github project: https://github.com/tttapa/docker-arm-cross-toolchain
cd /buildcp /path/to/generated/sysroot/sysroot.tar .node /build/musikcube/script/install-crosscompile-tools.js
This will download the cross-compile tools to the current directory, extract them, then use the sysroot.tar to populate the tools' environments.
Use cross-compile toolchain to compile dependencies
In order to facilite easy, efficient distribution of musikcube binaries, we compile various dependencies ourselves, omitting unused features and ensuring the entire package is "relocatable," meaning users can run them from anywhere (i.e. they don't need to be installed to /usr/ or /usr/local/ to work properly).
cd /buildCROSSCOMPILE=rpi-armv6 ./musikcube/script/build-vendor-libraries.sh
When this has finished, you'll be left with a vendor-rpi-armv6 directory that the main app compile will reference.
Build the main app
Now that we have all of our dependencies available it's time to compile the main app.
cd /build/musikcubeCROSSCOMPILE=rpi-armv6 ./script/archive-standalone-nix.sh 3.0.2
File: doc/rpi-buster-chroot.md
Forward
- stolen from here: https://medium.com/@crmoratelli/architectural-chroot-for-faster-compilation-and-deployment-on-raspberry-pi-76224327659d
Install dependencies
sudo apt install qemu-kvm qemu-user-static binfmt-support qemu-user-static qemu-utils kpartx e2fsprogs
Create a new directory
mkdir rpi-buster-chroot
Download image
wget https://downloads.raspberrypi.org/raspios_oldstable_lite_armhf/images/raspios_oldstable_lite_armhf-2023-05-03/2023-05-03-raspios-buster-armhf-lite.img.xz
Extract image
xz -d -v 2023-05-03-raspios-buster-armhf-lite.img.xz
Expand the image
qemu-img resize -f raw 2023-05-03-raspios-buster-armhf-lite.img 16G
Expand the partition within the image
fdisk 2023-05-03-raspios-buster-armhf-lite.imgCommand: p[prints the partition table. note partition #2's "Start" value.]Command: d[delete a partition]Command: 2[delete the Linux partition, which should be #2]Command: n[add new partition]Command: p[primary partition]Command: 2[partition number]Command:[enter start value from first step]Command:[press enter to accept default value]Command: N[to NOT remove the ext4 signature]Command: w[write table to file]
Create a mount point
mkdir os-mount
Mount both disk image partitions via loopback
sudo kpartx -a -v 2023-05-03-raspios-buster-armhf-lite.img
output, note device names:
add map loop4p1 (253:0): 0 524288 linear 7:4 8192
add map loop4p2 (253:1): 0 33021952 linear 7:4 532480 <== THIS IS OUR ACTUAL OSMount the second partition to the filesystem
sudo mount /dev/mapper/loop4p2 ./os-mount
Resize the ext filesystem
sudo /sbin/resize2fs /dev/mapper/loop4p2
Inject qemu and setup special mount points
sudo cp /usr/bin/qemu-arm-static ./os-mount/usr/binsudo mount -o bind /dev ./os-mount/devsudo mount -o bind /proc ./os-mount/procsudo mount -o bind /sys ./os-mount/sys
Magic: register `qemu-arm-static` as the arm interpreter in the kernel
Must be root, no
sudo
suecho ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:' > /proc/sys/fs/binfmt_misc/registerexit
Enter the chroot
sudo chroot ./os-mount /usr/bin/qemu-arm-static /usr/bin/bash
If you get an error about /usr/bin/bash not found, try /bin/bash instead
Shutdown
sudo umount ./os-mount/devsudo umount ./os-mount/procsudo umount ./os-mount/syssudo umount ./os-mountsudo kpartx -d -v 2023-05-03-raspios-buster-armhf-lite.img
File: src/plugins/server/README.md
musikcube server plugin
a playback remote and streaming audio server for musikcube using web sockets and vanilla http.
musikcubefor windows, macOS, linux and freebsd are all supported.musikdroidis a client implementation written for android.- api documentation can be found here.
the code is somewhat ugly, but it works pretty well. i currently have it running 24/7 on a raspberry pi with an iqaudio dac+, paired with a first generation moto g as a remote.
the backend plugin uses websocketpp and libmicrohttpd. the android client uses nv-websocket-client and exoplayer.
--- METRICS ---
- Files Extracted: 6
- Estimated Token Budget: ~8050 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/clangen/musikcube