Skip to content

12. Changelog

Jon McGuire edited this page Nov 6, 2024 · 44 revisions

Archived Content is at the end of this page.

Change History

v4.1.1 2024-11-06

  • Default StartFullScreen config to false, which is easier for first-time users
  • Change VertexIntegerArray settings on [multipass] to use : instead of =
  • Add uniform vec4 randomrun4 which provides four additional random numbers
  • Add --fade file to queue the next crossfade shader (filename prefix crossfade_ is optional)
  • Playlist viz entries can begin with >file identifying crossfade to use (filename prefix optional)
  • Add X keystroke to extend playlist auto-advance timer by 1 minute (cumulative)
  • Add A keystroke to pause playlist auto-advance timer (use right-arrow or --next to resume)
  • Visualizer playlist SwitchTimeHint=Half bug fixed
  • Updated to eyecandy 3.0.1 (minor debug logging changes to Shader constructor)

v4.0.0 2024-02-01

  • Eliminated the need for a Windows loopback audio driver (!)
  • New stand-alone executable installer / updater / uninstall, no more PowerShell shenanigans!
  • TCP relay support (via monkey-see-monkey-do) is deployed with the app
  • Reverted to OpenGL 4.5 due to Linux MESA drivers (no 4.6 features are needed by MHH)
  • Updated to eyecandy 3.0.0 (released 2024-01-27)
  • Reset uniform default values for each render pass
  • Viz / FX texture randomization by repeating a uniform name with different filenames
  • Crossfade renderer now supports randomized transition shaders
  • Added setting RandomizeCrossfade=true in mhh.conf (default is false)
  • For writing crossfade shaders, see comments in Volt's libraries\crossfade_simple.frag
  • Add --test [viz|fx|fade] [name] switch and --endtest switch
  • Test mode uses +/- to cycle through content using the named testing target
  • Test mode disables viz/FX caching, and shows a text overlay with test target info
  • Add TestingSkipVizCount and TestingSkipFXCount to mhh.conf (used during MHH dev)
  • Add config LoopbackApi to [windows] section, WindowsInternal is default, can be OpenALSoft

v3.1.0 2023-12-03

  • Migrated to .NET 8.0
  • Bug fixes via eyecandy v2.0.6 and OpenTK v4.8.2
  • Added u uninstall switch to installer script
  • The Shadertoy PCM wave texture is now 0.0 to 1.0 (silence is 0.5)
  • Many viz content improvements and additions via Volt's Laboratory
  • Internal font rendering support
  • Added a [text] settings section to the mhh.conf app config file
  • Added informational text overlays and crossfading popup notifications
  • Added --show [viz|stats] switches shows text overlay for 10 seconds
  • Added --show [popups|what] to toggle viz/fx playlist popup notifications or show the popup
  • Added --show [toggle|clear] to make text overlays permanent and clear anything shown
  • Added --show track to show Spotify track info (if available; currently Windows-only)
  • Added --show grid to display 100 x 15 characters for adjusting text settings
  • Added V to show visualization overlay (viz, fx, playlist, descriptions)
  • Added S to show stats overlay (frame rate, resolution, etc.)
  • Added < to toggle text overlay timed / permanent mode (really , / comma)
  • Added > to immediately clear any current text overlay (really . / period)
  • Added G to display the text grid test pattern
  • Added P to toggle viz/fx playlist popup notifications
  • Added W to immediately show a viz/fx playlist popup notifications
  • Added T to immediately show Spotify track info (if available; currently Windows-only)
  • Undocumented --show debug option and D key; content varies
  • Added Bksp to save JPG snapshot to user Desktop (Windows) or app directory (Linux)
  • Added ShowSpotifyTrackPopups to [windows] section of mhh.conf
  • Added UnsecuredRelayPort to mhh.conf for the (not yet released) Monkey-See-Monkey-Do launcher/relay service
  • Window is not visible until the first frame is rendered (prevents a white flicker at startup)
  • Added FullscreenMinimizeOnFocusChange in mhh.conf to allow using windows on other monitors

