]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blame - helpers/mixer.py
Coding styles
[perso/Immae/Projets/Python/MusicSampler.git] / helpers / mixer.py
CommitLineData
22514f3a
IB
1import sounddevice as sd
2import audioop
3import time
4
75d6cdba
IB
5from . import Config
6
7sample_width = Config.sample_width
2e404903 8
75d6cdba
IB
9def sample_width_to_dtype(sample_width):
10 if sample_width == 1 or sample_width == 2 or sample_width == 4:
11 return 'int' + str(8*sample_width)
12 else:
13 raise "Unknown sample width"
14
15def _latency(latency):
16 if latency == "high" or latency == "low":
17 return latency
18 else:
19 return float(latency)
22514f3a
IB
20
21class Mixer:
22 def __init__(self):
2e404903
IB
23 self.stream = sd.RawOutputStream(
24 samplerate=Config.frame_rate,
25 channels=Config.channels,
26 dtype=sample_width_to_dtype(Config.sample_width),
27 latency=_latency(Config.latency),
28 blocksize=Config.blocksize,
29 callback=self.play_callback)
22514f3a
IB
30 self.open_files = []
31
32 def add_file(self, music_file):
33 if music_file not in self.open_files:
34 self.open_files.append(music_file)
35 self.start()
36
37 def remove_file(self, music_file):
38 self.open_files.remove(music_file)
39 if len(self.open_files) == 0:
40 self.stop()
41
42 def stop(self):
43 self.stream.stop()
44
45 def start(self):
46 self.stream.start()
47
48 def play_callback(self, out_data, frame_count, time_info, status_flags):
49 out_data_length = len(out_data)
50 empty_data = b"\0" * out_data_length
51 data = b"\0" * out_data_length
52
53 for open_file in self.open_files:
54 file_data = open_file.play_callback(out_data_length, frame_count)
55
56 if data == empty_data:
57 data = file_data
58 elif file_data != empty_data:
59 data = audioop.add(data, file_data, sample_width)
60
61 out_data[:] = data
62