J'adore les trackballs de Kensington. Lorsqu'on lui a demandé «Est-ce facile d'utiliser une boule de commande?», J'ai parfois répondu: «C'est facile de s'y habituer, mais ça ressemble à Termin». Est-ce vraiment Termin? !! Afin de vérifier cela, j'ai créé un programme qui change la hauteur et le volume en fonction de la position de la souris.
Utilisez les 5 modules suivants.
import pyaudio
import numpy as np
import pyautogui
import keyboard
from scipy import arange, cumsum, sin, linspace
from scipy import pi as mpi
Cette fois, pyautogui est utilisé pour obtenir les informations de position de la souris. Si la version pip est 20.2.1, il semble qu'une erreur d'installation se produira (à partir du 2020.8.11). J'ai rétrogradé la pymsgbox qui était installée avec et l'ai installée manuellement pour l'éviter. À propos, la sous-machine était la version précédente de pip lui-même, mais dans ce cas, j'ai pu l'installer sans générer d'erreur. (Article précédent https://qiita.com/Lemon2Lemonade/items/0a24a4b65c9031536f6e)
pyaudio est un module qui produit des sons avec python, et le clavier obtient les valeurs d'entrée du clavier.
RATE est la soi-disant fréquence d'échantillonnage, et cette fois je l'ai réglée à 44,1 kHz, ce qui est identique à CD. minfreq est la fréquence la plus basse. C'est C, qui est une octave plus bas que la A à 442Hz et monte un court 3 degrés (en loi moyenne, multiplier la fréquence par la 12ème racine de 2 élève une demi-note). La plage de tonalité est la plage de lecture de Termin. Dans le texte, la fréquence est multipliée par une constante telle que minfreq * tonerange, donc doubler signifie une octave. période est la durée du son. Détecte la position du curseur toutes les 0,01 secondes. minamp est le volume minimum et amprange est la plage de volume.
RATE = 44100 #Fréquence d'échantillonnage
CHUNK = 1024 #tampon
PITCH = 442 #pas
minfreq = PITCH/2*2**(3/12)
tonerange = 2
period = 0.01
minamp = 0.1
amprange = 0.5
Tout d'abord, obtenez la taille de la fenêtre.
def get_window_size():
window_size = pyautogui.size()
return window_size
Réglez la hauteur à changer lorsque le curseur est déplacé verticalement et le volume à changer lorsque le curseur est déplacé horizontalement. Calculez la position relative de l'écran. La hauteur est la note la plus basse en bas de l'écran et la note la plus élevée en haut de l'écran. D'autre part, le volume doit être minimum au centre de l'écran et maximum aux deux extrémités. Obtient la position relative du curseur sur l'axe x (direction horizontale) ou l'axe y (direction verticale).
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
Correspond à la position de l'écran avec la hauteur et le volume.
def tonemapping():
ratio = distance()
freq = minfreq*2**(tonerange*ratio[1])
return freq
def ampmapping():
ratio = distance()
amp = minamp+amprange*ratio[0]
return amp
A part ça, j'ai eu du mal ici. Si vous ne jouez qu'un certain son pendant une certaine période de temps par rapport à la position, le son sera haché et du bruit sera ajouté. Par conséquent, mémorisez les conditions avant la boucle (fréquence de hauteur et d'onde sinusoïdale, phase, amplitude) afin qu'elles puissent être connectées en douceur.
Je l'ai fait en référence au site suivant. http://yukara-13.hatenablog.com/entry/2013/12/23/053957
Si vous ne correspondez pas à la phase (si vous ne faites pas d'onde de péché connectée), vous obtiendrez un «bourdonnement». Si vous calculez la période de lecture en 0,01 seconde, le bruit sera plus perceptible que l'onde sinueuse.
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 #Quantité de changement de fréquence angulaire
phazes = cumsum(phazes_diff) + phaze_start #phase
phaze_last = phazes[-1]
ret = A * sin(phazes) #Synthèse sinusoïdale
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