Skip to content

Commit f5dd012

Browse files
ThaendrilTheandrilShackless
authored
Add gain boosted sound effect variants for Azure with streaming. (#185)
* Files modified to compensate for Azure_TTS issues. Every thing that has a pedalboard issue will now have two variations one _Gain_Boost One _Normal Gain Boost will have boosted gain that needs to be tied with the output streaming issue : Basically the Gain Boost option should automatically turn output streaming to enabled as this option is intended to solve the very quiet issue azure TTS / Wingman Pro cause. This effectively boosts gain upwards to 3800%. The normal one should force output streaming to disabled, as if output streaming stays on with the boosted gain.. well if you wear headphones it wont be the most pleasant experience ever. This impacts Low_Quality_Radio, Medium_Quality_Radio, High_End_Radio only. As these have the effect boards on them which seems to be the issue. Also once this is pushed up, the 'Beep' effect needs to be double checked to make sure its playing the apollo_beep as currently I think its playing the old beep. * use gain boosted variants for Azure with streaming * convert to 44khz mono wav * implement Apollo Beep as separate effect --------- Co-authored-by: Theandril <michaelsizemore90@gmail.com> Co-authored-by: Simon Hopstätter <simon.hopstaetter@shipbit.de>
1 parent 77862fc commit f5dd012

9 files changed

Lines changed: 78 additions & 15 deletions

File tree

api/interface.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,10 @@ class WingmanProSettings(BaseModel):
316316

317317
class SoundConfig(BaseModel):
318318
play_beep: bool
319-
"""adds a beep/Quindar sound before and after the wingman talks"""
319+
"""adds a Beep/Quindar sound before and after the wingman talks"""
320+
321+
play_beep_apollo: bool
322+
"""adds a Apollo Beep sound before and after the wingman talks"""
320323

321324
effects: list[SoundEffect]
322325
"""You can put as many sound effects here as you want. They stack and are added in the defined order here."""

audio_samples/Apollo_Beep.wav

-375 KB
Binary file not shown.

providers/elevenlabs.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,22 @@ async def play_audio(
5252

5353
def notify_playback_finished():
5454
audio_player.playback_events.unsubscribe("finished", playback_finished)
55+
5556
if sound_config.play_beep:
56-
audio_player.play_beep()
57+
audio_player.play_wav("beep.wav")
58+
elif sound_config.play_beep_apollo:
59+
audio_player.play_wav("Apollo_Beep.wav")
60+
5761
WebSocketUser.ensure_async(
5862
audio_player.notify_playback_finished(wingman_name)
5963
)
6064

6165
def notify_playback_started():
6266
if sound_config.play_beep:
63-
audio_player.play_beep()
67+
audio_player.play_wav("beep.wav")
68+
elif sound_config.play_beep_apollo:
69+
audio_player.play_wav("Apollo_Beep.wav")
70+
6471
WebSocketUser.ensure_async(
6572
audio_player.notify_playback_started(wingman_name)
6673
)

providers/open_ai.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ def buffer_callback(audio_buffer):
285285
buffer_callback,
286286
sound_config,
287287
wingman_name=wingman_name,
288+
use_gain_boost=True, # "Azure Streaming" low gain workaround
288289
)
289290
else:
290291
await audio_player.play_with_effects(

providers/wingman_pro.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ def buffer_callback(audio_buffer):
178178
buffer_callback=buffer_callback,
179179
config=sound_config,
180180
wingman_name=wingman_name,
181+
use_gain_boost=True, # "Azure Streaming" low gain workaround
181182
)
182183
else: # non-streaming
183184
response = requests.post(

services/audio_player.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ async def play_with_effects(
9191
audio = sound_effect(audio, sample_rate)
9292

9393
if config.play_beep:
94-
audio = self._add_beep_effect(audio, sample_rate)
94+
audio = self._add_wav_effect(audio, sample_rate, "beep.wav")
95+
elif config.play_beep_apollo:
96+
audio = self._add_wav_effect(audio, sample_rate, "Apollo_Beep.wav")
9597

9698
channels = audio.shape[1] if audio.ndim > 1 else 1
9799

@@ -127,10 +129,10 @@ async def notify_playback_finished(self, wingman_name: str):
127129
if callable(self.on_playback_finished):
128130
await self.on_playback_finished(wingman_name)
129131

130-
def play_beep(self):
132+
def play_wav(self, audio_sample_file: str):
131133
bundle_dir = path.abspath(path.dirname(__file__))
132134
beep_audio, beep_sample_rate = self.get_audio_from_file(
133-
path.join(bundle_dir, "../audio_samples/beep.wav")
135+
path.join(bundle_dir, f"../audio_samples/{audio_sample_file}")
134136
)
135137
self.start_playback(beep_audio, beep_sample_rate, 1, None)
136138

@@ -142,10 +144,12 @@ def _get_audio_from_stream(self, stream: bytes) -> tuple:
142144
audio, sample_rate = sf.read(io.BytesIO(stream), dtype="float32")
143145
return audio, sample_rate
144146

145-
def _add_beep_effect(self, audio: np.ndarray, sample_rate: int) -> np.ndarray:
147+
def _add_wav_effect(
148+
self, audio: np.ndarray, sample_rate: int, audio_sample_file: str
149+
) -> np.ndarray:
146150
bundle_dir = path.abspath(path.dirname(__file__))
147151
beep_audio, beep_sample_rate = self.get_audio_from_file(
148-
path.join(bundle_dir, "../audio_samples/beep.wav")
152+
path.join(bundle_dir, f"../audio_samples/{audio_sample_file}")
149153
)
150154

151155
# Resample the beep sound if necessary to match the sample rate of 'audio'
@@ -179,6 +183,7 @@ async def stream_with_effects(
179183
sample_rate=16000,
180184
channels=1,
181185
dtype="int16",
186+
use_gain_boost=False,
182187
):
183188
buffer = bytearray()
184189
stream_finished = False
@@ -206,10 +211,15 @@ def callback(outdata, frames, time, status):
206211
await self.notify_playback_started(wingman_name)
207212

208213
if config.play_beep:
209-
self.play_beep()
214+
self.play_wav("beep.wav")
215+
elif config.play_beep_apollo:
216+
self.play_wav("Apollo_Beep.wav")
217+
210218
self.raw_stream.start()
211219

212-
sound_effects = get_sound_effects(config)
220+
sound_effects = get_sound_effects(
221+
config=config, use_gain_boost=use_gain_boost
222+
)
213223
audio_buffer = bytearray(buffer_size)
214224
filled_size = buffer_callback(audio_buffer)
215225
while filled_size > 0:
@@ -234,6 +244,9 @@ def callback(outdata, frames, time, status):
234244
sd.sleep(100)
235245

236246
if config.play_beep:
237-
self.play_beep()
247+
self.play_wav("beep.wav")
248+
elif config.play_beep_apollo:
249+
self.play_wav("Apollo_Beep.wav")
250+
238251
self.is_playing = False
239252
await self.notify_playback_finished(wingman_name)

services/sound_effects.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
Gain,
1111
Bitcrush,
1212
Compressor,
13-
PitchShift,
1413
Distortion,
1514
)
1615
from api.interface import SoundConfig
@@ -45,7 +44,7 @@ class SoundEffects(Enum):
4544
LowpassFilter(cutoff_frequency_hz=3400),
4645
Resample(target_sample_rate=8000), # Lower resample rate for tinny effect
4746
Reverb(room_size=0.1, damping=0.3, wet_level=0.1, dry_level=0.9),
48-
Gain(gain_db=-10),
47+
Gain(gain_db=-17),
4948
]
5049
)
5150
MEDIUM_QUALITY_RADIO = Pedalboard(
@@ -56,6 +55,7 @@ class SoundEffects(Enum):
5655
Resample(target_sample_rate=16000),
5756
Reverb(room_size=0.01, damping=0.3, wet_level=0.1, dry_level=0.9),
5857
Compressor(threshold_db=-18, ratio=4),
58+
Gain(gain_db=4),
5959
]
6060
)
6161
HIGH_END_RADIO = Pedalboard(
@@ -65,6 +65,38 @@ class SoundEffects(Enum):
6565
Compressor(threshold_db=-10, ratio=2),
6666
Reverb(room_size=0.001, damping=0.3, wet_level=0.1, dry_level=0.9),
6767
Resample(target_sample_rate=44100),
68+
Gain(gain_db=2),
69+
]
70+
)
71+
LOW_QUALITY_RADIO_GAIN_BOOST = Pedalboard(
72+
[
73+
Distortion(drive_db=30),
74+
HighpassFilter(cutoff_frequency_hz=800),
75+
LowpassFilter(cutoff_frequency_hz=3400),
76+
Resample(target_sample_rate=8000), # Lower resample rate for tinny effect
77+
Reverb(room_size=0.1, damping=0.3, wet_level=0.1, dry_level=0.9),
78+
Gain(gain_db=70),
79+
]
80+
)
81+
MEDIUM_QUALITY_RADIO_GAIN_BOOST = Pedalboard(
82+
[
83+
Distortion(drive_db=15),
84+
HighpassFilter(cutoff_frequency_hz=300),
85+
LowpassFilter(cutoff_frequency_hz=5000),
86+
Resample(target_sample_rate=16000),
87+
Reverb(room_size=0.01, damping=0.3, wet_level=0.1, dry_level=0.9),
88+
Compressor(threshold_db=-18, ratio=4),
89+
Gain(gain_db=82),
90+
]
91+
)
92+
HIGH_END_RADIO_GAIN_BOOST = Pedalboard(
93+
[
94+
HighpassFilter(cutoff_frequency_hz=100),
95+
LowpassFilter(cutoff_frequency_hz=8000), # Adjust cutoff to avoid conflicts
96+
Compressor(threshold_db=-10, ratio=2),
97+
Reverb(room_size=0.001, damping=0.3, wet_level=0.1, dry_level=0.9),
98+
Resample(target_sample_rate=44100),
99+
Gain(gain_db=30),
68100
]
69101
)
70102

@@ -103,7 +135,7 @@ class SoundEffects(Enum):
103135
)
104136

105137

106-
def get_sound_effects(config: SoundConfig):
138+
def get_sound_effects(config: SoundConfig, use_gain_boost: bool = False):
107139
if config is None or not config.effects or len(config.effects) == 0:
108140
return []
109141

@@ -114,13 +146,18 @@ def get_sound_effects(config: SoundConfig):
114146
"LOW_QUALITY_RADIO": SoundEffects.LOW_QUALITY_RADIO.value,
115147
"MEDIUM_QUALITY_RADIO": SoundEffects.MEDIUM_QUALITY_RADIO.value,
116148
"HIGH_END_RADIO": SoundEffects.HIGH_END_RADIO.value,
149+
"LOW_QUALITY_RADIO_GAIN_BOOST": SoundEffects.LOW_QUALITY_RADIO_GAIN_BOOST.value,
150+
"MEDIUM_QUALITY_RADIO_GAIN_BOOST": SoundEffects.MEDIUM_QUALITY_RADIO_GAIN_BOOST.value,
151+
"HIGH_END_RADIO_GAIN_BOOST": SoundEffects.HIGH_END_RADIO_GAIN_BOOST.value,
117152
"INTERIOR_SMALL": SoundEffects.INTERIOR_SMALL.value,
118153
"INTERIOR_MEDIUM": SoundEffects.INTERIOR_MEDIUM.value,
119154
"INTERIOR_LARGE": SoundEffects.INTERIOR_LARGE.value,
120155
}
121156

122157
for effect in config.effects:
123158
effect_name = effect.value
159+
if use_gain_boost and f"{effect_name}_GAIN_BOOST" in mapping:
160+
effect_name += "_GAIN_BOOST"
124161
effect = mapping.get(effect_name)
125162
if effect:
126163
sound_effects.append(effect)

templates/configs/_Star Citizen/ATC.template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ prompts:
3030
record_key: delete
3131
sound:
3232
effects: [AI]
33-
play_beep: True
33+
play_beep_apollo: true
3434
openai:
3535
tts_voice: onyx
3636
commands:

templates/configs/defaults.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ features:
4747
sound:
4848
effects: []
4949
play_beep: false
50+
play_beep_apollo: false
5051
openai:
5152
conversation_model: gpt-4o
5253
summarize_model: gpt-4o

0 commit comments

Comments
 (0)