Change for working version
This commit is contained in:
parent
90b63b24d2
commit
b8b912a10a
3 changed files with 76 additions and 73 deletions
|
@ -12,4 +12,4 @@ voice:
|
||||||
input_volume: 100
|
input_volume: 100
|
||||||
output_volume: 30
|
output_volume: 30
|
||||||
file_address: "http://hugveycmd.local:8888"
|
file_address: "http://hugveycmd.local:8888"
|
||||||
output_driver: pulseaudio
|
output_driver: null
|
||||||
|
|
|
@ -40,8 +40,8 @@ class Utterance(object):
|
||||||
|
|
||||||
def isFinished(self):
|
def isFinished(self):
|
||||||
return self.endTime is not None
|
return self.endTime is not None
|
||||||
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get utterance {self}')
|
# print(f'get utterance {self}')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
@ -68,7 +68,7 @@ class Message(object):
|
||||||
self.parseForVariables()
|
self.parseForVariables()
|
||||||
self.uuid = None # Have a unique id each time the message is played back.
|
self.uuid = None # Have a unique id each time the message is played back.
|
||||||
self.color = None
|
self.color = None
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# Copy the object's state from self.__dict__ which contains
|
# Copy the object's state from self.__dict__ which contains
|
||||||
# all our instance attributes. Always use the dict.copy()
|
# all our instance attributes. Always use the dict.copy()
|
||||||
|
@ -78,7 +78,7 @@ class Message(object):
|
||||||
# Remove the unpicklable entries.
|
# Remove the unpicklable entries.
|
||||||
del state['filenameFetchLock']
|
del state['filenameFetchLock']
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
self.filenameFetchLock = asyncio.Lock()
|
self.filenameFetchLock = asyncio.Lock()
|
||||||
|
@ -103,9 +103,9 @@ class Message(object):
|
||||||
if not 'vol' in msg.params:
|
if not 'vol' in msg.params:
|
||||||
# prevent clipping on some Lyrebird tracks
|
# prevent clipping on some Lyrebird tracks
|
||||||
msg.params['vol'] = .8
|
msg.params['vol'] = .8
|
||||||
|
|
||||||
msg.params['vol'] = float(msg.params['vol'])
|
msg.params['vol'] = float(msg.params['vol'])
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def parseForVariables(self):
|
def parseForVariables(self):
|
||||||
|
@ -215,8 +215,8 @@ class Reply(object):
|
||||||
self.forMessage = None
|
self.forMessage = None
|
||||||
self.utterances = []
|
self.utterances = []
|
||||||
self.setForMessage(message)
|
self.setForMessage(message)
|
||||||
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get reply {self}')
|
# print(f'get reply {self}')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
@ -297,8 +297,8 @@ class Condition(object):
|
||||||
self.logInfo = None
|
self.logInfo = None
|
||||||
self.originalJsonString = None
|
self.originalJsonString = None
|
||||||
self.usedContainsDuration = None
|
self.usedContainsDuration = None
|
||||||
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get condition {self.id}')
|
# print(f'get condition {self.id}')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
@ -500,8 +500,8 @@ class Direction(object):
|
||||||
self.conditions = []
|
self.conditions = []
|
||||||
self.conditionMet = None
|
self.conditionMet = None
|
||||||
self.isDiversionReturn = False
|
self.isDiversionReturn = False
|
||||||
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get direction {self.id}')
|
# print(f'get direction {self.id}')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
@ -568,8 +568,8 @@ class Diversion(object):
|
||||||
|
|
||||||
if not self.method:
|
if not self.method:
|
||||||
raise Exception("No valid type given for diversion")
|
raise Exception("No valid type given for diversion")
|
||||||
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get diversion {self.id}')
|
# print(f'get diversion {self.id}')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
@ -628,7 +628,7 @@ class Diversion(object):
|
||||||
}]
|
}]
|
||||||
"""
|
"""
|
||||||
self.counter +=1
|
self.counter +=1
|
||||||
|
# story.logger.warn(f"CREATING DIRECTIONS FOR {startMsg.id}")
|
||||||
finishMessageIds = story.getFinishesForMsg(startMsg)
|
finishMessageIds = story.getFinishesForMsg(startMsg)
|
||||||
finalTimeoutDuration = timeoutDuration
|
finalTimeoutDuration = timeoutDuration
|
||||||
finalContainsDurations = replyContainsDurations
|
finalContainsDurations = replyContainsDurations
|
||||||
|
@ -647,6 +647,7 @@ class Diversion(object):
|
||||||
finalContainsDurations = json.loads(condition.originalJsonString)['vars']['delays']
|
finalContainsDurations = json.loads(condition.originalJsonString)['vars']['delays']
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
# story.logger.warn(f"FINISHES: {finishMessageIds}")
|
||||||
for msgId in finishMessageIds:
|
for msgId in finishMessageIds:
|
||||||
# Some very ugly hack to add a direction & condition
|
# Some very ugly hack to add a direction & condition
|
||||||
i+=1
|
i+=1
|
||||||
|
@ -693,6 +694,7 @@ class Diversion(object):
|
||||||
story.logger.info(f"Created direction: {direction.id} {condition.id} with timeout {finalTimeoutDuration}s")
|
story.logger.info(f"Created direction: {direction.id} {condition.id} with timeout {finalTimeoutDuration}s")
|
||||||
story.add(condition)
|
story.add(condition)
|
||||||
story.add(direction)
|
story.add(direction)
|
||||||
|
# story.logger.warn(f"ADDED DIRECTION {direction.id}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -943,7 +945,7 @@ class Diversion(object):
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
id = 'configuration'
|
id = 'configuration'
|
||||||
volume = 1
|
volume = 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def initFromJson(configClass, data, story):
|
def initFromJson(configClass, data, story):
|
||||||
config = Configuration()
|
config = Configuration()
|
||||||
|
@ -1006,22 +1008,22 @@ class Stopwatch(object):
|
||||||
def clearMark(self, name):
|
def clearMark(self, name):
|
||||||
if name in self.marks:
|
if name in self.marks:
|
||||||
self.marks.pop(name)
|
self.marks.pop(name)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# print(f'get stopwatch')
|
# print(f'get stopwatch')
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
state['isRunning'] = self.isRunning.is_set()
|
state['isRunning'] = self.isRunning.is_set()
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
|
|
||||||
self.isRunning = asyncio.Event()
|
self.isRunning = asyncio.Event()
|
||||||
if 'isRunning' in state and state['isRunning']:
|
if 'isRunning' in state and state['isRunning']:
|
||||||
self.isRunning.set()
|
self.isRunning.set()
|
||||||
else:
|
else:
|
||||||
self.isRunning.clear()
|
self.isRunning.clear()
|
||||||
|
|
||||||
|
|
||||||
class StoryState(object):
|
class StoryState(object):
|
||||||
"""
|
"""
|
||||||
|
@ -1064,7 +1066,7 @@ class StoryState(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
#
|
#
|
||||||
|
|
||||||
class Story(object):
|
class Story(object):
|
||||||
"""Story represents and manages a story/narrative flow"""
|
"""Story represents and manages a story/narrative flow"""
|
||||||
|
@ -1484,7 +1486,7 @@ class Story(object):
|
||||||
|
|
||||||
# TODO create timer event
|
# TODO create timer event
|
||||||
# self.commands.append({'msg':'TEST!'})
|
# self.commands.append({'msg':'TEST!'})
|
||||||
|
|
||||||
# Test stability of Central Command with deliberate crash
|
# Test stability of Central Command with deliberate crash
|
||||||
# if self.timer.getElapsed() > 10:
|
# if self.timer.getElapsed() > 10:
|
||||||
# raise Exception("Test exception")
|
# raise Exception("Test exception")
|
||||||
|
@ -1552,10 +1554,10 @@ class Story(object):
|
||||||
self.logger.critical(f"error: crash when reading wave file: {fn}")
|
self.logger.critical(f"error: crash when reading wave file: {fn}")
|
||||||
self.logger.exception(e)
|
self.logger.exception(e)
|
||||||
duration = 10 # some default duration to have something to fall back to
|
duration = 10 # some default duration to have something to fall back to
|
||||||
|
|
||||||
params = message.getParams().copy()
|
params = message.getParams().copy()
|
||||||
params['vol'] = params['vol'] * self.configuration.volume if 'vol' in params else self.configuration.volume
|
params['vol'] = params['vol'] * self.configuration.volume if 'vol' in params else self.configuration.volume
|
||||||
|
|
||||||
# self.hugvey.google.pause() # pause STT to avoid text events while decision is made
|
# self.hugvey.google.pause() # pause STT to avoid text events while decision is made
|
||||||
self.hugvey.sendCommand({
|
self.hugvey.sendCommand({
|
||||||
'action': 'play',
|
'action': 'play',
|
||||||
|
@ -1620,7 +1622,7 @@ class Story(object):
|
||||||
self.isRunning = True
|
self.isRunning = True
|
||||||
if not self.lastMsgFinishTime and self.currentMessage:
|
if not self.lastMsgFinishTime and self.currentMessage:
|
||||||
await self.setCurrentMessage(self.currentMessage)
|
await self.setCurrentMessage(self.currentMessage)
|
||||||
|
|
||||||
await self._renderer()
|
await self._renderer()
|
||||||
|
|
||||||
def isFinished(self):
|
def isFinished(self):
|
||||||
|
@ -1648,16 +1650,16 @@ class Story(object):
|
||||||
self.timer.pause()
|
self.timer.pause()
|
||||||
|
|
||||||
def calculateFinishesForMsg(self, msgId, depth = 0, checked = []):
|
def calculateFinishesForMsg(self, msgId, depth = 0, checked = []):
|
||||||
if msgId in checked:
|
# if msgId in checked:
|
||||||
return []
|
# return []
|
||||||
|
#
|
||||||
checked.append(msgId)
|
# checked.append(msgId)
|
||||||
|
|
||||||
if not msgId in self.directionsPerMsg or len(self.directionsPerMsg[msgId]) < 1:
|
if not msgId in self.directionsPerMsg or len(self.directionsPerMsg[msgId]) < 1:
|
||||||
# is finish
|
# is finish
|
||||||
return [msgId]
|
return [msgId]
|
||||||
|
|
||||||
if depth > 200:
|
if depth > 100:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
finishes = []
|
finishes = []
|
||||||
|
@ -1690,6 +1692,7 @@ class Story(object):
|
||||||
|
|
||||||
returns message ids
|
returns message ids
|
||||||
"""
|
"""
|
||||||
|
print(msg.id, self.strands)
|
||||||
if msg.id in self.strands:
|
if msg.id in self.strands:
|
||||||
return self.strands[msg.id]
|
return self.strands[msg.id]
|
||||||
|
|
||||||
|
@ -1709,22 +1712,22 @@ class Story(object):
|
||||||
|
|
||||||
# TODO: should the direction have at least a timeout condition set, or not perse?
|
# TODO: should the direction have at least a timeout condition set, or not perse?
|
||||||
return self.directionsPerMsg[msg.id][0]
|
return self.directionsPerMsg[msg.id][0]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getStateDir(self):
|
def getStateDir(self):
|
||||||
return "/tmp"
|
return "/tmp"
|
||||||
# day = time.strftime("%Y%m%d")
|
# day = time.strftime("%Y%m%d")
|
||||||
# t = time.strftime("%H:%M:%S")
|
# t = time.strftime("%H:%M:%S")
|
||||||
#
|
#
|
||||||
# self.out_folder = os.path.join(self.main_folder, day, f"{self.hv_id}", t)
|
# self.out_folder = os.path.join(self.main_folder, day, f"{self.hv_id}", t)
|
||||||
# if not os.path.exists(self.out_folder):
|
# if not os.path.exists(self.out_folder):
|
||||||
# self.logger.debug(f"Create directory {self.out_folder}")
|
# self.logger.debug(f"Create directory {self.out_folder}")
|
||||||
# self.target_folder = os.makedirs(self.out_folder, exist_ok=True)
|
# self.target_folder = os.makedirs(self.out_folder, exist_ok=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getStateFilename(cls, hv_id):
|
def getStateFilename(cls, hv_id):
|
||||||
return os.path.join(cls.getStateDir(), f"hugvey{hv_id}")
|
return os.path.join(cls.getStateDir(), f"hugvey{hv_id}")
|
||||||
|
|
||||||
def storeState(self):
|
def storeState(self):
|
||||||
# TODO: stop stopwatch
|
# TODO: stop stopwatch
|
||||||
fn = self.getStateFilename(self.hugvey.id)
|
fn = self.getStateFilename(self.hugvey.id)
|
||||||
|
@ -1734,49 +1737,48 @@ class Story(object):
|
||||||
pickle.dump(self, fp)
|
pickle.dump(self, fp)
|
||||||
# write atomic to disk: flush, close, rename
|
# write atomic to disk: flush, close, rename
|
||||||
fp.flush()
|
fp.flush()
|
||||||
os.fsync(fp.fileno())
|
os.fsync(fp.fileno())
|
||||||
|
|
||||||
os.rename(tmpfn, fn)
|
os.rename(tmpfn, fn)
|
||||||
self.logger.debug(f"saved state to {fn}")
|
self.logger.debug(f"saved state to {fn}")
|
||||||
|
|
||||||
def hasSavedState(self):
|
def hasSavedState(self):
|
||||||
return self.hugveyHasSavedState(self.hugvey.id)
|
return self.hugveyHasSavedState(self.hugvey.id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def hugveyHasSavedState(cls, hv_id):
|
def hugveyHasSavedState(cls, hv_id):
|
||||||
return os.path.exists(cls.getStateFilename(hv_id))
|
return os.path.exists(cls.getStateFilename(hv_id))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def loadStoryFromState(cls, hugvey_state):
|
def loadStoryFromState(cls, hugvey_state):
|
||||||
# restart stopwatch
|
# restart stopwatch
|
||||||
with open(cls.getStateFilename(hugvey_state.id), 'rb') as fp:
|
with open(cls.getStateFilename(hugvey_state.id), 'rb') as fp:
|
||||||
story = pickle.load(fp)
|
story = pickle.load(fp)
|
||||||
|
|
||||||
story.hugvey = hugvey_state
|
story.hugvey = hugvey_state
|
||||||
story.logger = mainLogger.getChild(f"{story.hugvey.id}").getChild("story")
|
story.logger = mainLogger.getChild(f"{story.hugvey.id}").getChild("story")
|
||||||
return story
|
return story
|
||||||
# TODO: take running state etc.
|
# TODO: take running state etc.
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clearSavedState(cls, hv_id):
|
def clearSavedState(cls, hv_id):
|
||||||
fn = cls.getStateFilename(hv_id)
|
fn = cls.getStateFilename(hv_id)
|
||||||
if os.path.exists(fn):
|
if os.path.exists(fn):
|
||||||
os.unlink(fn)
|
os.unlink(fn)
|
||||||
mainLogger.info(f"Removed state: {fn}")
|
mainLogger.info(f"Removed state: {fn}")
|
||||||
#
|
#
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
# Copy the object's state from self.__dict__ which contains
|
# Copy the object's state from self.__dict__ which contains
|
||||||
# all our instance attributes. Always use the dict.copy()
|
# all our instance attributes. Always use the dict.copy()
|
||||||
# method to avoid modifying the original state.
|
# method to avoid modifying the original state.
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
|
|
||||||
# Remove the unpicklable entries.
|
# Remove the unpicklable entries.
|
||||||
del state['hugvey']
|
del state['hugvey']
|
||||||
del state['logger']
|
del state['logger']
|
||||||
# del state['isRunning']
|
# del state['isRunning']
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
#N canvas 200 136 660 592 10;
|
#N canvas 976 211 660 592 10;
|
||||||
#X obj 131 277 dac~;
|
#X obj 131 277 dac~;
|
||||||
#X obj 131 227 readsf~;
|
#X obj 131 227 readsf~;
|
||||||
#X obj 209 209 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
|
#X obj 209 209 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
|
||||||
-1 -1;
|
-1 -1;
|
||||||
#X text 229 206 (re-)start loop;
|
#X text 229 206 (re-)start loop;
|
||||||
#X msg 132 170 open /home/a/projects/pd-play/testaudio.wav \, 1;
|
|
||||||
#X obj 208 459 netsend -u -b;
|
#X obj 208 459 netsend -u -b;
|
||||||
#X obj 208 481 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
|
#X obj 208 481 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
|
||||||
1;
|
1;
|
||||||
#X msg 355 464 disconnect;
|
#X msg 355 464 disconnect;
|
||||||
#X obj 208 393 list prepend send;
|
#X obj 208 393 list prepend send;
|
||||||
|
@ -19,33 +18,35 @@
|
||||||
#X obj 318 84 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
|
#X obj 318 84 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
|
||||||
-1;
|
-1;
|
||||||
#X text 217 60 START;
|
#X text 217 60 START;
|
||||||
#X obj 436 84 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
|
#X obj 436 84 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
|
||||||
1;
|
1;
|
||||||
#X text 309 61 !STOP!;
|
#X text 309 61 !STOP!;
|
||||||
#X text 422 60 Playing indicator;
|
#X text 422 60 Playing indicator;
|
||||||
#X msg 261 118 1;
|
#X msg 261 118 1;
|
||||||
#X msg 330 117 0;
|
#X msg 330 117 0;
|
||||||
#X obj 208 345 oscformat /loop;
|
#X obj 208 345 oscformat /loop;
|
||||||
#X msg 356 434 connect 192.168.178.15 7400;
|
#X msg 356 434 connect 192.168.1.174 7400;
|
||||||
|
#X msg 132 170 open /mnt/stash/hugvey/score38_loop_40s_extra.wav \,
|
||||||
|
1;
|
||||||
#X connect 1 0 0 0;
|
#X connect 1 0 0 0;
|
||||||
#X connect 1 0 0 1;
|
#X connect 1 0 0 1;
|
||||||
#X connect 1 1 2 0;
|
#X connect 1 1 2 0;
|
||||||
#X connect 2 0 4 0;
|
#X connect 2 0 22 0;
|
||||||
#X connect 2 0 13 0;
|
#X connect 2 0 12 0;
|
||||||
#X connect 4 0 1 0;
|
#X connect 4 0 5 0;
|
||||||
#X connect 5 0 6 0;
|
#X connect 6 0 4 0;
|
||||||
#X connect 7 0 5 0;
|
#X connect 7 0 8 0;
|
||||||
#X connect 8 0 9 0;
|
#X connect 8 0 4 0;
|
||||||
#X connect 9 0 5 0;
|
#X connect 9 0 1 0;
|
||||||
#X connect 10 0 1 0;
|
#X connect 10 0 21 0;
|
||||||
#X connect 11 0 22 0;
|
#X connect 10 0 2 0;
|
||||||
#X connect 11 0 2 0;
|
#X connect 10 0 18 0;
|
||||||
#X connect 11 0 19 0;
|
#X connect 12 0 20 0;
|
||||||
#X connect 13 0 21 0;
|
#X connect 13 0 9 0;
|
||||||
#X connect 14 0 10 0;
|
#X connect 13 0 6 0;
|
||||||
#X connect 14 0 7 0;
|
#X connect 13 0 19 0;
|
||||||
#X connect 14 0 20 0;
|
#X connect 18 0 15 0;
|
||||||
#X connect 19 0 16 0;
|
#X connect 19 0 15 0;
|
||||||
#X connect 20 0 16 0;
|
#X connect 20 0 7 0;
|
||||||
#X connect 21 0 8 0;
|
#X connect 21 0 4 0;
|
||||||
#X connect 22 0 5 0;
|
#X connect 22 0 1 0;
|
||||||
|
|
Loading…
Reference in a new issue