|
@@ -2,22 +2,22 @@
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
import audioop
|
|
|
+import contextlib
|
|
|
+import glob
|
|
|
import io
|
|
|
import os
|
|
|
+import subprocess
|
|
|
import syslog
|
|
|
import threading
|
|
|
import time
|
|
|
-import glob
|
|
|
-import subprocess
|
|
|
+import wave
|
|
|
+from datetime import datetime
|
|
|
|
|
|
import linphone
|
|
|
from enum import Enum
|
|
|
-from datetime import datetime
|
|
|
-
|
|
|
-import wave
|
|
|
-import contextlib
|
|
|
+import threading
|
|
|
|
|
|
-VOLUME_THRESHOLD = 50
|
|
|
+VOLUME_THRESHOLD = 100
|
|
|
|
|
|
|
|
|
class ConversationStatus(Enum):
|
|
@@ -26,12 +26,31 @@ class ConversationStatus(Enum):
|
|
|
WAITFORANSWER = 2
|
|
|
|
|
|
|
|
|
+class Conversation(object):
|
|
|
+ def __init__(self):
|
|
|
+ self._status = ConversationStatus.READY_TO_TALK
|
|
|
+
|
|
|
+ @property
|
|
|
+ def status(self):
|
|
|
+ return self._status
|
|
|
+
|
|
|
+ @status.setter
|
|
|
+ def status(self, value):
|
|
|
+ if value != self._status:
|
|
|
+ print(" New status : " + str(value))
|
|
|
+ self._status = value
|
|
|
+
|
|
|
+
|
|
|
current_dir = os.path.dirname(os.path.realpath(__file__))
|
|
|
-replies = glob.glob(current_dir + "/replies/*.wav")
|
|
|
+replies_seq = glob.glob(current_dir + "/replies/sequence/*.wav")
|
|
|
+replies_seq.sort()
|
|
|
+
|
|
|
+replies_generic = glob.glob(current_dir + "/replies/generic/*.wav")
|
|
|
+replies_generic.sort()
|
|
|
|
|
|
incoming_stream_file = "/tmp/lenny"
|
|
|
|
|
|
-conversation_status = ConversationStatus.READY_TO_TALK
|
|
|
+conversation = Conversation()
|
|
|
|
|
|
replies_pos = 0
|
|
|
|
|
@@ -50,30 +69,42 @@ def get_wav_duration(fname):
|
|
|
return frames / float(rate)
|
|
|
|
|
|
|
|
|
+def sleep(duration):
|
|
|
+ dummy_event = threading.Event()
|
|
|
+ dummy_event.wait(timeout=duration)
|
|
|
+
|
|
|
+
|
|
|
def say(core):
|
|
|
- global conversation_status
|
|
|
+ global conversation
|
|
|
global replies_pos
|
|
|
- if conversation_status is not ConversationStatus.IMTALKING:
|
|
|
- voice_filename = replies[replies_pos]
|
|
|
- replies_pos = (replies_pos + 1) % len(replies)
|
|
|
+ if conversation.status is not ConversationStatus.IMTALKING:
|
|
|
+ conversation.status = ConversationStatus.IMTALKING
|
|
|
+
|
|
|
+ # On joue les repliques en sequence, puis quand
|
|
|
+ # on arrive au bout, on en joue une au hasard
|
|
|
+ # du groupe 'generic'
|
|
|
+
|
|
|
+ voice_filename = replies_seq[replies_pos]
|
|
|
+ replies_pos = (replies_pos + 1) % len(replies_seq)
|
|
|
if replies_pos == 0:
|
|
|
# On ne rejoue jamais la première réplique "allo"
|
|
|
replies_pos = 1
|
|
|
|
|
|
- print("Saying : " + voice_filename)
|
|
|
- conversation_status = ConversationStatus.IMTALKING
|
|
|
-
|
|
|
duration = get_wav_duration(voice_filename)
|
|
|
+ print("Saying : " + voice_filename + "(duration : " + str(duration) + ")")
|
|
|
+
|
|
|
core.play_file = voice_filename
|
|
|
- time.sleep(duration)
|
|
|
+
|
|
|
+ sleep(duration)
|
|
|
core.play_file = ""
|
|
|
|
|
|
# On laisse l'autre l'occassion de reparler
|
|
|
- conversation_status = ConversationStatus.WAITFORANSWER
|
|
|
+ conversation.status = ConversationStatus.WAITFORANSWER
|
|
|
|
|
|
|
|
|
def call_state_changed(core, call, state, message):
|
|
|
- global conversation_status
|
|
|
+ global conversation
|
|
|
+ global replies_pos
|
|
|
log("state changed : " + message)
|
|
|
|
|
|
if state == linphone.CallState.Released:
|
|
@@ -84,21 +115,29 @@ def call_state_changed(core, call, state, message):
|
|
|
|
|
|
if state == linphone.CallState.IncomingReceived:
|
|
|
log("Incoming call : {}".format(call.remote_address.username))
|
|
|
- if call.remote_address.username == "**620":
|
|
|
- print(" .. from JF !")
|
|
|
+
|
|
|
+ replies_pos = 0
|
|
|
+
|
|
|
+ if call.remote_address.username == "**620" or call.remote_address.username == "0765757624":
|
|
|
+ print(" ... " + call.remote_address.username)
|
|
|
+
|
|
|
+ #if call.remote_address.username == "0227570500":
|
|
|
+ # print(" .. from Bernard !")
|
|
|
+
|
|
|
|
|
|
call_params = core.create_call_params(call)
|
|
|
- call_params.record_file = current_dir + "/out/call_"+datetime.now().strftime('%Y-%m-%d_%Hh%Mmn%Ss')+".wav"
|
|
|
+ call_params.record_file = current_dir + "/out/call_" + datetime.now().strftime(
|
|
|
+ '%Y-%m-%d_%Hh%Mmn%Ss') + ".wav"
|
|
|
|
|
|
# Let ring some time
|
|
|
- time.sleep(5)
|
|
|
+ sleep(5)
|
|
|
|
|
|
core.accept_call_with_params(call, call_params)
|
|
|
call.start_recording()
|
|
|
|
|
|
- time.sleep(2)
|
|
|
+ sleep(2)
|
|
|
|
|
|
- t = threading.Thread(target=incoming_stream_worker, args=[silence_call_bak, core, call])
|
|
|
+ t = threading.Thread(target=incoming_stream_worker, args=[core, call])
|
|
|
t.start()
|
|
|
|
|
|
say(core)
|
|
@@ -112,15 +151,8 @@ def registration_state_changed(core, call, state, message):
|
|
|
log("registration_state_changed: " + str(state) + ", " + message)
|
|
|
|
|
|
|
|
|
-def silence_call_bak(core, call):
|
|
|
- global conversation_status
|
|
|
- global replies_pos
|
|
|
- if conversation_status is not ConversationStatus.WAITFORANSWER:
|
|
|
- say(core)
|
|
|
-
|
|
|
-
|
|
|
-def incoming_stream_worker(sil_cb, core, call):
|
|
|
- global conversation_status
|
|
|
+def incoming_stream_worker(core, call):
|
|
|
+ global conversation
|
|
|
print("Worker is starting")
|
|
|
|
|
|
f = open(incoming_stream_file, "rb")
|
|
@@ -128,25 +160,37 @@ def incoming_stream_worker(sil_cb, core, call):
|
|
|
p = f.tell()
|
|
|
buf = ''
|
|
|
|
|
|
+ previous_status = conversation.status
|
|
|
+
|
|
|
while call.state is not linphone.CallState.End and not THREADS_MUST_QUIT:
|
|
|
- f.seek(p)
|
|
|
- buf += f.read(4096)
|
|
|
- p = f.tell()
|
|
|
+ if conversation.status is ConversationStatus.IMTALKING:
|
|
|
+ f.seek(0, io.SEEK_END)
|
|
|
+ p = f.tell()
|
|
|
+ else:
|
|
|
+
|
|
|
+ if previous_status != conversation.status:
|
|
|
+ f.seek(0, io.SEEK_END)
|
|
|
+ p = f.tell()
|
|
|
+
|
|
|
+ f.seek(p)
|
|
|
+ buf += f.read(4096)
|
|
|
+ p = f.tell()
|
|
|
+
|
|
|
+ if len(buf) >= 20000:
|
|
|
+ volume = audioop.rms(buf, 2)
|
|
|
+ print("Detected volume : " + str(volume))
|
|
|
+ #print("State : " + str(conversation.status))
|
|
|
+ buf = ''
|
|
|
+ if volume < VOLUME_THRESHOLD:
|
|
|
+ if conversation.status is ConversationStatus.READY_TO_TALK:
|
|
|
+ threading.Thread(target=say, args=[core]).start()
|
|
|
+ else:
|
|
|
+ conversation.status = ConversationStatus.READY_TO_TALK
|
|
|
|
|
|
# We must sleep a bit to avoid cpu hog
|
|
|
- time.sleep(0.01)
|
|
|
-
|
|
|
- if len(buf) >= 20000:
|
|
|
- volume = audioop.rms(buf, 2)
|
|
|
- # print("Detected volume : " + str(volume))
|
|
|
- # print("State : " + str(conversation_status))
|
|
|
- buf = ''
|
|
|
- if volume < VOLUME_THRESHOLD:
|
|
|
- if conversation_status is not ConversationStatus.IMTALKING:
|
|
|
- t = threading.Thread(target=sil_cb, args=[core, call])
|
|
|
- t.start()
|
|
|
- else:
|
|
|
- conversation_status = ConversationStatus.READY_TO_TALK
|
|
|
+ sleep(0.01)
|
|
|
+ previous_status = conversation.status
|
|
|
+
|
|
|
|
|
|
print("Worker is quitting")
|
|
|
|
|
@@ -181,7 +225,7 @@ def main():
|
|
|
core.add_auth_info(auth_info)
|
|
|
|
|
|
while True:
|
|
|
- time.sleep(0.03)
|
|
|
+ sleep(0.03)
|
|
|
core.iterate()
|
|
|
|
|
|
log("callblocker quitting.")
|
|
@@ -206,16 +250,15 @@ if __name__ == "__main__":
|
|
|
# qui est allé à l'Université. Et elle l'a terminé avec mention, nous en sommes très fière.
|
|
|
# et du coup elle m'a dit que je devrais jeter un oeil à ce dont vous me parlez.
|
|
|
# - Hmm, désolé, j'ai pas tout à fait compris, vous pouvez répéter ?
|
|
|
-# - Could you say that again please ?
|
|
|
# - Heu, oui, vous pouvez me rappeler de la part de quelle entreprise vous appelez
|
|
|
# - Oui, en fait y'a une chose ... heuu, car j'avais eu un appel comme le votre, j'ai eu pas mal
|
|
|
# de problème avec le personnel ici, qui m'on fait la morale, car je me suis retrouvé avec des affaires
|
|
|
# dont je n'avais pas besoin, et ma nièce justement m'a fait la morale également ... vous savez ce que c'est
|
|
|
# la famille ....
|
|
|
-#
|
|
|
+# - Could you say that again please ?
|
|
|
|
|
|
# Idées :
|
|
|
# - En tout cas vous me semblez une personne fort sympathique, c'est toujours agréable de discute
|
|
|
# des personnes sympathique, quand on est une personne seule comme moi ... heuu, en fait on parlait
|
|
|
# de quoi déjà ?
|
|
|
-
|
|
|
+# - Bon,
|