Les êtres humains sont des créatures qui veulent créer eux-mêmes un logiciel de lecture vocale synthétique. C'est inévitable. Pascal dit aussi, les gens pensent aux roseaux. vous voyez? (Quoi?)
Eh bien, pour le moment, je vais essayer une implémentation qui produit des sons avec python avec des nuances comme cette enquête préliminaire.
--Langue: Python
python
import numpy as np
import matplotlib.pyplot as pl
import wave
import struct
import pyaudio
Le notebook Jupyter peut rendre le son un peu plus facile (je ne connais pas les détails), mais non.
Vous savez ce qu'est le son?
Le son est comme un changement périodique (?) De la densité de l'air.
Bref, c'est une vague. En parlant de vagues, c'est du péché, cos. Hourra!
En conclusion, cette fois nous utiliserons une onde sinusoïdale avec la formule suivante.
sin(2πnt/s)
note_hz
=n
sample_hz
=s
python
sec = 1 #1 seconde
note_hz = 440 #La fréquence sonore
sample_hz = 44100 #Fréquence d'échantillonnage
t = np.arange(0, sample_hz * sec) #Sécurisez une plage horaire pendant 1 seconde
wv = np.sin(2 * np.pi * note_hz * t/sample_hz)
«t» représente le temps de 1 seconde, et dans le cas ci-dessus, c'est un tableau unidimensionnel de 44100 éléments. Les informations dans le monde dans lequel nous vivons sont continues (analogiques), mais malheureusement, les ordinateurs personnels ne peuvent traiter que des données discrètes (numériques). Par conséquent, une seconde est divisée en 44100 pièces et exprimée. (À propos, la fréquence d'échantillonnage de 44100hz est la norme de la fréquence d'échantillonnage du CD, et c'est environ deux fois le nombre de la plage audible humaine. Pourquoi est-elle doublée? Google avec la fréquence de Nyquist.)
Le contenu du signe est * 2πnt / s *.
t / sample_hz
* = t / s * augmente à * 0,1,2, ..., 44100 * En divisant * t * par * s = 44100 *, * 0,1 / 44100 , 2/44100, ..., 440099 / 44100,1 *, qui exprime "une seconde qui augmente progressivement (1/44100 chacun)".
Une fois que vous ignorez note_hz
* = n * et regardez np.sin (2 * np.pi * t / sample_hz)
* = sin (2πt / s) *, * t / s * vaut 0 Puisqu'il est considéré comme une variable qui augmente de → 1 (plutôt qu'une fonction du temps?), On peut voir que * 2πt / s * à l'intérieur de sin augmente de 0 à 2π.
En d'autres termes, * sin (2πt / s) * est une fonction qui fait le tour du cercle unitaire exactement en une seconde (une onde qui vibre une fois par seconde).
Vibrer une fois par seconde signifie que la fréquence de cette onde est de 1 [Hz = 1 / s].
Cependant, il ne peut pas être entendu à la fréquence 1.
C'est là qu'intervient note_hz
* = n *.
Vous pouvez modifier librement la fréquence de l'onde simplement en multipliant n par * 2πt / s *. Par exemple, si * n = 440 *, * sin (2πnt / s) * devient une onde («la» en termes de son) qui vibre 440 fois par seconde.
Ceci termine l'expression du son sur le programme. Je recopierai le programme collé ci-dessus.
python
sec = 1 #1 seconde
note_hz = 440 #La fréquence sonore
sample_hz = 44100 #Fréquence d'échantillonnage
t = np.arange(0, sample_hz * sec) #Sécurisez une plage horaire pendant 1 seconde
wv = np.sin(2 * np.pi * note_hz * t/sample_hz)
Le flux à partir d'ici est le suivant.
Concernant 3., si vous ne vous souciez pas de la forme d'onde, vous n'avez pas à le faire du tout. 2. utilise un module appelé pyaudio, mais il est gênant de l'installer avec la série Python 3.7 (si vous voulez l'installer, veuillez vous référer au site de référence à la fin de cette page), donc le .wav créé en 1. Vous pouvez lire le fichier avec Windows Media Player.
Maintenant, je vais expliquer comment sortir en .wav.
Il est binarisé. La binarisation consiste à convertir des données en nombres binaires. Lors de l'utilisation du module wave, il semble qu'il n'est pas possible d'écrire dans le fichier .wav à moins qu'il ne soit binarisé. Peut-être. Alors faisons-le binaire!
Collons d'abord la réponse.
python
max_num = 32767.0 / max(wv) #Préparation à la binarisation
wv16 = [int(x * max_num) for x in wv] #Préparation à la binarisation
bi_wv = struct.pack("h" * len(wv16), *wv16) #Binaire
C'est comme ça. (C'est plutôt comme copier le site auquel j'ai fait référence, mais y a-t-il une manière qui interdit la copie ...? Eh bien, non. )
Regardons le contenu de [int (x * max_num) for x in wv]
avec wv
* = W, * x
* = "chacun des éléments enfants de W" = w *.
Dans chaque élément enfant w de W,
x * max_num
=x * 32767.0 / max(wv)
Quel nombre est 32767! Je pense que tu comprends. En effet, les valeurs possibles des données 16 bits (données exprimées en nombres binaires à 16 chiffres) sont * -32768 à 32767 *. (2 à la 16e puissance est 65536, et la moitié d'entre eux sont 32768, donc ... je suis fou)
wv16
. Euh ...Et le code binaire bi_wv = struct.pack (" h "* len (wv16), * wv16)
.
Pour être honnête, je n'en sais rien. Ceci est une copie.
Pour le moment, la structure binaire struct.pack
le convertit au format binaire, et le premier argument" h "
semble être un format entier de 2 octets (16 bits). Hey.
Oui, la binarisation est terminée!
Je vais coller à nouveau la réponse en premier.
python
file = wave.open('sin_wave.wav', mode='wb') #sin_wave.Ouvrez wav en mode écriture. (Si le fichier n'existe pas, créez-en un nouveau.)
param = (1,2,sample_hz,len(bi_wv),'NONE','not compressed') #Paramètres
file.setparams(param) #Paramètres des paramètres
file.writeframes(bi_wv) #Écrire des données
file.close #Fermer le fichier
C'est comme ça.
Ouvrez le fichier avec wave.open ()
.
Spécifiez le nom du fichier avec le premier argument, et définissez le mode d'écriture ( wb '') ou le mode de lecture (
rb '') avec le deuxième argument mode =
.
Définissez les paramètres du fichier .wav avec wave.setparams ()
.
Les paramètres (param
) sont dans l'ordre à partir de la gauche
t
)non compressé '' est renvoyé pour le format compressé
AUCUN ''.)est.
Ensuite, écrivez les données binarisées (bi_wv
) et fermez le fichier.
Il est facile d'oublier de fermer le fichier ...
D'accord, c'est fait! !! (Essayez d'exécuter le fichier sur votre terminal ou à l'invite de commande pour voir si un fichier .wav est généré!)
Alors, ouvrez d'abord le fichier que vous avez créé précédemment avec le module wave.
python
file = wave.open('sin_wave.wav', mode='rb')
Vous pouvez l'ouvrir avec ça.
Vous êtes correctement en mode lecture.
La partie file
de file = wave.open ('sin_wave.wav', mode = 'rb')
représente une variable, vous pouvez donc utiliser un nom différent. fairu
ou wave_no_kiwami_otome
ou autre.
Eh bien, je viens de le dire.
Quand j'étais débutant, devais-je l'appeler «fichier»? Parce que j'ai mal compris.
Jouez ensuite le son avec le module pyaudio.
python
p = pyaudio.PyAudio() #Instanciation de pyaudio
stream = p.open(
format = p.get_format_from_width(file.getsampwidth()),
channels = wr.getnchannels(),
rate = wr.getframerate(),
output = True
) #Créez un flux pour enregistrer et jouer des sons.
file.rewind() #Remettez le pointeur au début.
chunk = 1024 #Je ne suis pas sûr, mais la documentation officielle l'a fait.
data = file.readframes(chunk) #Lire des morceaux (1024) d'images (données de forme d'onde sonore).
while data:
stream.write(data) #Faites un son en écrivant des données dans le flux.
data = file.readframes(chunk) #Chargez une nouvelle image de bloc.
stream.close() #Fermez le flux.
p.terminate() #Fermez PyAudio.
Comme ci-dessus, la procédure est
1. Ouvrez pyaudio, 2. Ouvrez le flux, 3. Ecrivez des données pour diffuser et lire le son, 4. Fermer le flux, 5. Fermer pyaudio
C'est comme ça.
Eh bien, combien de temps un article durerait. Je suis fatigué, Patrasche. C'est pourquoi j'ai mis le code comme Burn.
python
pl.plot(t,wv)
pl.show()
Comme c'est simple! matplotlib.pyplot a beaucoup d'articles donc je ne dirai rien de particulier.
Merci d'avoir lu jusqu'ici! J'ai fait de mon mieux pour le deuxième article de Qiita de ma vie ...
Même ainsi, puis-je vraiment créer moi-même un logiciel de synthèse vocale artificielle?
python
import numpy as np
import matplotlib.pyplot as pl
import wave
import struct
import pyaudio
#Chapter1
sec = 1 #1 seconde
note_hz = 440 #La fréquence sonore
sample_hz = 44100 #Fréquence d'échantillonnage
t = np.arange(0, sample_hz * sec) #Sécurisez une plage horaire pendant 1 seconde
wv = np.sin(2 * np.pi * note_hz * t/sample_hz)
#Chapter2
max_num = 32767.0 / max(wv) #Préparation à la binarisation
wv16 = [int(x * max_num) for x in wv] #Préparation à la binarisation
bi_wv = struct.pack("h" * len(wv16), *wv16) #Binaire
file = wave.open('sin_wave.wav', mode='wb') #sin_wave.Ouvrez wav en mode écriture. (Si le fichier n'existe pas, créez-en un nouveau.)
param = (1,2,sample_hz,len(bi_wv),'NONE','not compressed') #Paramètres
file.setparams(param) #Paramètres des paramètres
file.writeframes(bi_wv) #Écrire des données
file.close #Fermer le fichier
#Chapter3
file = wave.open('sin_wave.wav', mode='rb')
p = pyaudio.PyAudio()
stream = p.open(
format = p.get_format_from_width(file.getsampwidth()),
channels = file.getnchannels(),
rate = file.getframerate(),
output = True
)
chunk = 1024
file.rewind()
data = file.readframes(chunk)
while data:
stream.write(data)
data = file.readframes(chunk)
stream.close()
p.terminate()
#Chapter4
pl.plot(t,wv)
pl.show()
Recommended Posts