web-dev-qa-db-fra.com

Quels sont les morceaux, les échantillons et les cadres lors de l'utilisation de pyaudio

Après avoir parcouru la documentation de pyaudio et lu quelques autres articles sur le web, je suis confus si ma compréhension est correcte.

Voici le code pour l'enregistrement audio trouvé sur le site de pyaudio:

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.Paint16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

et si j'ajoute ces lignes, je peux jouer ce que j'ai enregistré:

play=pyaudio.PyAudio()
stream_play=play.open(format=FORMAT,
                      channels=CHANNELS,
                      rate=RATE,
                      output=True)
for data in frames: 
    stream_play.write(data)
stream_play.stop_stream()
stream_play.close()
play.terminate()
  1. "TAUX" est le nombre d'échantillons collectés par seconde.
  2. "CHUNK" est le nombre d'images dans le tampon.
  3. Chaque trame aura 2 échantillons comme "CHANNELS = 2".
  4. La taille de chaque échantillon est de 2 octets, calculée à l'aide de la fonction: pyaudio.get_sample_size(pyaudio.Paint16).
  5. Par conséquent, la taille de chaque trame est de 4 octets.
  6. Dans la liste "frames", la taille de chaque élément doit être 1024 * 4 octets, par exemple, la taille de frames[0] Doit être 4096 octets. Cependant, sys.getsizeof(frames[0]) renvoie 4133, Mais len(frames[0]) renvoie 4096.
  7. for boucle exécute int(RATE / CHUNK * RECORD_SECONDS) fois, je ne comprends pas pourquoi. Ici est la même question à laquelle répond "Ruben Sanchez" mais je ne peux pas être sûr que ce soit correct comme il le dit CHUNK=bytes. Et selon son explication, ce doit être int(RATE / (CHUNK*2) * RECORD_SECONDS) car (CHUNK*2) Est le nombre d'échantillons lus dans le tampon à chaque itération.
  8. Enfin, quand j'écris print frames[0], Il imprime du charabia en essayant de traiter la chaîne pour qu'elle soit ASCII encodée, ce qu'elle n'est pas, c'est juste un flux d'octets. Alors, comment faire J'imprime ce flux d'octets en hexadécimal en utilisant le module struct? Et si plus tard, je modifie chacune des valeurs hexadécimales avec les valeurs de mon choix, produira-t-il toujours un son jouable?

Tout ce que j'ai écrit ci-dessus était ma compréhension des choses et beaucoup d'entre elles peuvent être erronées.

14
shiva
  1. "TAUX" est le "taux d'échantillonnage", c'est-à-dire le nombre de trames par seconde
  2. "CHUNK" est le nombre (choisi arbitrairement) de trames les signaux (potentiellement très longs) sont divisés en dans cet exemple
  3. Oui, chaque trame aura 2 échantillons comme "CHANNELS = 2", mais le terme "échantillons" est rarement utilisé dans ce contexte (car il prête à confusion)
  4. Oui, la taille de chaque échantillon est de 2 octets (= 16 bits) dans cet exemple
  5. Oui, la taille de chaque trame est de 4 octets
  6. Oui, chaque élément des "trames" doit faire 4096 octets. sys.getsizeof() indique l'espace de stockage requis par l'interpréteur Python, qui est généralement un peu plus que la taille réelle des données brutes.
  7. RATE * RECORD_SECONDS Est le nombre d'images qui doivent être enregistrées. Puisque la boucle for n'est pas répétée pour chaque trame mais uniquement pour chaque bloc , le nombre de boucles doit être divisé par la taille du bloc CHUNK. Cela n'a rien à voir avec les échantillons , donc il n'y a aucun facteur de 2 Impliqué.
  8. Si vous voulez vraiment voir les valeurs hexadécimales, vous pouvez essayer quelque chose comme [hex(x) for x in frames[0]]. Si vous voulez obtenir les nombres réels sur 2 octets, utilisez la chaîne de format '<H' Avec le module struct.

Vous pourriez être intéressé par mon tutoriel sur la lecture de fichiers WAV avec le module wave, qui couvre certaines de vos questions plus en détail: http://nbviewer.jupyter.org/github/mgeier/python -audio/blob/master/audio-files/audio-files-with-wave.ipynb

20
Matthias