-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
94 lines (68 loc) · 2.23 KB
/
main.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
93
94
import time
import math
import numpy as np
import simpleaudio as sa
def fnv1a_hash(word):
h = 2166136261
for c in word:
h ^= ord(c)
h *= 16777619
h &= 0xFFFFFFFF
return h
def generate_beep(frequency, duration=0.03, sample_rate=44100, amplitude=0.5):
t = np.linspace(0, duration, int(sample_rate * duration), False)
wave = amplitude * np.sin(2 * np.pi * frequency * t)
# Apply fade-in and fade-out
fade_duration = int(sample_rate * 0.01) # 50ms fade in/out
fade_in = np.linspace(0, 1, fade_duration)
fade_out = np.linspace(1, 0, fade_duration)
wave[:fade_duration] *= fade_in
wave[-fade_duration:] *= fade_out
# Ensure waveform is in 16-bit range
wave = np.int16(wave * 32767)
return wave
def play_sound(sound_wave, sample_rate=44100):
play_obj = sa.play_buffer(sound_wave, 1, 2, sample_rate)
play_obj.wait_done()
def word_to_beeps(word, factor=3, min_freq=200, max_freq=900):
punctuation_freq = -1
punctuation = {
"!": 800,
"?": 500,
"...": 300,
".": 400
}
for key in punctuation:
if word.endswith(key):
punctuation_freq = punctuation[key]
break
# Normalize the word: lowercase and remove punctuation
normalized_word = ''.join(char for char in word.lower() if char.isalnum())
# Calculate the number of beeps based on word length
num_beeps = math.ceil(len(normalized_word) / factor)
# Use FNV-1a hash
hash_int = fnv1a_hash(normalized_word)
# Generate the frequencies
freqs = []
for i in range(num_beeps):
segment = (hash_int >> (i * 8)) & 0xFF
freq = min_freq + (segment / 255) * (max_freq - min_freq)
freq = round(freq) # rounds into nice numbers to work with
print(f"f:{freq}")
freqs.append(freq)
if punctuation_freq > 0:
freqs.append(punctuation_freq)
return freqs
def droid_speak(sentence):
words = sentence.split()
for word in words:
freqs = word_to_beeps(word)
for freq in freqs:
beep = generate_beep(freq)
play_sound(beep)
time.sleep(0.03)
def main():
while True:
droid_speak(input(">"))
if __name__ == "__main__":
main()