Files

196 lines
7.5 KiB
Markdown

# Sound Tower Controller
A small, unofficial desktop remote for Samsung Sound Tower speakers. Control
EQ, bass, lighting, RGB color, volume, mute, playback, and source selection
through Bluetooth Low Energy.
Verified interactively on one **Samsung MX-T40 with Windows**. Other models
and operating systems have not been verified. No firmware flashing, Samsung
account, or bundled vendor software is required.
## Run with uv
Use Windows Python for a Windows Bluetooth adapter. From WSL, invoke `uv.exe`
so Bluetooth runs on Windows rather than inside WSL.
```powershell
uv run soundtower
```
For WSL:
```bash
uv.exe run soundtower
```
1. Turn on Windows Bluetooth and power on the speaker. Close the phone's Sound
Tower app if it is holding the control connection.
2. Click **Scan**. The window stays responsive during the eight-second search.
3. Choose your speaker in the **Speaker** dropdown, then click **Connect**.
A single result is selected automatically when the field is empty; the app
never connects automatically. Addresses distinguish speakers with the same name.
4. Wait for **Speaker handshake complete**, then use the controls.
The MX-T40 can advertise without a name. The selector recognizes its known
model advertisement and shows **MX-T40 (model advertisement)** in that case.
Discovery of another Sound Tower model is not a compatibility guarantee.
`uv run python -m controller` remains supported, as does the earlier
`--with-requirements requirements.txt` launch command.
### Finding or entering the Bluetooth address manually
The selector includes the Bluetooth address after each speaker name. You can
also list candidate names and addresses from the terminal without opening Tk
or connecting to a speaker:
```powershell
uv run python -m controller.discovery
```
An address looks like `12:34:56:78:9A:BC`. Copy your speaker's actual address,
not that example, and either type it in the editable **Speaker** field or use:
```powershell
uv run soundtower --address YOUR_SPEAKER_MAC
```
Use the address observed in the BLE scan rather than assuming an audio-device
display name is an address. If no speaker appears, ensure Windows Bluetooth
and the speaker are on, close the phone app, and scan again. An already open
phone connection can affect advertising. Scanning lists advertisements only;
it does not send control commands or pair/remove devices.
Python 3.11 or newer is required; physical device testing used Windows Python
3.14. The interpreter needs Tcl/Tk. If the interpreter provided by uv lacks Tk,
use a Windows Python installation with Tk support, for example:
```powershell
uv run --python C:\Path\To\Python\python.exe soundtower --address YOUR_SPEAKER_MAC
```
## Build a Windows executable
Build using **Windows PowerShell and Windows Python**, not a Linux Python
interpreter in WSL. [PyInstaller builds for the operating system it runs on](https://pyinstaller.org/en/stable/).
```powershell
git clone https://git.ldlda.com/lda/soundtower-controller.git
cd soundtower-controller
uv run --locked --python 3.14 --group bundle python scripts/build_exe.py
```
If you already cloned the repository, run `git pull --ff-only` there instead
of cloning again. If uv's selected interpreter lacks Tcl/Tk, use a Windows
Python installation with Tk via `--python C:\Path\To\Python\python.exe`.
The application is created at:
```text
dist\SoundTowerController\SoundTowerController.exe
```
Double-click it and use Scan → choose speaker → Connect. Keep the **entire
SoundTowerController folder**, including `_internal`, together when copying it
to another computer. The recipient does not need uv or Python installed.
For a single-file executable instead:
```powershell
uv run --locked --python 3.14 --group bundle python scripts/build_exe.py --onefile
```
That creates `dist\SoundTowerController.exe`; it extracts dependencies when
launched. If startup fails, rebuild with `--console` to see the error. No code
signing certificate is configured, so the build is an unsigned executable.
The build script's arguments are tested; a real Windows executable build still
requires validation on Windows.
## Controls
- EQ: Party, Standard, Hip-hop, EDM, Rock, Latin, House, Reggae.
- Bass boost, volume up/down, mute, play/pause, and audio source.
- Lighting: Off, Ambient, Party, Dance, Thunder, Star, Lover, Color.
- RGB color picker; lighting mode is queried after a color change.
- Readable activity log with optional raw packet display.
A command acknowledgment means the packet was received. A later status report
confirms the reported setting; the log distinguishes the two. Choosing an RGB
color switches the tested speaker to COLOR mode. A play/pause event does not
reveal the absolute playback state.
The source menu includes protocol options that may not exist on every model.
The tested MX-T40 reports Bluetooth, USB 1, AUX 1, and AUX 2.
## Audio versus control
This app opens the BLE remote-control connection. Windows establishes the
separate audio playback connection. Neither a BLE connection nor Windows'
word “Connected” guarantees an audio output is available.
If the speaker disappears from Windows' output list, disconnect/reconnect it
through Windows and select it as the sound output. Both connection orders
have worked in testing; no fixed startup order is established. Once playback
works, the BLE controller can operate alongside it.
The older RFCOMM/COM path is experimental and was unreliable on this MX-T40:
`--transport rfcomm` selects it. BLE is the default.
## Development
```bash
uv run --group dev python -m unittest discover -s tests -v
uv run --group dev ruff check controller tests scripts
uv run --group dev ruff format --check controller tests scripts
uv build
```
The committed `uv.lock` pins runtime, development, and Windows build dependencies.
Use `uv lock` when intentionally changing dependencies; the executable build
examples use `--locked` so an out-of-date lockfile fails rather than changing
silently.
The tests use captured packet fixtures and fake transports; they do not need
a speaker, Tk, or a display. They do not replace physical compatibility tests.
The optional GitHub Actions workflow runs headless tests on Windows/Linux and
Python 3.11/3.14. The same commands can be used in Gitea CI.
See [architecture](docs/ARCHITECTURE.md), [protocol](docs/PROTOCOL.md),
[feature research](docs/FEATURES.md), and [contributing](CONTRIBUTING.md).
## Diagnostics
List the MX-T40's advertised BLE/GATT endpoints without sending controls:
```powershell
uv run python -m controller.ble_probe
```
Experimental Windows RFCOMM discovery:
```powershell
uv run --extra diagnostics python -m controller.probe --channel 1
```
## Preparing a repository
If working from a mixed firmware-research workspace, export only the controller,
tests, and original documentation into a **new, empty directory**. A normal
clone of this repository already contains only the publishable source:
```bash
python scripts/export_project.py dist/soundtower-controller
```
The export uses an explicit allowlist. Firmware, APKs, extracted vendor files,
decompiled Java, environment files, and caches are excluded. Initialize Git in
that exported directory before adding a GitHub or Gitea remote. No remote is
configured and nothing is uploaded automatically.
## Project status
This is an independent interoperability project, not an official Samsung or
Qualcomm product. It contains original controller code and protocol notes,
not redistributed firmware or application code. A project license has not yet
been selected; no open-source license grant is currently declared.