v3.0.0 2023-10-20

Major Features
  • Post-processing FX shaders
  • Image texture loading (jpg, png, etc)
  • Double-buffering for multipass shaders (exposes framebuffers from previous frame)
  • Reusable function library shaders
  • New uniforms and custom uniforms
  • Many new commands
  • Install / Uninstall script
App Config & Commands
  • mhh.conf is now in the ConfigFiles directory to prevent overwrites when unzipping updates
  • Fallback environment variable monkey-hi-hat-config can point to an app config file anywhere
  • Apply default 60 FPS target, controlled by FrameRateLimit in mhh.conf (0 is unlimited, may break some shaders)
  • Added optional framerate target value to --fps command (0=disabled, max=9999)
  • Added VSync to mhh.conf, default is Off, can be On or Adaptive (on if framedrop drops below half of target FPS)
  • Added TexturePath to mhh.conf for external image files
  • Added --fullscreen command (toggle)
  • Added RenderResolutionLimit to global and visualizer configurations (minimum 256, default is 0 to disable)
    • Moved resolution uniform to renderers since buffered output may not match output resolution
    • Renderers own/control the buffer when needed (when output resolution exceeds defined limit)
    • Crossfade no longer allocates buffers unless the renderers actually need them
  • Changed IVisualizer interface to IVertexSource and implmentations to VertexIntegerArray and VertexQuad
  • Command line --load [viz] [fx] to immediately apply an FX to a newly loaded visualization
  • Added StartInStandby to mhh.conf for startup/login launching
  • Added CloseToStandby to mhh.conf for manual window-closing (ESC key or title-bar X button)
  • HideConsoleAtStartup, HideConsoleInStandby in [windows] section (issue minimizes Win11 Terminal)
  • --standby command toggles standby mode (intended for remote calls)
  • --console command toggles console visibility (Windows only)
  • The --load and --playlist commands will trigger a "wake up" from standby mode
  • Add FXCacheSize and cache FX shaders separately from visualizers, default is 50
  • Increase default ShaderCacheSize to 150 (viz shaders are generally small)
  • Added LibraryCacheSize to mhh.conf (default is 10)
  • Cache sizes can be set to 0 in mhh.conf to disable caching altogether
  • Added --nocache to disable shader caching for the session (good for testing)
  • Added --jpg and --png for screenshots (Win: desktop, Linux: app path); wait flag watches for Spacebar
Visualizer Configs
  • Added [textures] section to visualizer .conf files (uniform:filename.ext, uniform! is ClampToEdge wrap-mode)
  • Added [libraries] section to viz and FX .conf files (see test content vertint, vertquad, multipass, and mpvizconf1)
  • Simplified visualizer shader config (uses internal passthrough if filename omitted or * is used)
  • Added RandomTimeOffset to viz.conf, randomly starts elapsed time at 0 to X seconds. Default is zero. Can be negative.
  • Viz.conf [playlist] section SwitchTimeHint (None, Half, Double, DoubleFX), FXAddStartPercent (+/- to 50%/sec)
  • Viz.conf [fx-blacklist] section lists FX files to never apply to the visualizer
