diff options
Diffstat (limited to 'helpers/mixer.py')
-rw-r--r-- | helpers/mixer.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/helpers/mixer.py b/helpers/mixer.py new file mode 100644 index 0000000..9e8179a --- /dev/null +++ b/helpers/mixer.py | |||
@@ -0,0 +1,50 @@ | |||
1 | import sounddevice as sd | ||
2 | import audioop | ||
3 | import time | ||
4 | |||
5 | frame_rate = 44100 | ||
6 | channels = 2 | ||
7 | sample_width = 2 | ||
8 | |||
9 | class Mixer: | ||
10 | def __init__(self): | ||
11 | self.stream = sd.RawOutputStream(samplerate=frame_rate, | ||
12 | channels=channels, | ||
13 | dtype='int' + str(8*sample_width), # FIXME: ? | ||
14 | latency="high", | ||
15 | blocksize=5000, | ||
16 | callback=self.play_callback, | ||
17 | ) | ||
18 | self.open_files = [] | ||
19 | |||
20 | def add_file(self, music_file): | ||
21 | if music_file not in self.open_files: | ||
22 | self.open_files.append(music_file) | ||
23 | self.start() | ||
24 | |||
25 | def remove_file(self, music_file): | ||
26 | self.open_files.remove(music_file) | ||
27 | if len(self.open_files) == 0: | ||
28 | self.stop() | ||
29 | |||
30 | def stop(self): | ||
31 | self.stream.stop() | ||
32 | |||
33 | def start(self): | ||
34 | self.stream.start() | ||
35 | |||
36 | def play_callback(self, out_data, frame_count, time_info, status_flags): | ||
37 | out_data_length = len(out_data) | ||
38 | empty_data = b"\0" * out_data_length | ||
39 | data = b"\0" * out_data_length | ||
40 | |||
41 | for open_file in self.open_files: | ||
42 | file_data = open_file.play_callback(out_data_length, frame_count) | ||
43 | |||
44 | if data == empty_data: | ||
45 | data = file_data | ||
46 | elif file_data != empty_data: | ||
47 | data = audioop.add(data, file_data, sample_width) | ||
48 | |||
49 | out_data[:] = data | ||
50 | |||