feat: add 4 new voice effects (echo, robot, chorus, tremolo)
- Removed MAX_ACTIVE_EFFECTS limit (effects unlimited) - Added echo effect (0-100%): spatial delay/reverb - Added robot effect (0-100%): ring modulation voice - Added chorus effect (0-100%): multiple voices effect - Added tremolo depth (0.0-1.0) and rate (0.0-10.0 Hz): amplitude modulation - Effects apply in order: pitch → speed → echo → chorus → tremolo → robot - Updated /effects command with all 7 effect choices - Updated /effects list to display all 7 effects with emojis - Updated warning system: warns when > 2 active effects - Added validation and formatting for all new effects - Updated voice_manager.py to handle all 7 effect storage/loading Note: Cancel button for processing >10s not yet implemented Note: Queue system needs updating to handle all effect parameters
This commit is contained in:
@@ -201,9 +201,20 @@ class VoiceManager:
|
||||
# Convert to proper types (JSON stores them as strings)
|
||||
pitch = effects.get("pitch", AudioEffects.PITCH_DEFAULT)
|
||||
speed = effects.get("speed", AudioEffects.SPEED_DEFAULT)
|
||||
echo = effects.get("echo", AudioEffects.ECHO_DEFAULT)
|
||||
robot = effects.get("robot", AudioEffects.ROBOT_DEFAULT)
|
||||
chorus = effects.get("chorus", AudioEffects.CHORUS_DEFAULT)
|
||||
tremolo_depth = effects.get("tremolo_depth", AudioEffects.TREMOLO_DEPTH_DEFAULT)
|
||||
tremolo_rate = effects.get("tremolo_rate", AudioEffects.TREMOLO_RATE_DEFAULT)
|
||||
|
||||
return {
|
||||
"pitch": int(pitch) if pitch is not None else AudioEffects.PITCH_DEFAULT,
|
||||
"speed": float(speed) if speed is not None else AudioEffects.SPEED_DEFAULT,
|
||||
"echo": int(echo) if echo is not None else AudioEffects.ECHO_DEFAULT,
|
||||
"robot": int(robot) if robot is not None else AudioEffects.ROBOT_DEFAULT,
|
||||
"chorus": int(chorus) if chorus is not None else AudioEffects.CHORUS_DEFAULT,
|
||||
"tremolo_depth": float(tremolo_depth) if tremolo_depth is not None else AudioEffects.TREMOLO_DEPTH_DEFAULT,
|
||||
"tremolo_rate": float(tremolo_rate) if tremolo_rate is not None else AudioEffects.TREMOLO_RATE_DEFAULT,
|
||||
}
|
||||
|
||||
def set_user_effect(self, user_id: int, effect_name: str, value: Any) -> tuple[bool, str]:
|
||||
@@ -222,24 +233,37 @@ class VoiceManager:
|
||||
if user_id not in self._user_effects:
|
||||
self._user_effects[user_id] = {}
|
||||
|
||||
# Check if this would exceed max effects
|
||||
# Save the effect
|
||||
current_effects = self._user_effects[user_id].copy()
|
||||
if effect_name == "pitch":
|
||||
current_effects["pitch"] = int(value)
|
||||
elif effect_name == "speed":
|
||||
current_effects["speed"] = float(value)
|
||||
elif effect_name == "echo":
|
||||
current_effects["echo"] = int(value)
|
||||
elif effect_name == "robot":
|
||||
current_effects["robot"] = int(value)
|
||||
elif effect_name == "chorus":
|
||||
current_effects["chorus"] = int(value)
|
||||
elif effect_name == "tremolo_depth":
|
||||
current_effects["tremolo_depth"] = float(value)
|
||||
elif effect_name == "tremolo_rate":
|
||||
current_effects["tremolo_rate"] = float(value)
|
||||
|
||||
# Count active effects and show warning if > 2
|
||||
active_count = AudioEffects.count_active_effects(
|
||||
current_effects.get("pitch", AudioEffects.PITCH_DEFAULT),
|
||||
current_effects.get("speed", AudioEffects.SPEED_DEFAULT),
|
||||
pitch=current_effects.get("pitch", AudioEffects.PITCH_DEFAULT),
|
||||
speed=current_effects.get("speed", AudioEffects.SPEED_DEFAULT),
|
||||
echo=current_effects.get("echo", AudioEffects.ECHO_DEFAULT),
|
||||
robot=current_effects.get("robot", AudioEffects.ROBOT_DEFAULT),
|
||||
chorus=current_effects.get("chorus", AudioEffects.CHORUS_DEFAULT),
|
||||
tremolo_depth=current_effects.get("tremolo_depth", AudioEffects.TREMOLO_DEPTH_DEFAULT),
|
||||
)
|
||||
|
||||
# Save the effect
|
||||
self._user_effects[user_id][effect_name] = value
|
||||
self._save_preferences()
|
||||
|
||||
if active_count >= AudioEffects.MAX_ACTIVE_EFFECTS:
|
||||
return True, f"Effect applied! ⚠️ You now have {active_count} active effects (max {AudioEffects.MAX_ACTIVE_EFFECTS}). More effects = slower processing."
|
||||
if active_count > 2:
|
||||
return True, f"Effect applied! ⚠️ You have {active_count} active effects. Performance may be slower with more effects."
|
||||
else:
|
||||
return True, "Effect applied successfully!"
|
||||
|
||||
@@ -252,7 +276,14 @@ class VoiceManager:
|
||||
def count_active_effects(self, user_id: int) -> int:
|
||||
"""Count how many effects are active for a user."""
|
||||
effects = self.get_user_effects(user_id)
|
||||
return AudioEffects.count_active_effects(effects["pitch"], effects["speed"])
|
||||
return AudioEffects.count_active_effects(
|
||||
pitch=effects["pitch"],
|
||||
speed=effects["speed"],
|
||||
echo=effects["echo"],
|
||||
robot=effects["robot"],
|
||||
chorus=effects["chorus"],
|
||||
tremolo_depth=effects["tremolo_depth"],
|
||||
)
|
||||
|
||||
def _load_preferences(self) -> None:
|
||||
"""Load user voice preferences from JSON file."""
|
||||
|
||||
Reference in New Issue
Block a user