60267d450b
Allow users to allocate multiple virtual channels independently of browser tab count. Channels survive SDR center-frequency retuning as long as they stay within the capture bandwidth; channels that fall outside the SDR span are automatically destroyed. Changes: - trx-core: add AUDIO_MSG_VCHAN_DESTROYED (0x12) wire constant; add default subscribe_destroyed() to VirtualChannelManager trait - trx-backend-soapysdr: update_center_hz() detects OOB channels, removes them, fires destroyed_tx broadcast; add destroyed_sender() and subscribe_destroyed() override - trx-server/audio: recv_destroyed() helper avoids select! busy-loop for non-SDR backends; send AUDIO_MSG_VCHAN_DESTROYED to client when a channel is evicted server-side - trx-client/audio_client: persist active_subs across TCP reconnects, re-subscribe on reconnect; handle AUDIO_MSG_VCHAN_DESTROYED by pruning vchan_audio map and forwarding UUID via vchan_destroyed_tx - trx-frontend/lib: add vchan_destroyed broadcast field to FrontendRuntimeContext - trx-client/main: wire vchan_destroyed_tx into audio client and frontend runtime context - trx-frontend-http/vchan: remove per-session one-channel limit in allocate(); replace auto-evict in release_session_on_rig() with subscriber-count-only update; add remove_by_uuid() for server- triggered OOB destruction (skips redundant VChanAudioCmd::Remove) - trx-frontend-http/server: spawn background task that forwards vchan_destroyed broadcast to ClientChannelManager.remove_by_uuid() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>