Ich liebe Kensingtons Trackballs. Auf die Frage "Ist es einfach, einen Trackball zu benutzen?" Antwortete ich manchmal: "Es ist leicht, sich daran zu gewöhnen, aber es fühlt sich an wie Termin." Ist es wirklich Termin? !! Um dies zu überprüfen, habe ich ein Programm erstellt, das die Tonhöhe und Lautstärke abhängig von der Mausposition ändert.
Verwenden Sie die folgenden 5 Module.
import pyaudio
import numpy as np
import pyautogui
import keyboard
from scipy import arange, cumsum, sin, linspace
from scipy import pi as mpi
Dieses Mal wird Pyautogui verwendet, um die Mauspositionsinformationen abzurufen. Wenn die Pip-Version 20.2.1 ist, scheint ein Installationsfehler aufzutreten (Stand 2020.8.11). Ich habe die damit installierte pymsgbox heruntergestuft und manuell installiert, um dies zu vermeiden. Der Subcomputer war übrigens die vorherige Version von pip selbst, aber in diesem Fall konnte ich ihn ohne Fehler installieren. (Vorheriger Artikel https://qiita.com/Lemon2Lemonade/items/0a24a4b65c9031536f6e)
pyaudio ist ein Modul, das mit Python Sounds erzeugt, und die Tastatur erhält Tastatureingabewerte.
RATE ist die sogenannte Abtastfrequenz, und diesmal habe ich sie auf 44,1 kHz eingestellt, was der CD entspricht. minfreq ist die niedrigste Frequenz. Es ist C, das bei 442 Hz eine Oktave niedriger als A ist und um kurze 3 Grad ansteigt (im Durchschnitt erhöht das Multiplizieren der Frequenz mit der 12. Wurzel von 2 eine halbe Note). Der Tonbereich ist der Wiedergabebereich von Termin. Im Text wird die Frequenz mit einer Konstanten wie minfreq * tonerange multipliziert, also bedeutet Verdoppeln eine Oktave. Periode ist die Dauer des Tons. Erkennt die Position des Cursors alle 0,01 Sekunden. minamp ist das Mindestvolumen und amprange ist der Lautstärkebereich.
RATE = 44100 #Abtastfrequenz
CHUNK = 1024 #Puffer
PITCH = 442 #
minfreq = PITCH/2*2**(3/12)
tonerange = 2
period = 0.01
minamp = 0.1
amprange = 0.5
def get_window_size():
window_size = pyautogui.size()
return window_size
def distance():
window_size = get_window_size()
x, y = pyautogui.position()
x_dist = np.sqrt((x-window_size.width/2)**2)
y_dist = abs(y-window_size.height)
x_max = np.sqrt((window_size.width/2)**2)
y_max = window_size.height
x_ratio = x_dist/x_max
y_ratio = y_dist/y_max
return x_ratio, y_ratio
def tonemapping():
ratio = distance()
freq = minfreq*2**(tonerange*ratio[1])
return freq
def ampmapping():
ratio = distance()
amp = minamp+amprange*ratio[0]
return amp
Positionserkennung Ermitteln Sie zuerst die Fenstergröße. Stellen Sie die Tonhöhe so ein, dass sie sich ändert, wenn der Cursor vertikal bewegt wird, und die Lautstärke, die geändert werden soll, wenn der Cursor horizontal bewegt wird. Berechnen Sie die relative Position des Bildschirms. Die Tonhöhe ist die niedrigste Note am unteren Bildschirmrand und die höchste Note am oberen Bildschirmrand. Andererseits sollte die Lautstärke in der Mitte des Bildschirms minimal und an beiden Enden maximal sein. Ruft die relative Position des Cursors auf der x-Achse (horizontale Richtung) oder der y-Achse (vertikale Richtung) ab. Entspricht der Bildschirmposition der Tonhöhe und Lautstärke. Dies ist der Teil, in dem ich es schwer hatte, die Sin Wave (Schallquelle) einzustellen und zu spielen. Wenn Sie nur einen bestimmten Sound für einen bestimmten Zeitraum in Bezug auf die Position abspielen, wird der Sound zerhackt und es werden Geräusche hinzugefügt. Denken Sie daher an die Bedingungen unmittelbar vor der Schleife (Tonhöhe und Sinuswellenfrequenz, Phase, Amplitude), damit sie reibungslos verbunden werden können.
Ich habe es mit Bezug auf die folgende Seite gemacht. http://yukara-13.hatenablog.com/entry/2013/12/23/053957
Wenn Sie nicht mit der Phase übereinstimmen (wenn Sie keine einzige verbundene Sinuswelle erzeugen), erhalten Sie ein "summendes" Rauschen. Wenn Sie die Wiedergabezeit in 0,01 Sekunden berechnen, ist das Rauschen deutlicher als die Sinuswelle.
def make_time_varying_sine(start_freq, end_freq, start_A, end_A, fs, sec, phaze_start):
freqs = linspace(start_freq, end_freq, num = int(round(fs * sec)))
A = linspace(start_A, end_A, num = int(round(fs * sec)))
phazes_diff = 2. * mpi * freqs / fs #Betrag der Änderung der Winkelfrequenz
phazes = cumsum(phazes_diff) + phaze_start #Phase
phaze_last = phazes[-1]
ret = A * sin(phazes) #Sinuswellensynthese
return ret, phaze_last
def play_wave(stream, samples):
stream.write(samples.astype(np.float32).tostring())
def play_audio():
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32,
channels=1,
rate=RATE,
frames_per_buffer=CHUNK,
output=True)
freq_old = minfreq
amp_old = minamp
phaze = 0
while True:
try:
if keyboard.is_pressed('q'):
stream.close()
break # finishing the loop
else:
freq_new = tonemapping()
amp_new = ampmapping()
tone = make_time_varying_sine(freq_old, freq_new, amp_old, amp_new, RATE, period, phaze)
play_wave(stream, tone[0])
freq_old = freq_new
amp_old = amp_new
phaze = tone[1]
except:
continue
if __name__ == '__main__':
play_audio()
Recommended Posts