Expliquez en détail comment créer un son avec python

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.

Chapitre.0 Langue / Module

--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.

Chapitre 1. Je dois exprimer le son avec une expression ...

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. サンプリング周波数.jpg (À 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). 正弦波.jpg 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)

Chapitre 2. Sortons le son exprimé par le programme en .wav. Faisons cela.

Le flux à partir d'ici est le suivant.

  1. Sortez le son créé sous forme de fichier .wav.
  2. Binaire des données sonores avec le module struct.
  3. Sortez les données binarisées sous forme de fichier .wav avec le module wave.
  4. Jouez le son créé sur le programme. (Tout)
  5. Ouvrez le fichier .wav créé avec le module wave
  6. Jouez avec le module pyaudio.
  7. Affichez la forme d'onde sonore sous forme de graphique avec le module matplotlib.pyplot. (Tout)

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.

1. Binarisation

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)

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!

2. Sortie du fichier .wav avec le module wave

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

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é!)

Chapitre 3. Je veux faire un son sur le programme parce que c'est ennuyeux!

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.

Chapitre 4. Affichage Wave

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.

À la fin

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?

Site de référence / littérature

Code final

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

Expliquez en détail comment créer un son avec python
Comment utiliser BigQuery en Python
[REAPER] Comment jouer à Reascript avec Python
Comment utiliser tkinter avec python dans pyenv
Comment apporter des modifications à l'interpréteur Python dans Pycharm
Gérer les sons en Python
Comment développer en Python
Comment convertir / restaurer une chaîne avec [] en python
Comment faire un calcul de hachage avec Salt en Python
Comment exécuter des tests avec Python unittest
[Python] Comment faire PCA avec Python
Comment collecter des images en Python
Comment utiliser SQLite en Python
Comment démarrer avec Python
Comment utiliser Mysql avec python
Comment envelopper C en Python
Comment utiliser ChemSpider en Python
Comment utiliser PubChem avec Python
Comment calculer la date avec python
Comment gérer le japonais avec Python
Comment extraire n'importe quel rendez-vous dans Google Agenda avec Python
Comment se connecter à AtCoder avec Python et soumettre automatiquement
Comment gérer l'erreur d'installation de python dans pyenv (BUILD FAILED)
[Introduction à Python] Comment utiliser la classe en Python?
Comment ne pas échapper au japonais en traitant avec JSON en Python
Comment définir dynamiquement des variables en Python
[Python] Comment rendre une classe itérable
Comment faire R chartr () en Python
Comment transformer une chaîne en tableau ou un tableau en chaîne en Python
[Itertools.permutations] Comment créer une séquence en Python
Fractal pour faire et jouer avec Python
Comment créer une caméra de surveillance (caméra de sécurité) avec Opencv et Python
Pour utiliser python, mettez pyenv sur macOS avec PyCall
Comment obtenir stacktrace en python
Comment afficher la table quatre-vingt-dix-neuf en python
Comment extraire une zone de polygone en Python
Comment faire un test de sac avec python
Comment vérifier la version d'opencv avec python
Comment afficher le japonais python avec lolipop
Comment changer de version de Python dans cloud9
Comment régler le contraste de l'image en Python
Comment utiliser __slots__ dans la classe Python
Jetez quelque chose dans Kinesis avec python et assurez-vous qu'il est dans
Comment remplir dynamiquement des zéros avec Python
Comment entrer le japonais avec les malédictions Python
Pour faire fonctionner la station d'horodatage en Python
Comment utiliser les expressions régulières en Python
Comment afficher Hello World en python
Comment utiliser is et == en Python
Comment afficher les marques de légende en un avec le tracé Python 2D
Comment écrire Ruby to_s en Python
Comment installer python3 avec docker centos
Comment calculer "xx time" en un seul coup avec Python Timedelta
Comment obtenir la différence de date et d'heure en secondes avec Python
Je veux expliquer en détail la classe abstraite (ABCmeta) de Python
Que faire lorsque la version Python est ancienne dans Cloud 9 créée par une autre personne
Comment télécharger avec Heroku, Flask, Python, Git (4)