# MonsterMusic: an offline Android player with a native audio engine

> MonsterMusic is a music player for Android whose distinguishing feature is that its audio processing is written in C rather than in the language the rest of the app is written in. Everything else about it follows from that decision: the filters come in two architectures with different latency characteristics, the effects have per-effect dry and wet controls, and the interface includes an inspector that shows you the live state of the signal path. It is also distributed through four different channels, which is what a privacy-first project looks like in practice.

**ZTFtrue/MonsterMusic** — A music player on android platform, developed by Android composer

- Repository: https://github.com/ZTFtrue/MonsterMusic
- Stars: 535 · Forks: 35
- Language: Java
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ztftrue-monstermusic

## What the application is

MonsterMusic describes itself as a modern, privacy-first offline music player for Android, powered by a high-performance native audio engine.

Two words in that line do the work. The first is offline: this is a player for files you have, not a streaming service, and everything about the design follows from that. There is no account, no catalogue to sync, no recommendation engine, and the whole point of the audio engine is to make a local file sound better.

The second is privacy-first, and the readme backs that up with a concrete design decision rather than a promise, which we will come to: the application asks for audio permissions and nothing else, and the permission to read video has to be switched on deliberately.

The distribution is the first interesting thing about the project, because there are four channels and each says something. There is the free software repository, where the application is packaged and signed by the repository rather than by the developer. There is the ordinary app store, which is the channel with the widest reach and the least privacy. There is another repository that focuses on privacy-friendly software. And there are direct package downloads from the project's own release page.

And those direct downloads are per architecture, which is the detail worth explaining. There is a build for 64-bit ARM, recommended for most modern phones and tablets; a build for 32-bit ARM for older devices; builds for two desktop instruction sets, for emulators, for the desktop operating system built on Android, and for Intel and AMD machines; and a universal build with every architecture in one package.

That last one is a small thing with a real cost. A universal package is several times the size, and the readme's recommendation of the ARM 64 build for most people says so implicitly. Splitting the builds by architecture is a decision that every native Android project makes, and seeing a project that does it and explains it in the download section rather than leaving you to guess is a good sign about the documentation.

The other channels have their own value for this project. The free software repository build is reproducible from source, which for a privacy-first project is the whole point: the binary anybody installs is one that anybody can rebuild. The community server exists for the same reason.

And the localisation of the interface is done through a translation platform, with a badge linking to the invitation. For an application distributed to a wide audience, having the translation workflow in a public tool rather than in a spreadsheet is the difference between a translation that keeps up and one that does not.

## Why the audio engine is in C

The first feature heading is the native audio engine, and the explanation of why is the most technically interesting sentence in the readme: the audio processing is implemented in native C for maximum performance, real-time response, and zero garbage-collection jitter.

That third phrase is the one that matters, and it explains the whole design. An audio callback in a managed runtime has a problem that is not about speed: the collector can decide to run at any moment, including in the middle of the buffer, and a collection pause is an audible dropout. Moving the processing into native code does not make it faster so much as it makes its timing predictable, which for an audio thread is the property that actually matters.

The two filter architectures are the visible consequence. There is a biquad filter family, described as high-precision and zero-latency parametric equaliser filters. And there is a fast Fourier transform filter family, doing 2048-point linear-phase filtering for a transparent acoustic response without phase distortion.

That pair is the classic equaliser trade-off, and the readme states it plainly. A biquad is cheap and introduces a phase shift at the frequencies it changes, which is inaudible for most material and is a real problem for some. A large finite impulse response filter running as a fast transform is linear phase, so it does not smear the transients, and it costs more and adds a small latency of its own. The zero-latency claim belongs to the biquad path and the transparency claim belongs to the transform path, and offering both is the right answer for a player that has to handle anything from a spoken podcast to a mix.

On top of the filters there is a master soft limiter, described as an integrated stereo-linked peak tracking with a smooth curve to eliminate harsh digital clipping. The details are the interesting part. It is linked across the two channels, so a peak in one is limited in both, which is what stops the image from wandering; and it uses a smooth saturation curve rather than a hard clip, so the limiting is gradual rather than a sudden distortion at the threshold.

And a stereo spatializer, a native virtualiser that widens the soundstage. That is a much more polar feature than an equaliser, because it changes the image rather than the frequency response, and the fact that it is implemented natively alongside the rest is consistent with a project that treats the engine as a unit.

## The effects, and the inspector that shows the signal path

The second group of features is an effects suite, and the first entry is a stereo delay with configurable delay time, feedback decay, and a ping-pong crossfeed, which is the effect where the feedback goes to the opposite channel so the repeats bounce across the stereo field.

Then there is a group called studio effects covering reverb, chorus, flanger, and polyphony, with the readme noting that the algorithms are optimised. And then the feature that makes the suite usable rather than merely present: every effect has an independent dry and wet control, so you can set the proportion of processed sound for each effect separately.