Multipass & Post-Processing FX
  • Added multipass support for referencing viz.conf files instead of shaders and vert source types/args
  • Added multipass A-Z double-buffering (previous frame's data; allows Shadertoy-style multipass)
  • Defined FX config format (see repo testcontent/fx/snapclock.conf for details)
  • Added --fx [fx.conf] command
  • Added --list fx command
  • Added [textures] support to FX.conf files
Playlists
  • Added playlist settings FXPercent and FXDelaySeconds, and [FX] section
  • Playlist --next fx command applies FX immediately, even if one wasn't queued
  • Playlist InstantFXPercent for immediate application of FX to the next visualization
  • Playlist support for visualizer names followed by a specific immediately-applied FX name
Shader Uniforms
  • Custom [uniform] definitions in visualizer and FX .conf files (name=float or name=float:float to randomize)
  • Visualizer FX-options support via [FX-uniforms:filename] sections (see TestContent FX option_uniforms and viz vertint)
  • Added always-available uniforms:
    • frame - frame count float for the current visualizer (0-based)
    • date - vec4 year, month, date, seconds since midnight (like Shadertoy iDate)
    • clocktime - vec4 hour, minute, seconds, utc hour
    • randomseed - normalized float (0-1) randomly generated at program startup
    • randomrun - normalized float (0-1) randomly generated at visualization startup
    • randomnumber - normalized float (0-1) randomly generated for each new frame
    • Note the true maximum is very slightly less than 1: https://stackoverflow.com/a/52439575/152997
Miscellaneous & Internal
  • Changed to a more interesting internal idle-mode shader
  • Added better config file validations for basics like pathspec formatting and availability
  • Added Const class for solution-wide constants like StringSplitOptions
  • Added dependency on StbImageSharp for loading image texture files
  • Trace-level Dispose logging (async disposal completely incompatible with OpenGL/OpenAL!)
  • Use the mhh namespace globally (subdivisions were pointless)
  • Discontinued use of murmur3 hashing for shader cache keyes; too many collisions
  • Moved parsing of complex [multipass] section to a separate MultipassParser class
  • Added FXRenderer and generalized MultipassSectionParser
  • Added internal passthrough frag/vert shaders
  • Changed buffers to wrap mode
  • Decouple from window ClientSize, wait for OnResize events to stop; for Windows, OnWindowUpdate suspends
  • Added crossfade support to FX activation
  • Changed resource owner names to include class name and object creation timestamp to simplify debugging
  • Significantly enhanced --info output

v2.0.0 2023-09-07

  • Requires x64 architecture
  • Multipass visualizer support (including config [Multipass] section)
  • Crossfade for visualizer changes w/ option for immediate switch
  • Always load all eyecandy audio textures and assign required uniform names
    AudioTexture typename Fixed uniform name
    AudioTextureWaveHistory eyecandyWave
    AudioTextureFrequencyDecibelHistory eyecandyFreqDB
    AudioTextureFrequencyMagnitudeHistory eyecandyFreqMag
    AudioTextureWebAudioHistory eyecandyWebAudio
    AudioTextureShadertoy eyecandyShadertoy
    AudioTexture4ChannelHistory eyecandy4Channel
    AudioTextureVolumeHistory eyecandyVolume
  • Created RenderManager to centralize future visualizer complexity
  • Create PlaylistManager to simplify the HostWindow codebase
  • Removed OpenGL ES support (which also means no Raspberry Pi support)
  • Minimum OpenGL API version is 4.6
  • Set EnableCap.ProgramPointSize to support old-style gl_PointSize
  • Upgraded to eyecandy v2.0.0 with automatic TextureUnit assignments
  • Added shader caching (the --reload command forces a cache update)
  • Discontinue use of Shader reference in eyecandy.BaseWindow
  • Added Dispose-aware threadsafe LRU cache
  • Added murmur3 x64 128-bit hash keygen
  • Moved built-in viz.conf out of AppConfig and into Caching
  • Removed all audio texture requirements from visualizer .conf files
  • Removed --viz command support
  • Better Dispose coverage for GL objects
  • Implemented GLResourceManager to gen/delete framebuffers, textures, TextureUnits, etc.
  • Added CrossfadeSeconds to application configuration
  • Moved time uniform into the individual renderers for smoother transitions
  • Use VisualizerPath in mhh.conf instead of ShaderPath
  • Updated internal shaders and volt-lab shaders with #version 460 directives

v1.2.0 2023-09-02

  • Final version to support ARM32HF / Raspberry Pi 4B / OpenGL ES
  • Shader resolution uniform changed to ClientSize (viewport area); was Size (total window area)
  • Multiple search-path support (platform specific delimiters: Windows uses semicolons, Linux uses colons)
  • Support platform-specific path separators
  • Load separate configuration file during VS debug (mhh.debug.conf)
  • Updated to eyecandy v1.1.82 (fixes OpenAL error at program exit)
  • Updated to CommandLineSwitchPipe v1.1.2
  • Embedded a legit icon, fancy!
  • Call GC.SuppressFinalizer on Dispose methods (just in case)

v1.1.0 2023-08-26

  • Changes to support the monkey-droid GUI control application
  • Updated to CommandLineSwitchPipe v1.1.1 with TCP network support
  • Added UnsecuredPort to mhh.conf for TCP network support (disabled by default)
  • Added the monkey-droid --md.list switch to retrieve lists of playlist and visualizer files
  • Added the monkey-droid --md.detail switch to retrieve visualizer detail data
  • Added monkey-droid Windows msix and Android apk install packages to the release page

v1.0.0 2023-08-05

  • Initial release 🍰

Archived Content

For versions 3 and 4, a lot has changed quickly. Content which still may be useful but is not usually of interest will be archived here. For example, v4 has removed the need for Windows loopback drivers and OpenAL-Soft, but those are still options, so that content will eventually move here. This will hopefully simplify the main areas of the wiki.

Archived "Linux Quick-Start"

Linux is temporarily not supported.

My original plan was to run this on a Raspberry Pi 4B, so version 1.x supported ARM32HF and OpenGL ES. However, the GPU was just too underpowered, and I wanted to use features that require the OpenGL 4.x API, so as of version 2.0.0 the Raspberry Pi is not supported. I haven't had time to update the instructions below yet, but longer term I still intend to support modern 64-bit Linux machines with OpenGL 4.6 available. I'm leaving these instructions because I suspect they'll work for a more PC-like Linux device if you wish to run a build for yourself.

Note that these instructions reference .NET6, but version 3.1.0 requires .NET8. Due to bug-fixes in the OpenTK library, I believe v3.1 should work with Linux x64. I will be doing some testing and if all goes well, I will update this page with current information.

Setup Notes

This assumes you know a bit about Linux already, particularly how to set directory and executable permissions. If you don't know how to do that, nag me in the Issues and maybe I'll expand on that part a bit, but if you're going to use Linux, that's something pretty critically fundamental to understand for yourself.

These instructions are based on the way I set up my Raspberry Pi 4B (Debian 11 aka Bullseye). They probably work for other Linux distros, or at least should be extremely similar, but I haven't tried it yet (it's on my to-do list). If you see a problem on another distro and know how to address it, drop me a note in Issues and I'll update the wiki. However, I'm not intending to offer major support for Linux since it just isn't a priority for me (although I'll accept PRs as long as they don't break Windows).

