-
Notifications
You must be signed in to change notification settings - Fork 0
/
beep_generator.py
92 lines (74 loc) · 3.52 KB
/
beep_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# "python - how can I generate a WAV file with beeps?"; StackOverflow; Rik Mulder; Dec 6, 2022 at 23:48; https://stackoverflow.com/a/74710298
import scipy.io.wavfile
import numpy as np
class BeepGenerator:
def __init__(self):
# Audio will contain a long list of samples (i.e. floating point numbers describing the
# waveform). If you were working with a very long sound you'd want to stream this to
# disk instead of buffering it all in memory list this. But most sounds will fit in
# memory.
self.audio = []
self.sample_rate = 44100.0
def append_silence(self, duration_milliseconds=500):
"""
Adding silence is easy - we add zeros to the end of our array
"""
num_samples = duration_milliseconds * (self.sample_rate / 1000.0)
for x in range(int(num_samples)):
self.audio.append(0.0)
return
def append_sinewave(
self,
freq=440.0,
duration_milliseconds=500,
volume=1.0):
"""
The sine wave generated here is the standard beep. If you want something
more aggressive you could try a square or saw tooth waveform. Though there
are some rather complicated issues with making high quality square and
sawtooth waves... which we won't address here :)
"""
num_samples = duration_milliseconds * (self.sample_rate / 1000.0)
x = np.array([i for i in range(int(num_samples))])
sine_wave = volume * np.sin(2 * np.pi * freq * (x / self.sample_rate))
self.audio.extend(list(sine_wave))
return
def append_sinewaves(
self,
freqs=[440.0],
duration_milliseconds=500,
volumes=[1.0]):
"""
The sine wave generated here is the standard beep. If you want something
more aggressive you could try a square or saw tooth waveform. Though there
are some rather complicated issues with making high quality square and
sawtooth waves... which we won't address here :)
len(freqs) must be the same as len(volumes)
"""
volumes = list(np.array(volumes)/sum(volumes))
num_samples = duration_milliseconds * (self.sample_rate / 1000.0)
x = np.array([i for i in range(int(num_samples))])
first_it = True
for volume, freq in zip(volumes, freqs):
print(freq)
if first_it:
sine_wave = volume * np.sin(2 * np.pi * freq * (x / self.sample_rate))
first_it = False
else:
sine_wave += volume * np.sin(2 * np.pi * freq * (x / self.sample_rate))
self.audio.extend(list(sine_wave))
return
def save_wav(self, file_name):
# Open up a wav file
# wav params
# 44100 is the industry standard sample rate - CD quality. If you need to
# save on file size you can adjust it downwards. The standard for low quality
# is 8000 or 8kHz.
# WAV files here are using short, 16 bit, signed integers for the
# sample size. So we multiply the floating point data we have by 32767, the
# maximum value for a short integer. NOTE: It is theoretically possible to
# use the floating point -1.0 to 1.0 data directly in a WAV file but not
# obvious how to do that using the wave module in python.
self.audio = np.array(self.audio).astype(np.float32)
scipy.io.wavfile.write(file_name, int(self.sample_rate), np.array(self.audio))
return