That is a small design decision with a large effect on how an effects panel is used. A single global mix control means every effect is wired to the same knob, and a user who wants a lot of reverb and a little chorus has no way to ask for it. Per-effect controls mean the panel can express that one effect is the character of the sound and another is only a touch, which is how mixing is actually described.

The third feature is the most interesting, and it is a debugging tool shipped as a user-facing feature. There is a real-time signal flow view, placed directly beneath the album art, and it shows the end-to-end path: the track information, which is the format, the sample rate, the channel count, the bit depth and the bitrate; the decoder, which is the active codec, whether that is the platform decoder or the player library; the resampler, with the status of any real-time sample rate conversion; the digital signal processing engine, with the filter mode and the soft limiter status; and the audio sink, with the output routing, the buffer specifications and the sink's own sample rate.

And you can tap any of those sections to see the technical telemetry, or to jump straight to the relevant settings.

For a player with this many processing stages, that panel is the answer to a real problem. When the sound is wrong, the question is always which stage is doing it, and a list of five stages with live status answers it in one glance. It is also the sort of feature that a developer would build for themselves and then keep, because a chain inspector is how you find out that a resampler is silently resampling to 48 kilohertz when your file is 44.1.

The placement under the album art is a deliberate choice too. It means the information is on the screen you are already looking at, rather than behind a menu.

## Visualisers, pitch control and lyrics

The visualiser section is where the project is a bit playful, and there are three distinct things in it.

The first is a matrix-style digital rain, in which the fall rate, the glow intensity and the density all react to the real-time audio frequencies. The second is a 32-band spectrum analyser with a logarithmic frequency distribution and a smooth peak falloff. Both of those are ordinary visualisers with the ordinary parameter choices, and the parameter choices are the point: a linear frequency axis looks wrong to everybody, and a peak indicator that jumps is distracting.

The third is about how they are shown. There is a fullscreen visualisation view, a mode that turns the screen on its side, with a keep-awake toggle, and a cover-bounded mode in which, in the standard portrait view, the visualisers are cleanly contained within the boundaries of the album artwork.

That last one is a small piece of design thinking. A visualiser drawn over a cover art image looks striking, but it also looks wrong when the artwork is a photograph with a light corner, because the visualiser has no idea what is behind it. Constraining the effect to the artwork's bounds solves it, and the fullscreen mode is there for the case where the user wants the effect on its own.

The pitch and speed section has two independent controls, and the design of the speed control is the interesting part. There are coarse and fine sliders side by side: the coarse one steps by a tenth, the fine one by a hundredth, and the range runs from a quarter speed to three times. A single slider over that range would be unusable, because the interesting region is narrow and the interesting region is different for a podcast and for a drum solo.

And pitch shifting is separate from speed, with high-fidelity time stretching, so you can slow a track down without dropping a semitone.

The lyrics section is the most elaborate, and the features are: active lines automatically scrolling to centre themselves in the view; seeking by dragging along the timestamps; and a word-level dictionary popup, where you tap any word in the lyrics and it opens a lookup, with several dictionary providers to choose from and a setting for whether the popup dismisses itself.

That last feature is the one that makes this a lyrics viewer rather than a lyrics display. Tapping a word in a song to see what it means is a small idea that turns the lyric panel into a learning tool, and supporting several providers with a choice of dismissal behaviour is the level of detail a real user notices.

The format support is equally considered: embedded lyrics in the common tagging formats, and external files in four different subtitle formats, which covers what people actually have on disk.

## Video, and a permission decision worth reading

The video section is short, and it contains the best argument in the readme.

The feature itself is modest: a dedicated tab in the player for local video files, and the full digital signal processing chain applied to video soundtracks as well as to music. The interesting part is the battery behaviour, which is described as automatically switching to audio-only playback when the application is minimised or when you move away from the video tab, in order to conserve the battery. That is a sensible default, and it is the sort of thing that only gets written down when somebody has watched a phone get hot.

Then there are the steps to enable it: open the settings from the top app bar, scroll to the video support toggle and turn it on, grant the videos media permission when the system asks, and go back, where the local video files appear in the library and the tab becomes active. And the parenthetical in the first step is the important qualifier: the toggle is available when the build was compiled with video support enabled.

So video support is a compile-time option, not a runtime one, which is a perfectly normal Android pattern and a good one for a privacy-first application: the permission is only requested by a build that has the feature, so a user of the default build never has the video permission in their app's list at all.

And then the section asking why the permission is needed, which is where the project's stated values are made concrete. The answer is that the application adheres to the user's privacy: by default it only asks for audio permissions, so it never accesses personal photos or videos without explicit intent. And then the platform reason, which is the one that changed the rules: from a particular Android version, the platform split media storage into distinct permissions for audio and for video, so asking for one is not asking for the other.

