Add Left Only / Right Only channel modes#230
Conversation
|
Not confident this will pass either - I'll review and update. Edit: lol I missed the checks, nvm. |
Adds a runtime-settable channel routing mode (Stereo / Left Only / Right Only) that duplicates one input channel to both outputs before DSP processing. Persisted to NVS and exposed in the web UI as a dropdown. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
911a7ac to
54ed879
Compare
|
I think you can simply set i2s Or remove every second sample (left or right) to generate a mono stream and set |
Probably the preferable solution. |
|
For my case, my DAC is set to (L+R)/2, so wouldn't that make my output half volume? |
|
If I understand the linked i2s docu correctly it takes one date sample (even or odd depends on the selected channel) and repeats it so it is played on both channels. The other data sample is skipped. So in the end it should be identical to your implementation. |
Instead of duplicating L/R samples in software on every audio chunk, use the I2S hardware's slot_mask to route the selected channel to both outputs, eliminating the per-chunk sample manipulation loop. The inactive slot duplicates the active one natively (confirmed via esp-idf HAL source). Channel mode state moves from dsp_processor to player, where it can be applied directly to the I2S peripheral via i2s_channel_reconfig_std_slot(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
(I need to test again) |
|
Do we really need to make that two components depend on one another? @luar123 what do you think about that? Couldn't we just implement all in player? This would mean dependency of lightsnapcast for ui http though? Not sure which is better. Is there a third option? |
|
This is a setting that does not need to change during operation, right? I think that is the easiest solution. Of course you could also add a function to set only this parameter. Then you could call it from http_get_task during restart (pausing the player would be the easiest way to apply new settings without full reset), but that might be over complicated. |
|
Great thinking, this was my feeling too. Add API which let's us control this through |
Settings are loaded in main(), aren't they? So apply this from main during boot (by passing a parameter to init_player). If settings change, simply press the reboot button in the UI. Esp32 is booting fast so this is OK |
Channel mode is now passed as a parameter to init_player() rather than being applied at runtime via player_set_channel_mode(). main() loads the stored value from NVS before calling init_snapclient(), which threads it through to init_player(). A reboot applies any UI change, which the owner confirmed is acceptable. Removes player_get/set_channel_mode() API and the lightsnapcast build dependency from dsp_processor_settings. dsp_processor_settings retains a local s_channel_mode cache for correct JSON serialisation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
That sounds fine to me. Assuming we prefer not to make things runtime settable for the sake of simplicity? |
Channel mode now takes effect on reboot; show a disabled restart button that enables as soon as the user changes the dropdown, and add a brief note explaining the reboot requirement. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Since those things won't be changed very often rebooting should be OK don't you think? |
Channel routing (slot_mask) is an I2S hardware concern, not a DSP processing parameter. Remove it from dsp_processor_settings entirely: - Drop dsp_channel_mode_t from dsp_types.h; define it in player.h - Remove save/load/json/cache from dsp_processor_settings - Add settings_get/set_channel_mode (int32_t) to settings_manager, persisted in the existing 'snapclient' NVS namespace - ui_http_server routes channel_mode saves to settings_manager and injects the value into the DSP capabilities response for the UI - main() reads channel_mode from settings_manager and passes it to init_player via init_snapclient Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Channel mode is a hardware/boot setting, not a DSP parameter. Move it from the DSP settings page to the general settings page alongside other boot-time settings. The dropdown saves immediately via setParameter and enables a restart button to apply the change. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…m channel mode refactor
…SP JSON channel_mode is already included in the general settings endpoint via settings_manager, so there is no need to parse and reserialize the DSP JSON to inject it. Removes the cJSON dependency from ui_http_server. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Ope, I missed this:
So I would need to implement |
|
Did you try if your current implementation works? According to the documentation setting slot_mode=stereo and slot_mask=left/right should work. There are more options, but this should be the easiest. |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
settings_get_channel_mode returns ESP_ERR_INVALID_STATE when the mutex hasn't been created yet, leaving channel_mode silently at 0 (stereo). Move settings_manager_init before init_snapclient so the NVS read works. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Ah, my settings weren't applying in the right order. Pushed my latest which uses |
- Remove spurious dsp_processor REQUIRES from lightsnapcast — nothing in player.c/player.h uses it, and it created a build-breaking cycle since dsp_processor already PRIV_REQUIRES lightsnapcast - Reject out-of-range values in settings_set_channel_mode before writing to NVS, preventing a crafted HTTP request from permanently corrupting the stored mode - Clamp and warn on invalid channel_mode_raw read from NVS before casting to dsp_channel_mode_t Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hm, it seems to be 1/2 volume when I use Left/Right mode vs Stereo. |
|
See #235 - it touches a lot, but seems to work fine. |
|
Just tried it with only hard coding left channel: Works as expected: used stereo dac and played a left/right stereo speaker test. Left channel was played to both sides, right channel not at all. |
|
Do you find volume is cut in half? |
|
I would say no but hard to tell without measuring. My dac is not mixing anything. So from dac point of view it is just stereo. |

Wanted a way to be able to use two independent speakers as a stereo pair.
Adds a runtime-settable channel routing mode (Stereo / Left Only / Right Only) that duplicates one input channel to both outputs before DSP processing. Persisted to NVS and exposed in the web UI as a dropdown.