refactor: simplify audition to single-bot playback
derp now handles both listening and speaking, so audition no longer needs cross-bot lookup or dual-play through merlin. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -565,27 +565,13 @@ async def cmd_audition(bot, message):
|
|||||||
f"{_deep},{_bass},{_echo_chamber}"),
|
f"{_deep},{_bass},{_echo_chamber}"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Find merlin (the listener bot) -- plays the audition samples
|
|
||||||
merlin = None
|
|
||||||
for peer in getattr(bot.registry, "_bots", {}).values():
|
|
||||||
if getattr(peer, "_receive_sound", False):
|
|
||||||
merlin = peer
|
|
||||||
break
|
|
||||||
|
|
||||||
await bot.reply(message, f"Auditioning {len(samples)} voice samples...")
|
await bot.reply(message, f"Auditioning {len(samples)} voice samples...")
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Pre-generate derp's default voice (same phrase, no FX)
|
|
||||||
derp_wav = await loop.run_in_executor(
|
|
||||||
None, lambda: _fetch_tts_voice(piper_url, phrase),
|
|
||||||
)
|
|
||||||
|
|
||||||
for i, (label, voice, sid, fx) in enumerate(samples, 1):
|
for i, (label, voice, sid, fx) in enumerate(samples, 1):
|
||||||
announcer = merlin or bot
|
await bot.send("0", f"[{i}/{len(samples)}] {label}")
|
||||||
await announcer.send("0", f"[{i}/{len(samples)}] {label}")
|
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
# Generate the audition sample (merlin's candidate voice)
|
|
||||||
sample_wav = await loop.run_in_executor(
|
sample_wav = await loop.run_in_executor(
|
||||||
None, lambda v=voice, s=sid, f=fx: _fetch_tts_voice(
|
None, lambda v=voice, s=sid, f=fx: _fetch_tts_voice(
|
||||||
piper_url, phrase, voice=v, speaker_id=s,
|
piper_url, phrase, voice=v, speaker_id=s,
|
||||||
@@ -596,30 +582,14 @@ async def cmd_audition(bot, message):
|
|||||||
await bot.send("0", " (failed)")
|
await bot.send("0", " (failed)")
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
# Both bots speak simultaneously:
|
done = asyncio.Event()
|
||||||
# merlin plays the audition sample, derp plays its default voice
|
await bot.stream_audio(sample_wav, volume=1.0, on_done=done)
|
||||||
merlin_done = asyncio.Event()
|
await done.wait()
|
||||||
derp_done = asyncio.Event()
|
|
||||||
if merlin:
|
|
||||||
merlin_task = asyncio.create_task(
|
|
||||||
merlin.stream_audio(sample_wav, volume=1.0,
|
|
||||||
on_done=merlin_done))
|
|
||||||
derp_task = asyncio.create_task(
|
|
||||||
bot.stream_audio(derp_wav, volume=1.0,
|
|
||||||
on_done=derp_done))
|
|
||||||
await asyncio.gather(merlin_task, derp_task)
|
|
||||||
else:
|
|
||||||
await bot.stream_audio(sample_wav, volume=1.0,
|
|
||||||
on_done=merlin_done)
|
|
||||||
await merlin_done.wait()
|
|
||||||
finally:
|
finally:
|
||||||
Path(sample_wav).unlink(missing_ok=True)
|
Path(sample_wav).unlink(missing_ok=True)
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(2)
|
||||||
|
|
||||||
if derp_wav:
|
await bot.send("0", "Audition complete.")
|
||||||
Path(derp_wav).unlink(missing_ok=True)
|
|
||||||
announcer = merlin or bot
|
|
||||||
await announcer.send("0", "Audition complete.")
|
|
||||||
|
|
||||||
|
|
||||||
# -- Plugin lifecycle --------------------------------------------------------
|
# -- Plugin lifecycle --------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user