What can I say? I like Linux-as-OS (mostly), but Windows is my bread & butter, and most Linux apps kind of suck (or "lack polish" if your feelings are hurt by that).

For Spotify playback, I highly recommend the spotifyd client, which is compatible with remote control from other native Spotify clients (ex. I can control it on my Raspberry Pi from my Windows PC or an Android phone on the same network). You'll want the armhf build on their release page and the instructions are pretty clear, so I won't go over that here.

Also, spotifyd has a cool feature: it can run an arbitrary command or script when the track changes. This means you could script it to issue a --next command to monkey-hi-hat to load the next shader in the playlist. (If no playlist is active, the command does nothing, but be aware that if the program isn't running at all, that command would launch it...)

.NET Runtime

Note that I'm not currently providing Linux binaries, so you will have to build and publish the program from source. If you don't have a Windows PC where you can run Visual Studio, you'll want to install the .NET6 SDK instead of one of the runtimes. Those details are beyond the scope of this Quick Start.

You must install the .NET6 runtime. Microsoft offers install scripts for many 64-bit distros. Because the pre-v2 program supported 32-bit Raspberry Pi, the instructions below are for a 32-bit .NET6 runtime install. I will update this later with 64-bit instructions after I've had time to complete Linux WSL testing. Also, even though it isn't "the Linux way", I prefer a machine-wide installation, whereas the Microsoft scripts only dumps the runtime into your user directory. The program only needs the basic runtime, but I chose to install the larger ASP.NET Core version of the runtime because I have some other projects in mind.

First, a few links:

Configure the environment variables:

  • sudo mkdir /etc/dotnet
  • sudo nano /etc/dotnet/install_location
    • Type this into the file and save:
    • /opt/.dotnet
    • CTRL+X ➡️ Save? Y ➡️ Filename? Enter
  • sudo nano /etc/profile.d/dotnet.sh
    • Type this into the file and save:
    • export DOTNET_ROOT=/opt/.dotnet
    • export PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools
    • CTRL+X ➡️ Save? Y ➡️ Filename? Enter
  • If you're using SSH, disconnect and reconnect, otherwise log out and log back in, or reboot.
  • Verify by checking the path: echo $PATH

Remove any older version of .NET:

  • cd /opt
  • rm -r .dotnet

The links on the downloads page will take you to another page that tries to auto-start a download. Cancel that, for the install process below, you will want to copy the "Direct Link" URL shown on that page.

Install the runtime:

  • cd /opt
  • sudo mkdir .dotnet
  • cd .dotnet
  • Paste the "Direct Link" URL at the end of this command:
    • sudo wget direct_link_url
  • Change the filename if you aren't using the ASP.NET Core runtime:
    • sudo tar xf aspnetcore-runtime*
  • sudo rm *.tar.gz
  • cd ~
  • Verify the installation: dotnet --info

Note this doesn't leave you ready to immediately host ASP.NET Core sites. That isn't currently needed by monkey-hi-hat, so those steps are beyond the scope of this application's Quick-Start (you'll need to configure nginx or Apache).