That is a well-argued case, and it is the difference between a privacy claim and a privacy design. The claim would be that the application does not collect your data. The design is that the permission which would let it do so is not requested unless you turn on a feature that needs it, and the platform's own permission split is what makes that separation possible.

## The repository, and what it says about the project

The top level of the repository is the standard Android layout with several entries that tell you about the project rather than about the code.

There is the application directory, the build files written in the Kotlin dialect, the Gradle wrapper with its Windows counterpart, and the properties file. There is the store listing directory, with a per-language structure, since the icon path in the readme is a per-locale path. There is a file for the free software repository's packaging metadata, and the repository's own directory, which is the older convention for a distribution's own package.

There are branding directories: one for the launcher icon assets and one for pictures. That a project keeps its icon assets in a directory of their own, rather than in the application's resources, suggests a build step that generates several icon densities from a source image, which is the modern approach and the reason the assets are worth versioning separately.

And then there are three entries I would not have predicted. There is a file with a name that reads as a request for help, and a directory with a similar name, both at the root of the repository. A file at the root of a repository is something a reader sees first, and its name says that the author is asking for help with the project rather than presenting it. That is a striking thing to find in a repository with three releases in four days.

There is a configuration file for the stability analysis tooling, which is the sort of file that a project adds when it has decided to track a known set of problems rather than discover them in issues.

There is a change log, and there is a debug signing key file checked into the repository. The last one is worth a moment's thought. A debug key is not a secret in the way a production signing key is, and publishing one is a common and harmless practice that lets anybody build and run the application. It is also a small piece of information about how the release process works, since the release build has to use a different key that is kept elsewhere.

And there is a temporary directory, which is the kind of artefact that ends up in a repository and is never cleaned up, and its presence is a reminder that the repository is maintained by one person.

Which is the overall picture. The application itself is a well-engineered audio player with an unusually honest technical inspector, a considered permission model, and four distribution channels chosen to match its values. The repository is the work of one developer who is doing all of it, and who has left a note at the root asking for help.

## Conclusion

MonsterMusic fits somebody who wants an offline player with a real equaliser and effects, and who would rather install from a free software repository than from a store. It does not fit somebody who wants a streaming service, since the app is about local files. Verify first which architecture you need when you install a package by hand, since the builds are per processor and an emulator needs the instruction set for a desktop, that the video feature is compiled in rather than always present, since the readme says the toggle only appears when the build enables it, and that the permissions the app asks for are the ones you want it to have, since the privacy claim in the readme is a claim about what the app does not request unless you turn the feature on.

## FAQ

### What is MonsterMusic?

It is a modern, privacy-first offline music player for Android, powered by a native C digital signal processing engine. It plays local files rather than streaming, and it is distributed through a free software repository, the ordinary app store, a privacy-focused repository, and per-architecture downloads from its own release page.

### Why does MonsterMusic implement its audio processing in native C?

For latency, real-time response and, above all, predictable timing: a garbage collection pause in the middle of an audio buffer is an audible dropout, so the processing lives in native code where the timing is under the engine's control. The engine offers both a zero-latency biquad parametric equaliser and a 2048-point fast transform filter for linear phase response.

### What does the audio processing chain inspector in MonsterMusic show?

A live view of the signal path under the album art: the track's format, sample rate, channel count, bit depth and bitrate, the active decoder, the status of any real-time sample rate conversion, the digital signal processing engine with its filter mode and soft limiter state, and the audio sink with its routing, buffer specifications and sample rate. Tapping a section shows its telemetry or jumps to the related settings.

### Why does MonsterMusic need a permission to read videos?

Only for the optional local video playback feature, and only in a build compiled with that support. By default the application asks for audio permissions alone, so it never touches personal photos or videos, and the platform's split of media storage into separate audio and video permissions is what makes that separation possible.

### What can I do with the lyrics in MonsterMusic?

The active line scrolls to centre itself, you can seek by dragging along the timestamps, and tapping any word opens a dictionary lookup with a choice of providers and an auto-dismiss setting. Lyrics are read from the common embedded tagging formats or from external files in four subtitle formats.

## Sources

- [Issues](https://github.com/ZTFtrue/MonsterMusic/issues)
- [License: Apache-2.0](https://github.com/ZTFtrue/MonsterMusic/blob/master/LICENSE)
- [README](https://github.com/ZTFtrue/MonsterMusic/blob/master/README.md)
- [Releases](https://github.com/ZTFtrue/MonsterMusic/releases)
- [ZTFtrue/MonsterMusic on GitHub](https://github.com/ZTFtrue/MonsterMusic)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ztftrue-monstermusic
