A new audio program for use with VTT setups, inspired by Kenku.fm and Winamp
C++
0
126 commits
updated Oct 12, 2026
Beta. A Windows app for running the sound of a tabletop game (D&D, Daggerheart, Call of Cthulhu, Pathfinder, anything you like!) over Discord.
You get music playlists that crossfade on their own, a soundboard of effects and looping ambience, scenes that change the whole mood in one press, and your own microphone run through noise suppression and your VST3 plugins. It's all mixed in one place and sent straight into your Discord voice channel through the app's own bot. No virtual audio cable, no DAW, no routing.
It also works with no Discord at all, playing through your own speakers, which is the easiest way to try it.
Inspired by Kenku FM and Winamp.
Inkwyrd Audio is free, and it stays free. If it's saved you some faff at the table and you'd like to put something in the hat:
Entirely optional, and no part of the app is held back for it. Bug reports and suggestions are every bit as useful, and those are free to give.
Inkwyrd Audio Tutorial walks through setting it up and using it. If you'd rather read, the guides below cover the same ground in more detail.
Music
Soundboard and ambience
Scenes
Your voice
Control and comfort
Under the hood
Get the newest release from the Releases page. What changed in each version, all the way back to the first beta, is in CHANGELOG.md.
There's nothing to install. Download
InkwyrdAudio-Portable-<version>.zip, unzip it anywhere you like, your
Desktop, Documents, a USB stick, and run Inkwyrd Audio.exe from
inside. To remove Inkwyrd, delete the folder.
Everything it needs is in that folder, including the Microsoft C++ runtime, so it runs on a fresh Windows install with nothing set up first.
To upgrade, unzip the new version over the old folder, or into a new
one and delete the old. Your settings, playlists, soundboard, scenes,
track library and skins live in %APPDATA%\Inkwyrd Audio, separately
from the program, so they survive either way.
There used to be an installer here, but it's gone now. It did the same job with a Start menu entry and an uninstaller, but it was the part antivirus engines disliked most: an unsigned program that unpacks other programs looks exactly like a dropper to a machine-learning model, whatever it actually does. One download is also one less thing to explain.
If you installed Inkwyrd that way before, uninstall it first (Windows Settings -> Apps -> Installed apps -> Inkwyrd Audio -> Uninstall) then use the ZIP. Your settings and playlists are in
%APPDATA%and aren't touched by uninstalling. Running both at once would leave you with two copies sharing one set of settings, which is confusing rather than harmful.
It will probably say "Windows protected your PC" the first time you run it, and your browser may say the file "isn't commonly downloaded." Both happen because Inkwyrd isn't code-signed. Click More info -> Run anyway.
Microsoft Defender may go further and block it as a threat. Here is the honest position, because you're being asked to run an unsigned program off the internet and you deserve the whole picture:
!ml, Wacatac.B!ml,
Sabsik.EN.D!ml. Those suffixes mean a model guessed, not that anything
was found.So: if Defender blocks it, don't override the block. Open an issue instead and I'll look into it. Overriding your antivirus on the say-so of the person who wrote the program is a bad habit, and I'm not going to ask you to get into it.
If you'd rather satisfy yourself independently: the full source is in this repository and you can build it yourself, every release lists a SHA-256 checksum below, and you can upload the download to VirusTotal and read the results first-hand.
The real fix is code signing, which Inkwyrd doesn't have yet.
Checksums. Every release's notes list the SHA-256 of the download. Check yours matches before running it:
Get-FileHash InkwyrdAudio-Portable-*.zip
This gets you from nothing to music playing, without setting up Discord.
When you're ready to play over Discord, follow Connecting to Discord.
Inkwyrd is six windows you can arrange however suits your screen:
| Window | What it's for |
|---|---|
| Player | The main window: what's playing, the transport buttons, volume and playback settings |
| Playlist | The tracks in the selected playlist |
| Library | Your playlists (top) and every track you've added (bottom) |
| Voice FX | Noise suppression and your microphone plugins |
| Soundboard | The grid of sound-effect buttons |
| Scenes | One-press setups for the whole room |
The warning banner on the Player window is where Inkwyrd tells you about anything that would otherwise fail silently: the audio device didn't open, a playlist has no playable files, tracks are missing from disk, or a file couldn't be read.
When a newer version is out, an Update available link appears at the top of the Player window, next to Settings. Click it to open the release page in your browser.
Everything here is on the Player window.
The display at the top shows the track's artist, title and cover art, the time played and total, a live spectrum of what's being sent out, and a seek bar. Click or drag the seek bar to move through the track.
The transport buttons:
Master is the volume of everything Inkwyrd sends out: your speakers and Discord.
Mic (to the left of Master) is the volume of your voice only - the music and sound effects stay where they are. Turn it down if you're too loud in the call.
The row below sets how playback behaves. All of it is remembered:
Keyboard: click the Player window, then use Space to play or pause, S to stop, Right arrow to skip, Up/Down for the master volume, M for the mic and Esc for the Killswitch. See Keyboard shortcuts.
The Library window's lower half, All Tracks, is every track you've added to Inkwyrd, whether or not it's in a playlist. It's where you search, preview, tag and pick tracks for playlists.
To add music:
Two ways to look at it, switched with Table and Folders next to the heading. Whichever you used last is remembered.
To search, type in the box above the list. It matches title, artist, album, genre and filename, so untagged tracks are still findable. Words match in any order: "drake blue" finds "Blue Drake". In the Folders view, the folders containing matches open up so you can see where they are. Esc or the x clears the search, and the tree goes back the way you had it. The heading shows how many tracks match, for example "All Tracks (12 of 84)".
To remove tracks, select them and click Remove (or press Delete). That takes them out of the library only. It never deletes the files, and doesn't touch any playlist already using them.
A preview plays a track in your ears only, to check it's the one you want, without the table hearing it.
While a preview plays, the playlist pauses and picks up again afterwards. A preview never reaches Discord, and you hear it even when Monitor is off.
Can't see a play symbol? Make sure All Tracks has tracks in it. If it's empty, click Add folder... and add your music.
The Library window's upper half is your playlists. Keep as many as you like: one per location, mood or session.
To make a playlist, click New. A box asks for its name; type it and press Enter.
To put tracks in it:
To play a playlist, double-click it, or select it and click Play. If something is already playing, it crossfades across rather than cutting. Switching back to a playlist later in the same session resumes it where it left off.
Clicking a playlist (single click) just shows its tracks in the Playlist window, without changing what's playing, so you can look through one list while another plays.
Rename and Delete manage the list. Refresh re-reads a playlist's linked folder (see below).
The Playlist window shows the selected playlist's tracks; title, artist and length, in the order they play when Shuffle is off, with the playing one marked.
The playlist made from your Setup music folder is linked to that folder. Music you add to the folder later joins the playlist; click Refresh to pick it up straight away. Tracks in a linked playlist can't be removed one at a time, because they come from the folder.
To see where playlists are stored (readable JSON files), use Open playlists folder in Settings.
Every track has its own volume and its own fade length. Both belong to the file, so a track in several playlists is fixed in all of them at once.
A change applies straight away, even to the track that's playing.
Tags are what a music file says about itself: title, artist, album and so on. Inkwyrd shows them everywhere, and can change them.
Changes are written into the file itself, so every other music program sees them too, and the Library updates straight away.
Editing several tracks at once: select them first, then right-click.
Fields that differ between them show <keep> and are left alone unless
you type in them. So you can fix an album's artist without flattening
thirteen different titles. Only the fields you actually change are
written.
Your files are handled carefully. Inkwyrd never edits a file in place. It copies it, tags the copy, checks the copy still plays, and only then swaps it in. If anything fails, the original is untouched.
A track that's currently loaded in the player can't be tagged, because Windows won't let a file in use be replaced. Press Stop and save again. A track being previewed is fine: the preview stops itself.
The Soundboard window is a grid of buttons for sound effects.
To put a sound on a button:
To play a sound, click its button. Sounds can overlap, and the same button can be pressed repeatedly.
To rearrange the board, drag a button onto another to swap them, or onto an empty one to move it there. Everything moves with the button, including its name, so Stream Deck keys keep working.
Right-click a button to:
+ and - at the top add or remove buttons. A button with a sound on it is never removed.
Killswitch (top of the window, or Esc on the Player) instantly silences every sound effect playing, loops included, and switches off any sound set to play randomly. It never touches the music: use Stop or Fade out on the Player for that.
A button whose file has gone missing says (file missing) rather than silently doing nothing.
Any soundboard button can loop instead of playing once. That's what you want for rain, a crackling fire, a tavern crowd or wind: sounds that should run under the music until you say otherwise.
The same press starts and stops it from a Stream Deck too, and the Killswitch stops it. Each loop keeps its own volume, so you can set an ambience bed quietly under the music and leave it.
Loops are what scenes switch on and off.
Any button can fade in when it starts and fade out when it stops, instead of starting and stopping at full volume. Right-click it and choose a length under Fade in and Fade out (from half a second to ten seconds), or Off.
Scenes keep their own fade settings for each sound, so the same rain can swell in slowly in one scene and cut in at once in another.
A sound effect can play on its own every so often, such as a seagull over the waves, distant thunder, a creak in an old house, while the rest of the scene carries on.
Right-click the button and choose Play randomly.
Pick how often:
Each gap is picked at random within its range, so it never falls into a pattern. The first one comes sooner, so you can tell it's on.
A small dice appears in the button's top corner while it's playing randomly.
Clicking the button still plays it straight away, whenever you like. It never plays over itself: if one is still playing when the next is due, that turn is skipped. To stop it, choose Play randomly -> Off, or press the Killswitch.
Random play is for sounds that play once. A looping button can't play randomly, since it never finishes. It also doesn't switch itself on when Inkwyrd starts, the same as loops: save it in a scene and pressing the scene switches it on.
A scene is one press that sets the whole room: which playlist plays, which looping sounds are running, which sounds play randomly, and (if you choose) the master volume. For example "Tavern", "Road", "Combat" or "Storm".
Open the Scenes window from the Scenes button on the Player.
To make a scene:
To use a scene, click it. Here's what happens:
The scene you last pressed is outlined. A scene change takes as long as the Player's crossfade setting, and never less than a second.
Right-click a scene to:
If something a scene uses disappears (its playlist is deleted, or a soundboard button is cleared or stops looping), its button says how many things are missing and hovering over it says which. The rest of the scene still works. Renaming a soundboard button updates every scene that uses it, and moving buttons around the board changes nothing.
Your mic is mixed in with the music and sent to Discord. The Mic button on the Player (or M) turns it on and off, and the setting is remembered.
The Mic slider on the Player sets how loud your voice is, without touching the music or sound effects. It's remembered too. It doesn't change what ducking counts as speech, so turning yourself down won't stop the music dipping when you talk.
The Voice FX window shapes how you sound.
Noise suppression (at the top, off by default) removes steady background noise, a fan, hiss, room tone, from the gaps between your words. Turn it on for a noisy mic and leave it off for a quiet one: on a clean mic it takes more from your voice than from the noise. It adds about 40ms of delay. The line under the switch says which state you're in.
Your plugin chain runs your mic through VST3 plugins you already own (EQ, compression, a noise gate and so on).
Save your settings as each plugin's own presets. The chain itself isn't remembered between sessions. Noise suppression runs before your plugins, so they shape your voice rather than your room.
With ducking on, the music and sound effects dip while you're speaking and come back when you stop, so you can narrate without riding the Master slider.
The timing is fixed: it dips fast enough not to clip your first word, and waits a moment before coming back so the music doesn't surge up between sentences. It listens to your mic after noise suppression and your plugins, so a noise gate you already use decides what counts as speech. A muted mic never ducks anything, and your voice itself is never ducked.
Inkwyrd plays into Discord as its own bot, so you need a bot of your own. It's free and takes about five minutes.
Create the bot:
Invite it to your server:
5. Open OAuth2 -> URL Generator. Under Scopes tick bot; under
Bot Permissions tick Connect and Speak. Copy the URL at the
bottom.
6. Open that URL in your browser, pick your server, and click
Authorize. The bot appears in your member list (offline until
Inkwyrd connects it).
Get the server and channel IDs: 7. In Discord, turn on User Settings -> Advanced -> Developer Mode. 8. Right-click your server's icon and Copy Server ID. 9. Right-click the voice channel the bot should join and Copy Channel ID. Make sure it's the voice channel (the one under the speaker icon that people join), not the text channel above it.
If that voice channel is private, the bot needs to be let in. A private channel only admits the roles and people named in its own permissions, and a bot you've just invited isn't one of them. The Connect permission from the invite link applies to the server as a whole and doesn't override a channel's own settings.
To fix it: hover the channel in Discord, click the gear (Edit Channel) -> Permissions, add your bot's role under Roles / Members, and allow Connect.
You can tell this is the problem because Inkwyrd connects, the bot appears in your member list, and it simply never joins the channel. Discord doesn't report a voice join it won't allow, so there's no error anywhere: it just never happens.
Put them into Inkwyrd: 10. Open Settings, paste the Bot token, Server (guild) ID and Voice channel ID, and click Save & Apply. 11. Inkwyrd connects straight away, and the status line at the top of the Player shows how it's going. Changing these details later, once it has connected, takes effect the next time Inkwyrd starts; it offers to restart for you.
Where your token is kept, and how to cancel it. Inkwyrd saves the bot token in its settings file at
%APPDATA%\Inkwyrd Audio\Inkwyrd Audio.settings, as ordinary text that isn't encrypted. Anyone who can read that file can use your bot.That's fine on a computer only you use, and worth knowing about otherwise. Two things follow from it:
- Don't send anyone that file - including when you report a bug. Send the log files instead (Settings -> Open log folder); the log deliberately never records your token.
- If you think it has got out, go to the Developer Portal -> your app -> Bot -> Reset Token. The old token stops working immediately. Paste the new one into Settings.
The same applies to the client secret if you set up automatic muting. Your bot can only join voice channels and speak, on servers you invited it to, so the worst case is somebody playing audio at your group, not access to your Discord account.
Starting before anyone else has joined is fine. Discord sets its voice encryption up as a group, and it won't finish doing that until there's somebody to share it with, so a bot sitting alone in a channel waits. While it's waiting, the status line says "In the voice channel, nobody else here yet, so nothing is being sent to Discord" and your music plays locally only. The moment a player joins, sound starts reaching the channel on its own. Nothing to press.
Inkwyrd rebuilds the connection by itself if Discord drops it. Discord ends a call whose channel has been empty for a while, and moves bots between its own servers from time to time. Either way you'll see "Reconnecting to the voice channel..." and it carries on. You don't need to restart it.
Once you're connected, turn Monitor off. You're in the call too, so you already hear everything through the bot.
When your mic is live in Inkwyrd, your voice reaches the call twice: once from your own Discord client and again through the bot. Inkwyrd can mute you in Discord whenever your mic is live here, and unmute you when it isn't.
This is optional. If you only use Inkwyrd for music and effects, skip it. It uses the same Discord application as your bot:
https://inkwyrd.com/rpc exactly, and Save Changes. Nothing is
ever sent there, Discord just requires one. It must be that exact
address, and first in the list if you have several.It mutes your own Discord client on your own machine, so it needs no special server permissions and works in any server.
Inkwyrd has a plugin for Elgato's Stream Deck. Every key works while Inkwyrd is running.
| Action | What it does |
|---|---|
| Skip Track | Crossfades to the next track |
| Toggle Shuffle | Turns shuffle on or off |
| Toggle Mic Mute | Turns your mic on or off |
| Music Fade Out | Same as the Player's Fade out button, taking the same time |
| Soundboard | Plays one soundboard sound, or starts/stops a loop |
| Soundboard Killswitch | Silences every sound effect; the music keeps playing |
| Scene | Switches to a scene |
Installing it. The plugin isn't in the download yet, it's built from this repository's source. You need the Stream Deck app (version 6.5 or later) and Node.js.
git clone).streamdeck-plugin folder and run:
npm install
npm run build
npx @elgato/cli link com.inkwyrd.audiodeck.sdPlugin
Setting up the keys. Drag actions onto keys. For a Soundboard key, select it and type the button's name exactly as it reads on the Soundboard (capitals and spaces count). For a Scene key, type the scene's name (capitals don't matter).
What the key tells you:
There's more detail in streamdeck-plugin/README.md.
A skin changes Inkwyrd's colours, fonts, corner rounding, title bar height and logo and, optionally, draws the buttons, sliders and window frames from pictures of your own (see below).
To change skin, open Settings and pick one under Skin. It applies straight away. Inkwyrd (built-in) always takes you back.
Seven skins are included, in two styles and four colour schemes:
| Colours | Flat | Pixel art |
|---|---|---|
| Green | Inkwyrd (built-in) | Pixel Phosphor |
| Amber | Amber | Pixel Amber |
| Blue | Midnight | Pixel Midnight |
| Black, white and yellow | High Contrast | Pixel High Contrast |
The pixel-art skins draw the buttons, sliders and window frames from pictures and use the Silkscreen pixel font.
Included skins get updated. When a new version of Inkwyrd improves
one of these skins, your copy is replaced with the new one, but only if
you haven't changed it. If you've edited any of its files, Inkwyrd leaves
it exactly as it is. If you've deleted one, it stays deleted. (Each
included skin's folder holds a small .inkwyrd-example.json file that
records what Inkwyrd installed, which is how it can tell.)
To make your own:
skin.json inside it.A skin is a folder under %APPDATA%\Inkwyrd Audio\skins, holding a
skin.json and optionally a logo image:
skins\Amber\skin.json
skins\Amber\logo.png
Everything in the file is optional. Anything you leave out uses Inkwyrd's own value, so a short file is fine.
{
"schemaVersion": 1,
"name": "Amber",
"version": 2,
"colours": { "accent": "#ffb340", "text": "#efc98a" },
"fonts": { "title": "Segoe UI Semibold", "label": "Segoe UI", "digits": "Consolas" },
"metrics": { "cornerRadius": 6, "titleBarHeight": 46 },
"logo": "logo.png"
}
version is your skin's own revision number. Raise it whenever you
change a skin you share, so people can tell which one they have.
Colours are #rrggbb, or #aarrggbb for transparency.
| Colour key | Where you see it |
|---|---|
background | Behind everything, and the deepest areas inside a window |
panelDeep | List and table backgrounds, the cover art slot |
panel | A window's main body |
panelRaised | Buttons, table headings, menus, empty soundboard buttons |
titleBar | The bar across the top of each window |
titleBarText | The window name and buttons on that bar |
titleBarSubtle | The smaller second line ("AUDIO PLAYER") |
text | Normal text |
textDim | Captions, hints and column headings |
accent | The playing track, the seek bar, sliders, selected items, the logo |
accentSoft | Selected rows, scrollbars, pressed buttons |
outline | Borders around panels, buttons and fields |
outlineFaint | The fine lines between rows in a list |
warning | Things needing attention: a missing file, a boosted track |
danger | The close button when you hover over it |
Fonts name a font family. title is for headings, label for all
ordinary text, and digits for the time readout (a monospaced font stops
the numbers jumping about). A font that isn't available falls back to the
default.
A skin can bring its own font, so it works on computers that don't have
it installed: put the font files next to your skin.json and list them
in fontFiles, then name the family under fonts as usual. Include the
font's licence file with them if it has one. Pixel Phosphor does this
with the Silkscreen pixel font.
"fontFiles": [ "Silkscreen-Regular.ttf", "Silkscreen-Bold.ttf" ],
"fonts": { "title": "Silkscreen", "label": "Silkscreen", "digits": "Silkscreen" }
cornerRadius rounds panels, buttons and fields (0 for square).
titleBarHeight is kept between 28 and 80 pixels, so a window can
always be grabbed.
logo names an image next to your skin.json (PNG, JPEG, GIF or
SVG) to use instead of the drawn ink bottle, in every title bar and on
the Player's display. SVGs are drawn without blur, filters or text, so
keep them to plain shapes.
If something's wrong with a skin, Inkwyrd keeps working. A file it can't read leaves the previous look in place and says why under the Skin picker. A single colour it can't understand keeps that one colour and uses the rest of your file.
A skin can also replace how the controls themselves are drawn, with
pictures from one image, a sprite sheet in the skin's folder. The
Pixel Phosphor example skin does this: open its folder and its
sprites.png to see one.
Every picture is optional. Anything you don't draw is drawn the normal way in your skin's colours, so you can start with just the buttons.
"sprites": {
"sheet": "sprites.png",
"scale": 2,
"pixelArt": true,
"items": {
"button": { "rect": [0, 0, 16, 12], "slice": [4, 4, 4, 4] },
"button@down": { "rect": [16, 0, 16, 12], "slice": [4, 4, 4, 4] },
"icon.transport.play": { "rect": [0, 20, 8, 8] },
"window": { "rect": [40, 0, 40, 40], "slice": [6, 6, 6, 6], "tile": true }
}
}
rect is where the picture sits in the sheet: [x, y, width, height]
in pixels.slice keeps the edges from stretching: [left, top, right, bottom].
The corners stay their real size and only the middle stretches, so one
small picture fits a button of any width and a window of any size.tile repeats the edges and middle instead of stretching them, good
for textures and patterned frames.scale is how many screen pixels each sheet pixel becomes (1-8).
Pixel art drawn small looks right at 2 or 3.pixelArt keeps pixels sharp and square when scaled (the default).
Set it to false for smooth artwork.sheet2x (optional) names a second sheet at exactly twice the size,
used on high-resolution screens.What you can draw. Add @over, @down, @on, @onover, @ondown
or @disabled to a name for that state; anything missing falls back to
the plain picture, and a disabled control with no picture of its own is
dimmed.
| Name | What it is |
|---|---|
window | A window's whole background |
titlebar (+ @inactive) | The bar across the top; the title is written over it |
titlebutton | Behind the minimise and close buttons |
button | Every button |
checkbox | A tick box, at its own size (@on when ticked) |
slider.track, slider.fill, slider.thumb | A slider's groove, the filled part, and the knob |
scrollbar.track, scrollbar.thumb | Scroll bars |
textbox (+ @focus), combobox, popup | Text fields, drop-downs, menus |
panel, panel.raised, well | Framed and recessed areas |
display | The Player's now-playing screen |
One control only. Add a control's name after a dot to give just that
control its own picture: button.transport.stop, slider.thumb.master.
An icon. picture is drawn at its own size in place of the button's
words: icon.transport.play. The Player's controls are
transport.play, transport.pause, transport.stop, transport.fadeout,
transport.skip, toggle.shuffle, toggle.mute, toggle.monitor,
toggle.crossfade, toggle.loop, open.playlist, open.library,
open.voicefx, open.soundboard, open.scenes, open.settings, and the
sliders crossfade, loopgap, fadeout, master and mic. The title
bar's own glyphs are icon.close, icon.minimise and icon.maximise.
Toggles are lit (@on) while their option is on.
A misspelt name, a picture that reaches outside the sheet, or a slice wider than its picture is listed under the Skin picker and skipped, the rest of the skin still loads.
Export current... saves colours, fonts and sizes only. To start from a sprite skin, copy its whole folder instead.
For making sheets, tools/skin-builder in the source code generates a
complete sprite skin you can then redraw by hand.
Settings opens from the button at the top of the Player window. It floats over the other windows while it's open.
| Setting | What it does |
|---|---|
| Music folder | Required on first run. Becomes your first playlist, linked to the folder |
| Sound effects folder | Optional. Its sounds are added to free soundboard buttons |
| Discord bot | Token, server and channel, see Connecting to Discord |
| Mute me in Discord | See Muting yourself in Discord automatically |
| Duck the music | See Ducking the music while you talk |
| Tell me when a newer release exists | Checks GitHub once at startup |
| Playlist files | Opens the folder your playlists are saved in |
| Skin | See Skins |
Click Save & Apply to keep your changes. Closing Settings with its X discards them. Everything applies straight away, except changing Discord details after Inkwyrd has already connected: that takes effect the next time it starts, and it offers to restart. Your version number is shown at the bottom right.
Updates. With the update check on, Inkwyrd asks GitHub once at startup whether a newer release exists. If one does, an Update available link appears at the top of the Player window: click it to open the release page in your browser, or hover over it to see the address first. It never downloads or installs anything, you get the new version from that page yourself.
Your files all live in %APPDATA%\Inkwyrd Audio (paste that into
Explorer's address bar to open it): settings, playlists, the
soundboard, scenes, your track library, per-track volumes, cached tags,
your plugin list and skins. Copy that folder to back everything up.
Keep the backup somewhere private: the settings file holds your Discord
bot token as plain text (see
Connecting to Discord).
Log files are in %APPDATA%\Inkwyrd Audio\logs, and Open log
folder in Settings takes you straight there. log.txt covers the run
you're in; log-previous.txt is the run before it, kept so that a crash
you reported after restarting still has its evidence. They record what
Inkwyrd did; which files it loaded, how the Discord connection went,
how long startup took, and a report if it stopped unexpectedly. They
never contain your bot token. Attaching both to a bug report is the
single most useful thing you can do.
Inkwyrd never overwrites a file it can't safely read. If one was written by a newer version of Inkwyrd, or has been damaged, it's left exactly as it is and the warning banner tells you. Changes to that part of the app won't be saved until you go back to the newer version or fix the file, so nothing in it is lost. (The one exception is the tag cache, which is rebuilt, because tags can always be read again from your tracks.)
Player window (click it first):
| Key | Does |
|---|---|
| Space | Play / pause |
| S | Stop |
| Right arrow | Skip to the next track |
| Up / Down | Master volume up / down |
| M | Mic on / off |
| Esc | Killswitch: silence every sound effect |
Elsewhere:
| Where | Key | Does |
|---|---|---|
| Library search box | Esc | Clear the search |
| Library track list | Delete | Remove the selected tracks from the library |
| Playlist window | Delete | Remove the selected tracks from the playlist |
| Playlist window | Up / Down | Move the selected tracks up or down the playlist |
| Playlist window | Ctrl+A | Select every track |
| Playlist window | Shift+click / Ctrl+click | Select a range / pick tracks one at a time |
| Naming a new playlist | Enter | Save the name |
Shortcuts only work while Inkwyrd's window has focus. For control while you're in another program, use a Stream Deck.
I can't hear anything. If you're not connected to Discord, turn Monitor on. Without Discord it's the only way to hear the mix. Also check the Master slider, and the Player's warning banner (it says if the audio device failed to open, or a playlist has no playable files).
I hear everything twice, slightly out of step. Monitor is on while you're in the Discord call. Turn Monitor off: you already hear the bot in the call.
People hear my voice twice. Your own Discord mic and Inkwyrd's are both live. Set up automatic muting, or mute yourself in Discord.
There's feedback or echo from my mic. Wear headphones. Your mic is mixed into the same output as the music.
I can't find how to preview a track. Hover over a track in the Library's All Tracks list and click the play symbol that appears. If All Tracks is empty, click Add folder... and add your music first. See Previewing a track.
The status line says nobody else is here, and Discord gets no sound. That's expected rather than a fault. Discord won't finish setting up its voice encryption until someone else is in the channel, so Inkwyrd waits there with the music playing locally. As soon as a player joins, the sound starts going out on its own. See Connecting to Discord.
The bot is online, but it never joins the voice channel. Nearly always a private voice channel. A private channel only admits the roles listed in its own permissions, and your bot isn't one of them until you add it. Hover the channel, click the gear (Edit Channel -> Permissions), add your bot's role and allow Connect. See Connecting to Discord.
Failing that, check you copied the voice channel's ID rather than a text channel's, and that the channel isn't full. Discord never reports a voice join it won't allow, so nothing appears as an error; Inkwyrd will tell you what it found in the status line.
Discord says my bot token was rejected, or the bot stays offline. Copy the token again from the Developer Portal (Bot tab), and when you paste it into Settings make sure you replace what's in the box rather than adding to it. Inkwyrd checks the shape of what you paste and will tell you if it looks wrong. If the bot never comes online at all, the log says why: Settings, then Open log folder.
My Discord changes didn't do anything. Once Inkwyrd has connected, changes to the bot token, server or channel apply the next time it starts. Accept the restart it offers, or close and reopen it.
"Can't tag this track." It's loaded in the player. Press Stop, then save again.
The warning banner says a file is being kept as it is. That file was written by a newer version of Inkwyrd, or is damaged. It hasn't been touched, but changes to that part of the app won't be saved. Go back to the newer version, or restore the file from a backup. See Settings, updates and your files.
A Stream Deck key shows a warning triangle. Inkwyrd isn't running, or the key needs a sound or scene name. See Using a Stream Deck.
Windows or Defender blocked the download. See the note under Download and install.
Inkwyrd Audio.exe if you want one: right-
click it, Show more options -> Send to -> Desktop.This is a beta, and reports are what make it better.
Please attach your log files to a bug report. Settings -> Open log
folder, then attach log.txt and log-previous.txt. They say what the
app was doing and record a crash if there was one, and they don't contain
your bot token. A screenshot of the Player's status line or warning
banner helps too.
Inkwyrd Audio is free to use, and its source is public to read, but it isn't open source. Copyright (c) 2026 InkWyrd, all rights reserved. The full terms are in LICENSE, and the short version is:
The source is published so you can see exactly what the program does before you run it. That matters here, because the downloads aren't code-signed yet and Windows will warn you about them; "read the code yourself" is the honest answer to "should I trust this?".
If you want to do something the licence doesn't allow, open an issue and ask. It's a small project and the answer may well be yes.
Inkwyrd Audio is built on other people's work, all of it properly licensed and credited in THIRD_PARTY_LICENSES.md, which is also installed next to the program. Those licences are theirs, not affected by the one above, and a few of them grant you rights this licence can't take away.
A new audio program for use with VTT setups, inspired by Kenku.fm and Winamp
C++
0
126 commits
updated Oct 12, 2026
Beta. A Windows app for running the sound of a tabletop game (D&D, Daggerheart, Call of Cthulhu, Pathfinder, anything you like!) over Discord.
You get music playlists that crossfade on their own, a soundboard of effects and looping ambience, scenes that change the whole mood in one press, and your own microphone run through noise suppression and your VST3 plugins. It's all mixed in one place and sent straight into your Discord voice channel through the app's own bot. No virtual audio cable, no DAW, no routing.
It also works with no Discord at all, playing through your own speakers, which is the easiest way to try it.
Inspired by Kenku FM and Winamp.
Inkwyrd Audio is free, and it stays free. If it's saved you some faff at the table and you'd like to put something in the hat:
Entirely optional, and no part of the app is held back for it. Bug reports and suggestions are every bit as useful, and those are free to give.
Inkwyrd Audio Tutorial walks through setting it up and using it. If you'd rather read, the guides below cover the same ground in more detail.
Music
Soundboard and ambience
Scenes
Your voice
Control and comfort
Under the hood
Get the newest release from the Releases page. What changed in each version, all the way back to the first beta, is in CHANGELOG.md.
There's nothing to install. Download
InkwyrdAudio-Portable-<version>.zip, unzip it anywhere you like, your
Desktop, Documents, a USB stick, and run Inkwyrd Audio.exe from
inside. To remove Inkwyrd, delete the folder.
Everything it needs is in that folder, including the Microsoft C++ runtime, so it runs on a fresh Windows install with nothing set up first.
To upgrade, unzip the new version over the old folder, or into a new
one and delete the old. Your settings, playlists, soundboard, scenes,
track library and skins live in %APPDATA%\Inkwyrd Audio, separately
from the program, so they survive either way.
There used to be an installer here, but it's gone now. It did the same job with a Start menu entry and an uninstaller, but it was the part antivirus engines disliked most: an unsigned program that unpacks other programs looks exactly like a dropper to a machine-learning model, whatever it actually does. One download is also one less thing to explain.
If you installed Inkwyrd that way before, uninstall it first (Windows Settings -> Apps -> Installed apps -> Inkwyrd Audio -> Uninstall) then use the ZIP. Your settings and playlists are in
%APPDATA%and aren't touched by uninstalling. Running both at once would leave you with two copies sharing one set of settings, which is confusing rather than harmful.
It will probably say "Windows protected your PC" the first time you run it, and your browser may say the file "isn't commonly downloaded." Both happen because Inkwyrd isn't code-signed. Click More info -> Run anyway.
Microsoft Defender may go further and block it as a threat. Here is the honest position, because you're being asked to run an unsigned program off the internet and you deserve the whole picture:
!ml, Wacatac.B!ml,
Sabsik.EN.D!ml. Those suffixes mean a model guessed, not that anything
was found.So: if Defender blocks it, don't override the block. Open an issue instead and I'll look into it. Overriding your antivirus on the say-so of the person who wrote the program is a bad habit, and I'm not going to ask you to get into it.
If you'd rather satisfy yourself independently: the full source is in this repository and you can build it yourself, every release lists a SHA-256 checksum below, and you can upload the download to VirusTotal and read the results first-hand.
The real fix is code signing, which Inkwyrd doesn't have yet.
Checksums. Every release's notes list the SHA-256 of the download. Check yours matches before running it:
Get-FileHash InkwyrdAudio-Portable-*.zip
This gets you from nothing to music playing, without setting up Discord.
When you're ready to play over Discord, follow Connecting to Discord.
Inkwyrd is six windows you can arrange however suits your screen:
| Window | What it's for |
|---|---|
| Player | The main window: what's playing, the transport buttons, volume and playback settings |
| Playlist | The tracks in the selected playlist |
| Library | Your playlists (top) and every track you've added (bottom) |
| Voice FX | Noise suppression and your microphone plugins |
| Soundboard | The grid of sound-effect buttons |
| Scenes | One-press setups for the whole room |
The warning banner on the Player window is where Inkwyrd tells you about anything that would otherwise fail silently: the audio device didn't open, a playlist has no playable files, tracks are missing from disk, or a file couldn't be read.
When a newer version is out, an Update available link appears at the top of the Player window, next to Settings. Click it to open the release page in your browser.
Everything here is on the Player window.
The display at the top shows the track's artist, title and cover art, the time played and total, a live spectrum of what's being sent out, and a seek bar. Click or drag the seek bar to move through the track.
The transport buttons:
Master is the volume of everything Inkwyrd sends out: your speakers and Discord.
Mic (to the left of Master) is the volume of your voice only - the music and sound effects stay where they are. Turn it down if you're too loud in the call.
The row below sets how playback behaves. All of it is remembered:
Keyboard: click the Player window, then use Space to play or pause, S to stop, Right arrow to skip, Up/Down for the master volume, M for the mic and Esc for the Killswitch. See Keyboard shortcuts.
The Library window's lower half, All Tracks, is every track you've added to Inkwyrd, whether or not it's in a playlist. It's where you search, preview, tag and pick tracks for playlists.
To add music:
Two ways to look at it, switched with Table and Folders next to the heading. Whichever you used last is remembered.
To search, type in the box above the list. It matches title, artist, album, genre and filename, so untagged tracks are still findable. Words match in any order: "drake blue" finds "Blue Drake". In the Folders view, the folders containing matches open up so you can see where they are. Esc or the x clears the search, and the tree goes back the way you had it. The heading shows how many tracks match, for example "All Tracks (12 of 84)".
To remove tracks, select them and click Remove (or press Delete). That takes them out of the library only. It never deletes the files, and doesn't touch any playlist already using them.
A preview plays a track in your ears only, to check it's the one you want, without the table hearing it.
While a preview plays, the playlist pauses and picks up again afterwards. A preview never reaches Discord, and you hear it even when Monitor is off.
Can't see a play symbol? Make sure All Tracks has tracks in it. If it's empty, click Add folder... and add your music.
The Library window's upper half is your playlists. Keep as many as you like: one per location, mood or session.
To make a playlist, click New. A box asks for its name; type it and press Enter.
To put tracks in it:
To play a playlist, double-click it, or select it and click Play. If something is already playing, it crossfades across rather than cutting. Switching back to a playlist later in the same session resumes it where it left off.
Clicking a playlist (single click) just shows its tracks in the Playlist window, without changing what's playing, so you can look through one list while another plays.
Rename and Delete manage the list. Refresh re-reads a playlist's linked folder (see below).
The Playlist window shows the selected playlist's tracks; title, artist and length, in the order they play when Shuffle is off, with the playing one marked.
The playlist made from your Setup music folder is linked to that folder. Music you add to the folder later joins the playlist; click Refresh to pick it up straight away. Tracks in a linked playlist can't be removed one at a time, because they come from the folder.
To see where playlists are stored (readable JSON files), use Open playlists folder in Settings.
Every track has its own volume and its own fade length. Both belong to the file, so a track in several playlists is fixed in all of them at once.
A change applies straight away, even to the track that's playing.
Tags are what a music file says about itself: title, artist, album and so on. Inkwyrd shows them everywhere, and can change them.
Changes are written into the file itself, so every other music program sees them too, and the Library updates straight away.
Editing several tracks at once: select them first, then right-click.
Fields that differ between them show <keep> and are left alone unless
you type in them. So you can fix an album's artist without flattening
thirteen different titles. Only the fields you actually change are
written.
Your files are handled carefully. Inkwyrd never edits a file in place. It copies it, tags the copy, checks the copy still plays, and only then swaps it in. If anything fails, the original is untouched.
A track that's currently loaded in the player can't be tagged, because Windows won't let a file in use be replaced. Press Stop and save again. A track being previewed is fine: the preview stops itself.
The Soundboard window is a grid of buttons for sound effects.
To put a sound on a button:
To play a sound, click its button. Sounds can overlap, and the same button can be pressed repeatedly.
To rearrange the board, drag a button onto another to swap them, or onto an empty one to move it there. Everything moves with the button, including its name, so Stream Deck keys keep working.
Right-click a button to:
+ and - at the top add or remove buttons. A button with a sound on it is never removed.
Killswitch (top of the window, or Esc on the Player) instantly silences every sound effect playing, loops included, and switches off any sound set to play randomly. It never touches the music: use Stop or Fade out on the Player for that.
A button whose file has gone missing says (file missing) rather than silently doing nothing.
Any soundboard button can loop instead of playing once. That's what you want for rain, a crackling fire, a tavern crowd or wind: sounds that should run under the music until you say otherwise.
The same press starts and stops it from a Stream Deck too, and the Killswitch stops it. Each loop keeps its own volume, so you can set an ambience bed quietly under the music and leave it.
Loops are what scenes switch on and off.
Any button can fade in when it starts and fade out when it stops, instead of starting and stopping at full volume. Right-click it and choose a length under Fade in and Fade out (from half a second to ten seconds), or Off.
Scenes keep their own fade settings for each sound, so the same rain can swell in slowly in one scene and cut in at once in another.
A sound effect can play on its own every so often, such as a seagull over the waves, distant thunder, a creak in an old house, while the rest of the scene carries on.
Right-click the button and choose Play randomly.
Pick how often:
Each gap is picked at random within its range, so it never falls into a pattern. The first one comes sooner, so you can tell it's on.
A small dice appears in the button's top corner while it's playing randomly.
Clicking the button still plays it straight away, whenever you like. It never plays over itself: if one is still playing when the next is due, that turn is skipped. To stop it, choose Play randomly -> Off, or press the Killswitch.
Random play is for sounds that play once. A looping button can't play randomly, since it never finishes. It also doesn't switch itself on when Inkwyrd starts, the same as loops: save it in a scene and pressing the scene switches it on.
A scene is one press that sets the whole room: which playlist plays, which looping sounds are running, which sounds play randomly, and (if you choose) the master volume. For example "Tavern", "Road", "Combat" or "Storm".
Open the Scenes window from the Scenes button on the Player.
To make a scene:
To use a scene, click it. Here's what happens:
The scene you last pressed is outlined. A scene change takes as long as the Player's crossfade setting, and never less than a second.
Right-click a scene to:
If something a scene uses disappears (its playlist is deleted, or a soundboard button is cleared or stops looping), its button says how many things are missing and hovering over it says which. The rest of the scene still works. Renaming a soundboard button updates every scene that uses it, and moving buttons around the board changes nothing.
Your mic is mixed in with the music and sent to Discord. The Mic button on the Player (or M) turns it on and off, and the setting is remembered.
The Mic slider on the Player sets how loud your voice is, without touching the music or sound effects. It's remembered too. It doesn't change what ducking counts as speech, so turning yourself down won't stop the music dipping when you talk.
The Voice FX window shapes how you sound.
Noise suppression (at the top, off by default) removes steady background noise, a fan, hiss, room tone, from the gaps between your words. Turn it on for a noisy mic and leave it off for a quiet one: on a clean mic it takes more from your voice than from the noise. It adds about 40ms of delay. The line under the switch says which state you're in.
Your plugin chain runs your mic through VST3 plugins you already own (EQ, compression, a noise gate and so on).
Save your settings as each plugin's own presets. The chain itself isn't remembered between sessions. Noise suppression runs before your plugins, so they shape your voice rather than your room.
With ducking on, the music and sound effects dip while you're speaking and come back when you stop, so you can narrate without riding the Master slider.
The timing is fixed: it dips fast enough not to clip your first word, and waits a moment before coming back so the music doesn't surge up between sentences. It listens to your mic after noise suppression and your plugins, so a noise gate you already use decides what counts as speech. A muted mic never ducks anything, and your voice itself is never ducked.
Inkwyrd plays into Discord as its own bot, so you need a bot of your own. It's free and takes about five minutes.
Create the bot:
Invite it to your server:
5. Open OAuth2 -> URL Generator. Under Scopes tick bot; under
Bot Permissions tick Connect and Speak. Copy the URL at the
bottom.
6. Open that URL in your browser, pick your server, and click
Authorize. The bot appears in your member list (offline until
Inkwyrd connects it).
Get the server and channel IDs: 7. In Discord, turn on User Settings -> Advanced -> Developer Mode. 8. Right-click your server's icon and Copy Server ID. 9. Right-click the voice channel the bot should join and Copy Channel ID. Make sure it's the voice channel (the one under the speaker icon that people join), not the text channel above it.
If that voice channel is private, the bot needs to be let in. A private channel only admits the roles and people named in its own permissions, and a bot you've just invited isn't one of them. The Connect permission from the invite link applies to the server as a whole and doesn't override a channel's own settings.
To fix it: hover the channel in Discord, click the gear (Edit Channel) -> Permissions, add your bot's role under Roles / Members, and allow Connect.
You can tell this is the problem because Inkwyrd connects, the bot appears in your member list, and it simply never joins the channel. Discord doesn't report a voice join it won't allow, so there's no error anywhere: it just never happens.
Put them into Inkwyrd: 10. Open Settings, paste the Bot token, Server (guild) ID and Voice channel ID, and click Save & Apply. 11. Inkwyrd connects straight away, and the status line at the top of the Player shows how it's going. Changing these details later, once it has connected, takes effect the next time Inkwyrd starts; it offers to restart for you.
Where your token is kept, and how to cancel it. Inkwyrd saves the bot token in its settings file at
%APPDATA%\Inkwyrd Audio\Inkwyrd Audio.settings, as ordinary text that isn't encrypted. Anyone who can read that file can use your bot.That's fine on a computer only you use, and worth knowing about otherwise. Two things follow from it:
- Don't send anyone that file - including when you report a bug. Send the log files instead (Settings -> Open log folder); the log deliberately never records your token.
- If you think it has got out, go to the Developer Portal -> your app -> Bot -> Reset Token. The old token stops working immediately. Paste the new one into Settings.
The same applies to the client secret if you set up automatic muting. Your bot can only join voice channels and speak, on servers you invited it to, so the worst case is somebody playing audio at your group, not access to your Discord account.
Starting before anyone else has joined is fine. Discord sets its voice encryption up as a group, and it won't finish doing that until there's somebody to share it with, so a bot sitting alone in a channel waits. While it's waiting, the status line says "In the voice channel, nobody else here yet, so nothing is being sent to Discord" and your music plays locally only. The moment a player joins, sound starts reaching the channel on its own. Nothing to press.
Inkwyrd rebuilds the connection by itself if Discord drops it. Discord ends a call whose channel has been empty for a while, and moves bots between its own servers from time to time. Either way you'll see "Reconnecting to the voice channel..." and it carries on. You don't need to restart it.
Once you're connected, turn Monitor off. You're in the call too, so you already hear everything through the bot.
When your mic is live in Inkwyrd, your voice reaches the call twice: once from your own Discord client and again through the bot. Inkwyrd can mute you in Discord whenever your mic is live here, and unmute you when it isn't.
This is optional. If you only use Inkwyrd for music and effects, skip it. It uses the same Discord application as your bot:
https://inkwyrd.com/rpc exactly, and Save Changes. Nothing is
ever sent there, Discord just requires one. It must be that exact
address, and first in the list if you have several.It mutes your own Discord client on your own machine, so it needs no special server permissions and works in any server.
Inkwyrd has a plugin for Elgato's Stream Deck. Every key works while Inkwyrd is running.
| Action | What it does |
|---|---|
| Skip Track | Crossfades to the next track |
| Toggle Shuffle | Turns shuffle on or off |
| Toggle Mic Mute | Turns your mic on or off |
| Music Fade Out | Same as the Player's Fade out button, taking the same time |
| Soundboard | Plays one soundboard sound, or starts/stops a loop |
| Soundboard Killswitch | Silences every sound effect; the music keeps playing |
| Scene | Switches to a scene |
Installing it. The plugin isn't in the download yet, it's built from this repository's source. You need the Stream Deck app (version 6.5 or later) and Node.js.
git clone).streamdeck-plugin folder and run:
npm install
npm run build
npx @elgato/cli link com.inkwyrd.audiodeck.sdPlugin
Setting up the keys. Drag actions onto keys. For a Soundboard key, select it and type the button's name exactly as it reads on the Soundboard (capitals and spaces count). For a Scene key, type the scene's name (capitals don't matter).
What the key tells you:
There's more detail in streamdeck-plugin/README.md.
A skin changes Inkwyrd's colours, fonts, corner rounding, title bar height and logo and, optionally, draws the buttons, sliders and window frames from pictures of your own (see below).
To change skin, open Settings and pick one under Skin. It applies straight away. Inkwyrd (built-in) always takes you back.
Seven skins are included, in two styles and four colour schemes:
| Colours | Flat | Pixel art |
|---|---|---|
| Green | Inkwyrd (built-in) | Pixel Phosphor |
| Amber | Amber | Pixel Amber |
| Blue | Midnight | Pixel Midnight |
| Black, white and yellow | High Contrast | Pixel High Contrast |
The pixel-art skins draw the buttons, sliders and window frames from pictures and use the Silkscreen pixel font.
Included skins get updated. When a new version of Inkwyrd improves
one of these skins, your copy is replaced with the new one, but only if
you haven't changed it. If you've edited any of its files, Inkwyrd leaves
it exactly as it is. If you've deleted one, it stays deleted. (Each
included skin's folder holds a small .inkwyrd-example.json file that
records what Inkwyrd installed, which is how it can tell.)
To make your own:
skin.json inside it.A skin is a folder under %APPDATA%\Inkwyrd Audio\skins, holding a
skin.json and optionally a logo image:
skins\Amber\skin.json
skins\Amber\logo.png
Everything in the file is optional. Anything you leave out uses Inkwyrd's own value, so a short file is fine.
{
"schemaVersion": 1,
"name": "Amber",
"version": 2,
"colours": { "accent": "#ffb340", "text": "#efc98a" },
"fonts": { "title": "Segoe UI Semibold", "label": "Segoe UI", "digits": "Consolas" },
"metrics": { "cornerRadius": 6, "titleBarHeight": 46 },
"logo": "logo.png"
}
version is your skin's own revision number. Raise it whenever you
change a skin you share, so people can tell which one they have.
Colours are #rrggbb, or #aarrggbb for transparency.
| Colour key | Where you see it |
|---|---|
background | Behind everything, and the deepest areas inside a window |
panelDeep | List and table backgrounds, the cover art slot |
panel | A window's main body |
panelRaised | Buttons, table headings, menus, empty soundboard buttons |
titleBar | The bar across the top of each window |
titleBarText | The window name and buttons on that bar |
titleBarSubtle | The smaller second line ("AUDIO PLAYER") |
text | Normal text |
textDim | Captions, hints and column headings |
accent | The playing track, the seek bar, sliders, selected items, the logo |
accentSoft | Selected rows, scrollbars, pressed buttons |
outline | Borders around panels, buttons and fields |
outlineFaint | The fine lines between rows in a list |
warning | Things needing attention: a missing file, a boosted track |
danger | The close button when you hover over it |
Fonts name a font family. title is for headings, label for all
ordinary text, and digits for the time readout (a monospaced font stops
the numbers jumping about). A font that isn't available falls back to the
default.
A skin can bring its own font, so it works on computers that don't have
it installed: put the font files next to your skin.json and list them
in fontFiles, then name the family under fonts as usual. Include the
font's licence file with them if it has one. Pixel Phosphor does this
with the Silkscreen pixel font.
"fontFiles": [ "Silkscreen-Regular.ttf", "Silkscreen-Bold.ttf" ],
"fonts": { "title": "Silkscreen", "label": "Silkscreen", "digits": "Silkscreen" }
cornerRadius rounds panels, buttons and fields (0 for square).
titleBarHeight is kept between 28 and 80 pixels, so a window can
always be grabbed.
logo names an image next to your skin.json (PNG, JPEG, GIF or
SVG) to use instead of the drawn ink bottle, in every title bar and on
the Player's display. SVGs are drawn without blur, filters or text, so
keep them to plain shapes.
If something's wrong with a skin, Inkwyrd keeps working. A file it can't read leaves the previous look in place and says why under the Skin picker. A single colour it can't understand keeps that one colour and uses the rest of your file.
A skin can also replace how the controls themselves are drawn, with
pictures from one image, a sprite sheet in the skin's folder. The
Pixel Phosphor example skin does this: open its folder and its
sprites.png to see one.
Every picture is optional. Anything you don't draw is drawn the normal way in your skin's colours, so you can start with just the buttons.
"sprites": {
"sheet": "sprites.png",
"scale": 2,
"pixelArt": true,
"items": {
"button": { "rect": [0, 0, 16, 12], "slice": [4, 4, 4, 4] },
"button@down": { "rect": [16, 0, 16, 12], "slice": [4, 4, 4, 4] },
"icon.transport.play": { "rect": [0, 20, 8, 8] },
"window": { "rect": [40, 0, 40, 40], "slice": [6, 6, 6, 6], "tile": true }
}
}
rect is where the picture sits in the sheet: [x, y, width, height]
in pixels.slice keeps the edges from stretching: [left, top, right, bottom].
The corners stay their real size and only the middle stretches, so one
small picture fits a button of any width and a window of any size.tile repeats the edges and middle instead of stretching them, good
for textures and patterned frames.scale is how many screen pixels each sheet pixel becomes (1-8).
Pixel art drawn small looks right at 2 or 3.pixelArt keeps pixels sharp and square when scaled (the default).
Set it to false for smooth artwork.sheet2x (optional) names a second sheet at exactly twice the size,
used on high-resolution screens.What you can draw. Add @over, @down, @on, @onover, @ondown
or @disabled to a name for that state; anything missing falls back to
the plain picture, and a disabled control with no picture of its own is
dimmed.
| Name | What it is |
|---|---|
window | A window's whole background |
titlebar (+ @inactive) | The bar across the top; the title is written over it |
titlebutton | Behind the minimise and close buttons |
button | Every button |
checkbox | A tick box, at its own size (@on when ticked) |
slider.track, slider.fill, slider.thumb | A slider's groove, the filled part, and the knob |
scrollbar.track, scrollbar.thumb | Scroll bars |
textbox (+ @focus), combobox, popup | Text fields, drop-downs, menus |
panel, panel.raised, well | Framed and recessed areas |
display | The Player's now-playing screen |
One control only. Add a control's name after a dot to give just that
control its own picture: button.transport.stop, slider.thumb.master.
An icon. picture is drawn at its own size in place of the button's
words: icon.transport.play. The Player's controls are
transport.play, transport.pause, transport.stop, transport.fadeout,
transport.skip, toggle.shuffle, toggle.mute, toggle.monitor,
toggle.crossfade, toggle.loop, open.playlist, open.library,
open.voicefx, open.soundboard, open.scenes, open.settings, and the
sliders crossfade, loopgap, fadeout, master and mic. The title
bar's own glyphs are icon.close, icon.minimise and icon.maximise.
Toggles are lit (@on) while their option is on.
A misspelt name, a picture that reaches outside the sheet, or a slice wider than its picture is listed under the Skin picker and skipped, the rest of the skin still loads.
Export current... saves colours, fonts and sizes only. To start from a sprite skin, copy its whole folder instead.
For making sheets, tools/skin-builder in the source code generates a
complete sprite skin you can then redraw by hand.
Settings opens from the button at the top of the Player window. It floats over the other windows while it's open.
| Setting | What it does |
|---|---|
| Music folder | Required on first run. Becomes your first playlist, linked to the folder |
| Sound effects folder | Optional. Its sounds are added to free soundboard buttons |
| Discord bot | Token, server and channel, see Connecting to Discord |
| Mute me in Discord | See Muting yourself in Discord automatically |
| Duck the music | See Ducking the music while you talk |
| Tell me when a newer release exists | Checks GitHub once at startup |
| Playlist files | Opens the folder your playlists are saved in |
| Skin | See Skins |
Click Save & Apply to keep your changes. Closing Settings with its X discards them. Everything applies straight away, except changing Discord details after Inkwyrd has already connected: that takes effect the next time it starts, and it offers to restart. Your version number is shown at the bottom right.
Updates. With the update check on, Inkwyrd asks GitHub once at startup whether a newer release exists. If one does, an Update available link appears at the top of the Player window: click it to open the release page in your browser, or hover over it to see the address first. It never downloads or installs anything, you get the new version from that page yourself.
Your files all live in %APPDATA%\Inkwyrd Audio (paste that into
Explorer's address bar to open it): settings, playlists, the
soundboard, scenes, your track library, per-track volumes, cached tags,
your plugin list and skins. Copy that folder to back everything up.
Keep the backup somewhere private: the settings file holds your Discord
bot token as plain text (see
Connecting to Discord).
Log files are in %APPDATA%\Inkwyrd Audio\logs, and Open log
folder in Settings takes you straight there. log.txt covers the run
you're in; log-previous.txt is the run before it, kept so that a crash
you reported after restarting still has its evidence. They record what
Inkwyrd did; which files it loaded, how the Discord connection went,
how long startup took, and a report if it stopped unexpectedly. They
never contain your bot token. Attaching both to a bug report is the
single most useful thing you can do.
Inkwyrd never overwrites a file it can't safely read. If one was written by a newer version of Inkwyrd, or has been damaged, it's left exactly as it is and the warning banner tells you. Changes to that part of the app won't be saved until you go back to the newer version or fix the file, so nothing in it is lost. (The one exception is the tag cache, which is rebuilt, because tags can always be read again from your tracks.)
Player window (click it first):
| Key | Does |
|---|---|
| Space | Play / pause |
| S | Stop |
| Right arrow | Skip to the next track |
| Up / Down | Master volume up / down |
| M | Mic on / off |
| Esc | Killswitch: silence every sound effect |
Elsewhere:
| Where | Key | Does |
|---|---|---|
| Library search box | Esc | Clear the search |
| Library track list | Delete | Remove the selected tracks from the library |
| Playlist window | Delete | Remove the selected tracks from the playlist |
| Playlist window | Up / Down | Move the selected tracks up or down the playlist |
| Playlist window | Ctrl+A | Select every track |
| Playlist window | Shift+click / Ctrl+click | Select a range / pick tracks one at a time |
| Naming a new playlist | Enter | Save the name |
Shortcuts only work while Inkwyrd's window has focus. For control while you're in another program, use a Stream Deck.
I can't hear anything. If you're not connected to Discord, turn Monitor on. Without Discord it's the only way to hear the mix. Also check the Master slider, and the Player's warning banner (it says if the audio device failed to open, or a playlist has no playable files).
I hear everything twice, slightly out of step. Monitor is on while you're in the Discord call. Turn Monitor off: you already hear the bot in the call.
People hear my voice twice. Your own Discord mic and Inkwyrd's are both live. Set up automatic muting, or mute yourself in Discord.
There's feedback or echo from my mic. Wear headphones. Your mic is mixed into the same output as the music.
I can't find how to preview a track. Hover over a track in the Library's All Tracks list and click the play symbol that appears. If All Tracks is empty, click Add folder... and add your music first. See Previewing a track.
The status line says nobody else is here, and Discord gets no sound. That's expected rather than a fault. Discord won't finish setting up its voice encryption until someone else is in the channel, so Inkwyrd waits there with the music playing locally. As soon as a player joins, the sound starts going out on its own. See Connecting to Discord.
The bot is online, but it never joins the voice channel. Nearly always a private voice channel. A private channel only admits the roles listed in its own permissions, and your bot isn't one of them until you add it. Hover the channel, click the gear (Edit Channel -> Permissions), add your bot's role and allow Connect. See Connecting to Discord.
Failing that, check you copied the voice channel's ID rather than a text channel's, and that the channel isn't full. Discord never reports a voice join it won't allow, so nothing appears as an error; Inkwyrd will tell you what it found in the status line.
Discord says my bot token was rejected, or the bot stays offline. Copy the token again from the Developer Portal (Bot tab), and when you paste it into Settings make sure you replace what's in the box rather than adding to it. Inkwyrd checks the shape of what you paste and will tell you if it looks wrong. If the bot never comes online at all, the log says why: Settings, then Open log folder.
My Discord changes didn't do anything. Once Inkwyrd has connected, changes to the bot token, server or channel apply the next time it starts. Accept the restart it offers, or close and reopen it.
"Can't tag this track." It's loaded in the player. Press Stop, then save again.
The warning banner says a file is being kept as it is. That file was written by a newer version of Inkwyrd, or is damaged. It hasn't been touched, but changes to that part of the app won't be saved. Go back to the newer version, or restore the file from a backup. See Settings, updates and your files.
A Stream Deck key shows a warning triangle. Inkwyrd isn't running, or the key needs a sound or scene name. See Using a Stream Deck.
Windows or Defender blocked the download. See the note under Download and install.
Inkwyrd Audio.exe if you want one: right-
click it, Show more options -> Send to -> Desktop.This is a beta, and reports are what make it better.
Please attach your log files to a bug report. Settings -> Open log
folder, then attach log.txt and log-previous.txt. They say what the
app was doing and record a crash if there was one, and they don't contain
your bot token. A screenshot of the Player's status line or warning
banner helps too.
Inkwyrd Audio is free to use, and its source is public to read, but it isn't open source. Copyright (c) 2026 InkWyrd, all rights reserved. The full terms are in LICENSE, and the short version is:
The source is published so you can see exactly what the program does before you run it. That matters here, because the downloads aren't code-signed yet and Windows will warn you about them; "read the code yourself" is the honest answer to "should I trust this?".
If you want to do something the licence doesn't allow, open an issue and ask. It's a small project and the answer may well be yes.
Inkwyrd Audio is built on other people's work, all of it properly licensed and credited in THIRD_PARTY_LICENSES.md, which is also installed next to the program. Those licences are theirs, not affected by the one above, and a few of them grant you rights this licence can't take away.