Configure Mesa Driver

The Mesa OpenGL driver can be set to support OpenGL ES 3.2 (the default is 3.1). This probably only applies to the Raspberry Pi and its relatively primitive GPU. (Although the Pi is no longer a system I plan to use with this myself, everything in the library, the visualization program I'm writing, and the shaders, are still currently pegged to that version -- mostly because I'm converting WebGL-based shaders right now, and WebGL is based on OpenGL ES 2.0.)

  • sudo nano /etc/profile.d/mesa_opengl_es_32.sh
    • Type this into the file and save:
    • export MESA_GLES_VERSION_OVERRIDE=32
    • CTRL+X ➡️ Save? Y ➡️ Filename? Enter
  • If you're using SSH, disconnect and reconnect, otherwise log out and log back in, or reboot.
  • Verify by checking the variable: echo $MESA_GLES_VERSION_OVERRIDE

Install GLFW Support

GLFW is a standard windowing framework for OpenGL.

Fortunately the Debian GLFW library seems to work fine:

  • sudo apt install libglfw3

Previously it was necessary to build from source:

  • sudo apt install cmake
  • sudo apt install xorg-dev
  • git clone https://github.com/glfw/glfw
  • cd glfw
  • cmake -DBUILD_SHARED_LIBS=ON .
  • make
  • sudo make install
  • if you won't uninstall, the glfw directory can be deleted at this point
  • app uses libglfw.so.3 which is in /usr/local/lib/arm-linux-gnueabihf
  • to remove: sudo make uninstall

Configure Audio Loopback

This assumes the use of ALSA and PulseAudio, which is the default for Pi OS, and also assumes output on HDMI-1. You may wish to install the Pulse Audio GUI control panel, although it is not really needed. Run sudo apt install pavucontrol and you will find it in the Start menu (or whatever X desktops call it) at Sound & Video ➡️ PulseAudio Volume Control.

Configure OpenAL to use the PulseAudio drivers first:

  • nano .alsoftrc
    • Type this into the file and save:
    • drivers = pulse,alsa,core,oss
    • [pulse]
    • allow-moves=yes
    • CTRL+X ➡️ Save? Y ➡️ Filename? Enter

