Skip to content

Audio output in the Insert menu: Auto, Stereo or 5.1 - #1240

Merged
hckrman101 merged 1 commit into
NotRexed:mainfrom
janvitos:feat/audio-output-menu
Nov 9, 2026
Merged

hckrman101 merged 1 commit into
NotRexed:mainfrom
janvitos:feat/audio-output-menu

Conversation

@janvitos

@janvitos janvitos commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

A follow-up to #1182, as suggested in its review: an Audio output row in the Insert menu (Gameplay) with Auto, Stereo and 5.1.

What

  • Auto (the default) is Mix for 5.1 when the default output has 5.1 speakers #1182's behaviour: 5.1 when the default output device has 5.1 or more speakers, else stereo.
  • Stereo or 5.1 chooses one whatever the device has. 5.1 on stereo speakers is mixed down, as before.
  • Saved as audio_output= in hookshot_options.ini. host/nn_audio.c reads it from the file, the way nn_applet.c reads the Handheld profile, because the game asks for its speakers only once, at its start. The row says "(restart)", like Output resolution.
  • HOS_AUDIO_CHANNELS=2 or 6 still wins over the menu.
  • readme: the options table and a short note under it.

How it was tested

  • Machine: Linux (CachyOS), RTX 4070 SUPER, default output stereo.

  • In game: a game build with this host change, on the v2.0.8-rc.5 source plus Mix for 5.1 when the default output has 5.1 speakers #1182, with headless runs. In each run the log line and the dumped audio's channel count match:

    audio_output HOS_AUDIO_CHANNELS The game is told Dump
    1 — stereo (the Insert menu's Audio output) 2 ch
    2 — 5.1 (the Insert menu's Audio output) 6 ch
    0 — stereo (the default output has 2 channels) 2 ch
    1 6 5.1 (HOS_AUDIO_CHANNELS) 6 ch
  • Not tested: the menu row itself wasn't seen in game. This PC has no Vulkan toolchain, so the build used the release's prebuilt Vulkan back end.

  • New test: tests/test_audio_output_menu.py compiles the real au_speakers and au_menu_output together with the menu's ini_key and tx_audio_output. It writes the row's choice under the key the menu would save, so a renamed row or key fails it. It covers Auto with a 2-, 6- and 8-channel device, Stereo, 5.1, hand-edited 3 and -1 (clamped as the menu reads them), and HOS_AUDIO_CHANNELS over the menu. It's registered in run_all.py with --cxx g++. I checked that it fails when the host ignores the menu, when the key is misspelled or when the row is renamed.

  • Windows: host/nn_audio.c passes a syntax check with mingw-w64 and has the same warnings as main's.

  • Suite: on this branch (on 09e4eb5), python -I -B tests/run_all.py gives 144 passed, 2 failed, 17 skipped on Linux. Both failures are the same on unchanged main here:

    • nx2/test_nup_read_name.py needs zstandard, which isn't installed here.
    • tests/test_output_resolution.py aborts on its first case.

🤖 Generated with Claude Code

@janvitos

janvitos commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

The two failing checks are tests/test_output_resolution.py, which also fails on main's own CI (fe611e4, Linux and Windows). tests/test_audio_output_menu.py passes on both, and both Vulkan back-end builds pass.

A follow-up to NotRexed#1182, as suggested in its review: the speakers the game
mixes for can be chosen in the Insert menu (Gameplay), not only with
HOS_AUDIO_CHANNELS. Auto keeps NotRexed#1182's behaviour (5.1 when the default
output has 5.1 or more, else stereo); Stereo or 5.1 chooses one whatever
the device has. The choice is saved as audio_output= in
hookshot_options.ini and read by host/nn_audio.c from the file, as
nn_applet.c reads the Handheld profile: the game asks for its speakers
once, at its start. The row is a restart row (Row::restart), so the menu
marks a change "(after restart)" and offers a restart on closing; each
value has a hint line. HOS_AUDIO_CHANNELS still wins over the menu.

tests/test_audio_output_menu.py compiles the real au_speakers with the
menu's ini_key, value texts and hints, so the key the menu saves is the
one the host reads, and checks the row is a preset-exempt restart row.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@janvitos
janvitos force-pushed the feat/audio-output-menu branch from 5e8c1d6 to 4856258 Compare November 9, 2026 19:33
@janvitos

janvitos commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks. Rebased onto main (ac3bd44) as 4856258:

  • The row now ends hn_audio_output, true, true}: a restart row, still preset-exempt, so a change shows "(after restart)", joins the Restart needed list, and closing the menu offers the restart.
  • The values are plain Auto, Stereo, 5.1, with a hint line each (hn_audio_output via MENU_HINTS).
  • menu_restart.h's comment now counts six restart rows (kMax is 8).
  • The test checks the row's hint, restart and preset_exempt fields and the hints against main's Row.

@hckrman101
hckrman101 merged commit 95fd521 into NotRexed:main Nov 9, 2026
10 checks passed
wyatt-poole added a commit to wyatt-poole/Hookshot that referenced this pull request Nov 10, 2026
Conflicts in gpu/vk/vk_menu.cpp with main's Audio output row (NotRexed#1240) and
the Restart/Quit confirm (NotRexed#1266, NotRexed#1255): tx_deadzone and tx_audio_output
both kept; Esc on the Motion page goes back before the pending confirm
is cancelled; the Motion row opens its page after the Cheats row's test
in main's confirm chain. TAB_MOTION is now TAB_COUNT itself (one past
the strip), and tab_selected is sized by it, so a tab added before
TAB_COUNT (NotRexed#1270) moves the Motion page along instead of colliding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BsKC8mjbyEUFAv6uy3SQiW
bvtterbroot added a commit to bvtterbroot/Hookshot that referenced this pull request Nov 10, 2026
The Insert menu gets an Audio tab between Graphics and Gameplay:

- Volume, 0 to 100% in steps of 5, on a squared curve (50% is -12 dB): the
  mixer scales each frame before the output, on every output channel, and
  ramps a change over one frame so it does not click.
- Mute in background: silent while another window has the focus. A tool or
  no-activate window in front (Steam's or Discord's overlay, a toast, a tray
  flyout) counts as the game's only while the last normal window in front was
  the game's, as host/nn_hid.c's game_in_front decides it; the mixer keeps its
  own state.
- Audio output (NotRexed#1240) moves here from the Gameplay tab.

The host reads the two new rows through the renderer's option table every
100 ms (HOS_OPT_VOLUME 27, HOS_OPT_MUTE_BACKGROUND 28). Out of the box nothing
changes: 100% and off. Without the Vulkan renderer's menu the game plays at
full volume.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant