Skip to content
This repository has been archived by the owner on Jun 28, 2024. It is now read-only.

Commit

Permalink
add ducking feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
TerryGeng committed Feb 8, 2020
1 parent ce2dae9 commit c5fa90b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
4 changes: 4 additions & 0 deletions configuration.default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ max_track_playlist = 20
# Maximum music duration (minutes)
max_track_duration = 60
# If ducking is enabled, the bot will automatically attenuate its volume when someone is talking.
ducking = False
ducking_volume = 0.05
[webinterface]
enabled = False
is_web_proxified = True
Expand Down
8 changes: 4 additions & 4 deletions interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ def post():
elif action == "clear":
var.botamusique.stop()
elif action == "volume_up":
if var.botamusique.volume + 0.03 < 1.0:
var.botamusique.volume = var.botamusique.volume + 0.03
if var.botamusique.volume_set + 0.03 < 1.0:
var.botamusique.volume_set = var.botamusique.volume_set + 0.03
else:
var.botamusique.volume = 1.0
logging.info("web: volume up to %d" % (var.botamusique.volume * 100))
var.botamusique.volume_set = 1.0
logging.info("web: volume up to %d" % (var.botamusique.volume_set * 100))
elif action == "volume_down":
if var.botamusique.volume - 0.03 > 0:
var.botamusique.volume = var.botamusique.volume - 0.03
Expand Down
46 changes: 38 additions & 8 deletions mumbleBot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import threading
import time
import sys
import math
import signal
import configparser
import audioop
Expand Down Expand Up @@ -67,9 +68,11 @@
class MumbleBot:
def __init__(self, args):
signal.signal(signal.SIGINT, self.ctrl_caught)
self.volume = var.config.getfloat('bot', 'volume')
self.volume_set = var.config.getfloat('bot', 'volume')
if db.has_option('bot', 'volume'):
self.volume = var.db.getfloat('bot', 'volume')
self.volume_set = var.db.getfloat('bot', 'volume')

self.volume = self.volume_set

self.channel = args.channel

Expand Down Expand Up @@ -116,6 +119,7 @@ def __init__(self, args):
tt.daemon = True
tt.start()


if args.host:
host = args.host
else:
Expand Down Expand Up @@ -160,6 +164,14 @@ def __init__(self, args):
self.mumble.channels.find_by_name(self.channel).move_in()
self.mumble.set_bandwidth(200000)

self.is_ducking = False
self.on_ducking = False
if var.config.getboolean("bot", "ducking"):
self.is_ducking = True
self.ducking_volume = var.config.getfloat("bot", "ducking_volume")
self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_SOUNDRECEIVED, self.ducking_sound_received)
self.mumble.set_receive_sound(True)

# Set the CTRL+C shortcut
def ctrl_caught(self, signal, frame):
logging.info(
Expand All @@ -173,7 +185,6 @@ def ctrl_caught(self, signal, frame):

# All text send to the chat is analysed by this function
def message_received(self, text):

message = text.message.strip()
user = self.mumble.users[text.actor]['name']

Expand Down Expand Up @@ -506,14 +517,14 @@ def message_received(self, text):
elif command == var.config.get('command', 'volume'):
# The volume is a percentage
if parameter is not None and parameter.isdigit() and 0 <= int(parameter) <= 100:
self.volume = float(float(parameter) / 100)
self.volume_set = float(float(parameter) / 100)
self.send_msg(var.config.get('strings', 'change_volume') % (
int(self.volume * 100), self.mumble.users[text.actor]['name']), text)
var.db.set('bot', 'volume', str(self.volume))
logging.info('bot: volume set to %d' % (self.volume * 100))
int(self.volume_set * 100), self.mumble.users[text.actor]['name']), text)
var.db.set('bot', 'volume', str(self.volume_set))
logging.info('bot: volume set to %d' % (self.volume_set * 100))
else:
self.send_msg(var.config.get(
'strings', 'current_volume') % int(self.volume * 100), text)
'strings', 'current_volume') % int(self.volume_set * 100), text)

elif command == var.config.get('command', 'current_music'):
if len(var.playlist.playlist) > 0:
Expand Down Expand Up @@ -710,6 +721,7 @@ def launch_music(self, index=-1):
self.thread = sp.Popen(command, stdout=sp.PIPE, bufsize=480)
self.is_playing = True
self.is_pause = False
self.last_volume_cycle_time = time.time()

def download_music(self, index=-1):
if index == -1:
Expand Down Expand Up @@ -856,6 +868,23 @@ def async_download_next(self):
th.daemon = True
th.start()

def volume_cycle(self):
delta = time.time() - self.last_volume_cycle_time

if delta > 0.001:
if self.is_ducking and self.on_ducking:
self.volume = (self.volume - self.ducking_volume) * math.exp(- delta / 0.2) + self.ducking_volume
if self.ducking_release > time.time():
self.on_ducking = False
else:
self.volume = self.volume_set - (self.volume_set - self.volume) * math.exp(- delta / 0.5)

self.last_volume_cycle_time = time.time()

def ducking_sound_received(self, user, sound):
self.on_ducking = True
self.ducking_release = time.time() + 1 # ducking release after 0.5s

@staticmethod
# Parse the html from the message to get the URL
def get_url_from_input(string):
Expand All @@ -881,6 +910,7 @@ def loop(self):
raw_music = self.thread.stdout.read(480)
if raw_music:
# Adjust the volume and send it to mumble
self.volume_cycle()
self.mumble.sound_output.add_sound(
audioop.mul(raw_music, 2, self.volume))
else:
Expand Down

0 comments on commit c5fa90b

Please sign in to comment.