]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blame - music_sampler/mixer.py
Use pip setup file
[perso/Immae/Projets/Python/MusicSampler.git] / music_sampler / mixer.py
CommitLineData
22514f3a
IB
1import sounddevice as sd
2import audioop
3import time
4
6ebe6247 5from .helpers import Config
75d6cdba
IB
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):
20586193
IB
38 if music_file in self.open_files:
39 self.open_files.remove(music_file)
22514f3a
IB
40 if len(self.open_files) == 0:
41 self.stop()
42
43 def stop(self):
44 self.stream.stop()
45
46 def start(self):
47 self.stream.start()
48
49 def play_callback(self, out_data, frame_count, time_info, status_flags):
50 out_data_length = len(out_data)
51 empty_data = b"\0" * out_data_length
52 data = b"\0" * out_data_length
53
54 for open_file in self.open_files:
55 file_data = open_file.play_callback(out_data_length, frame_count)
56
57 if data == empty_data:
58 data = file_data
59 elif file_data != empty_data:
60 data = audioop.add(data, file_data, sample_width)
61
62 out_data[:] = data
63