Make your HDMI1 device the default recording device:

  • identify the device name: pacmd dump
  • device is probably: alsa_output.platform-fef00700.hdmi.hdmi-stereo.monitor
  • set the default: pacmd set-default-source alsa_output.platform-fef00700.hdmi.hdmi-stereo.monitor

Using monkey-hi-hat

Obviously, you need to install monkey-hi-hat itself. I don't currently provide any Linux binaries, so you'll have to compile and publish from source. Put that into its own directory, remember to chmod appropriate permissions on the executable (mhh), and grant user/group write permissions so that the log file can be written to the app directory. Now it's "installed" but you still must configure it.

If you installed the visualizers from my Volt's Laboratory repository or the content zip from the monkey-hi-hat Release page, edit mhh.conf to point to those directories (see the config wiki topic for more details).

If you're making your own visualizations and effects, create another directory structure on your computer or your network for those files (your config file can point to both sets of directories). I recommend something like this:

📂 /media/monkey-hi-hat-content
      |--📂 fx
      |--📂 libraries
      |--📂 playlists
      |--📂 shaders
      |--📂 templates
      +--📂 textures

Usage is simple: open a command-line window, change to the install directory, and run ./mhh. This loads the low-overhead "idle" visualizer. To send commands to the running instance, open another command-line window, change to the install directory, and run ./mhh again to see the command-line help options. If you're using the sample content, start up some music and run the command ./mhh --playlist variety.

The program window recognizes several keyboard commands. Two important ones are:

  • ESC ends the program
  • loads the next playlist visualizer (right-arrow)

If you didn't change anything, at this point the program is running in a window. You can resize or maximize that window, but you probably want to open the mhh.conf configuration file and change this setting StartFullScreen to true. But then, unless you have multiple monitors, you can't use a second window to send commands (well, technically you could ALT+TAB between the two, assuming your desktop is configured for that), and if you're running it remotely (for example, in your AV stack outputting to your TV), you don't want to be chained to the keyboard.

Remote Control Options

If you have a separate Windows or Android device available, I recommend the dedicated GUI control application, monkey-droid. Find out more about installing and using this in the monkey-droid section of the Windows Quick Start wiki page. If you don't have a Windows or Android device, or you don't want to use a GUI, you can use SSH.

Luckily, virtually everyone using Linux knows how to use ssh, so I'm not going to get into those details. Just go to another computer and spin up an ssh terminal connection and go to town with monkey-hi-hat's command-line switches. (If the other computer or laptop is Windows-based, hop over to the Windows SSH section of the wiki for help getting an OpenSSH Client set up.)

I also run ConnectBot on my Android phone. It's a little bit buggy, but it's free, it's actively maintained, and it doesn't harangue you with bullshit ads that you'll never intentionally click on. But if you're doing that, the monkey-droid application is a lot easier. (It's also buggy, mostly thanks to .NET MAUI's not-ready-for-prime-time status, but it's still a lot more convenient than typing commands using a crappy touch-screen keyboard.)

Recommended: GLSL Editor

If you want to create or modify the visualization shaders, it's extremely useful to have an editor that "speaks" GLSL, the OpenGL Shader Language. I don't really know what Linux programmers normally use, but I would assume GLSL plugins exist. I personally think Electron apps are an abomination that should have never seen the day (as is anything JS- or nodeJS-related), but if you use Visual Studio Code, it appears there may be useful GLSL extensions available.

It's a pretty nice workflow to run monkey-hi-hat on another monitor or off to the side in a window, and use an editor to modify the shader, then just issue an ./mhh --reload command to immediately see the results.

Recommended: Volt's Awesome Icon

I'm not sure how to create a desktop shortcut and custom icon on the LXDE desktop, which is the default on the Raspberry Pi OS. However, the Volt's Laboratory repository's misc directory contains a PNG icon file you might like (I assume the Windows ico format is never used by Linux). This is also included in the content archive on the release page.