|
|
|
@ -3,8 +3,9 @@ import time
|
|
|
|
|
import sys
|
|
|
|
|
import random
|
|
|
|
|
from glob import glob
|
|
|
|
|
from pygame import mixer
|
|
|
|
|
from threading import Thread
|
|
|
|
|
from typing import Union, List, Mapping
|
|
|
|
|
from pygame import mixer
|
|
|
|
|
|
|
|
|
|
from atmorepl import AtmoReplRunner
|
|
|
|
|
|
|
|
|
@ -83,9 +84,25 @@ class CampAtmo:
|
|
|
|
|
line_reaction_wait_sec = 0.8
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.stopped = False
|
|
|
|
|
mixer.init(frequency=22050 * 2)
|
|
|
|
|
self.load_sounds()
|
|
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
|
self.background_thread = Thread(
|
|
|
|
|
None, self.run_forever, "atmo-background", daemon=True
|
|
|
|
|
)
|
|
|
|
|
self.background_thread.start()
|
|
|
|
|
self.lines_thread = Thread(
|
|
|
|
|
None, self.run_lines_forever, "atmo-lines", daemon=True
|
|
|
|
|
)
|
|
|
|
|
self.lines_thread.start()
|
|
|
|
|
|
|
|
|
|
def stop():
|
|
|
|
|
self.stopped = True
|
|
|
|
|
self.lines_thread.join(2)
|
|
|
|
|
self.background_thread.join(0.5)
|
|
|
|
|
|
|
|
|
|
def load_sounds(self):
|
|
|
|
|
type_names = glob("samples/*/")
|
|
|
|
|
type_files = {}
|
|
|
|
@ -119,7 +136,9 @@ class CampAtmo:
|
|
|
|
|
i += 1
|
|
|
|
|
self.sounds = {}
|
|
|
|
|
for name, files in type_files.items():
|
|
|
|
|
self.sounds[name] = SoundCollection(name, files)
|
|
|
|
|
self.sounds[name] = SoundCollection(
|
|
|
|
|
name, files, volume=0.1 if name in self.background_track_types else 0.9
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def manage_background_queue(self, name, type_channels):
|
|
|
|
|
for c in type_channels:
|
|
|
|
@ -131,7 +150,7 @@ class CampAtmo:
|
|
|
|
|
c.queue(self.sounds[name].next())
|
|
|
|
|
|
|
|
|
|
def run_forever(self):
|
|
|
|
|
while True:
|
|
|
|
|
while not self.stopped:
|
|
|
|
|
for name, type_channels in self.types.items():
|
|
|
|
|
if (
|
|
|
|
|
name not in self.background_track_types
|
|
|
|
@ -142,15 +161,35 @@ class CampAtmo:
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
self.load_sounds()
|
|
|
|
|
|
|
|
|
|
def play_type_sounds(self, type_name) -> int:
|
|
|
|
|
if len(self.sounds[type_name]) == 0:
|
|
|
|
|
return
|
|
|
|
|
max_sound_length = 0
|
|
|
|
|
for channel in self.types[type_name]:
|
|
|
|
|
sound = self.sounds[type_name].next()
|
|
|
|
|
max_sound_length = max(max_sound_length, sound.get_length())
|
|
|
|
|
channel.queue(sound)
|
|
|
|
|
return max_sound_length
|
|
|
|
|
|
|
|
|
|
def run_lines_forever(self):
|
|
|
|
|
while not self.stopped:
|
|
|
|
|
time.sleep(random.randrange(*self.lines_delta_sec))
|
|
|
|
|
length_sec = self.play_type_sounds("lines")
|
|
|
|
|
time.sleep(length_sec + self.line_reaction_wait_sec)
|
|
|
|
|
self.play_type_sounds("reactions")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
atmo = CampAtmo()
|
|
|
|
|
atmoRepl = AtmoReplRunner(atmo, port=7723)
|
|
|
|
|
atmoRepl.start()
|
|
|
|
|
atmo.start()
|
|
|
|
|
try:
|
|
|
|
|
atmo.run_forever()
|
|
|
|
|
while True:
|
|
|
|
|
time.sleep(100)
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
print("exit")
|
|
|
|
|
print("exiting...")
|
|
|
|
|
atmo.stop()
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|