Python >> Tutoriel Python >  >> Python

Comment visualiser le son en Python

Il existe de nombreuses données musicales et vocales. Il existe également des applications intéressantes pour les accompagner. Nous vous montrons comment visualiser le son en Python.

L'analyse des données audio est devenue de plus en plus pertinente ces derniers temps. Des produits d'assistant virtuel populaires ont été lancés par de grandes entreprises technologiques, et ces produits sont de plus en plus courants dans les smartphones et les foyers du monde entier. Ils sont largement développés sur des modèles qui analysent les données vocales et en extraient des informations.

Il existe une large gamme d'applications utilisant l'analyse de données audio, et c'est un sujet riche à explorer. Dans cet article, nous allons nous concentrer sur une partie fondamentale du processus d'analyse des données audio :tracer la forme d'onde et le spectre de fréquences du fichier audio.

Cet article s'adresse aux personnes ayant un peu plus d'expérience dans l'analyse de données. Si vous êtes débutant et que vous recherchez du matériel pour vous familiariser avec la science des données, jetez un œil à cette piste.

Ouvrir un fichier WAV

Les fichiers audio sont disponibles dans une variété de formats. Vous connaissez probablement le MP3, qui utilise une compression avec perte pour stocker des données. Des formats tels que FLAC utilisent une compression sans perte, ce qui permet de reconstruire parfaitement les données d'origine à partir des données compressées. Notre fichier audio est au format WAV (Waveform Audio File), qui n'est pas compressé. La taille des fichiers peut donc devenir importante.

Le fichier sonore que nous allons examiner est un jingle optimiste qui commence par un piano. D'autres sons comme des cloches et des applaudissements entrent tout au long du jingle, avec une partie de guitare grattante à deux points de la piste. Il convient de mentionner ces caractéristiques dans l'enregistrement audio, car nous pourrons en identifier certaines plus tard lorsque nous traçons la forme d'onde et le spectre de fréquences.

Pour ouvrir notre fichier WAV, nous utilisons le module wave en Python, qui peut être importé et appelé comme suit :

>>> import wave
>>> wav_obj = wave.open('file.wav', 'rb')

Le 'rb ' le mode renvoie un wave_read objet. Utilisation de 'wb ' pour ouvrir le fichier renvoie un wave_write objet, qui a des méthodes différentes de l'ancien objet. Vous pouvez également utiliser un with déclaration pour ouvrir le fichier comme nous le démontrons ici. Si vous souhaitez en savoir plus sur la gestion par programmation d'un grand nombre de fichiers, consultez cet article.

Une onde sonore est une quantité continue qui doit être échantillonnée à un certain intervalle de temps pour la numériser. Le taux d'échantillonnage quantifie le nombre d'échantillons du son pris chaque seconde. Nous pouvons accéder à ces informations en utilisant la méthode suivante :

>>> sample_freq = wav_obj.getframerate()
>>> sample_freq
44100

La fréquence d'échantillonnage quantifie le nombre d'échantillons par seconde. Dans ce cas, c'est 44 100 fois par seconde, ce qui correspond à la qualité CD. Le nombre d'images individuelles, ou d'échantillons, est donné par :

>>> n_samples = wav_obj.getnframes()
>>> n_samples
5384326

Nous pouvons maintenant calculer la durée de notre fichier audio en secondes :

>>> t_audio = n_samples/sample_freq
>>> t_audio
122.09356009070295

Le fichier audio est enregistré en stéréo, c'est-à-dire sur deux canaux audio indépendants. Cela donne l'impression que le son provient de deux directions différentes. Nous pouvons vérifier le nombre de canaux comme suit :

>>> n_channels = wav_obj.getnchannels()
>>> n_channels
2

L'étape suivante consiste à obtenir les valeurs du signal, c'est-à-dire l'amplitude de l'onde à ce moment précis. Pour ce faire, nous pouvons utiliser le readframes() méthode, qui prend un argument, n, définissant le nombre de trames à lire :

>>> signal_wave = wav_obj.readframes(n_samples)

Cette méthode renvoie un objet bytes. Vérifiez par vous-même en utilisant le type() fonction intégrée sur le signal_wave objet. Pour obtenir des valeurs de signal à partir de cela, nous devons nous tourner vers numpy :

>>> import numpy as np
>>> signal_array = np.frombuffer(signal_wave, dtype=np.int16)

Cela renvoie toutes les données des deux canaux sous la forme d'un tableau à une dimension. Si vous vérifiez la forme de signal_array , vous remarquez qu'il contient 10 768 652 éléments, soit exactement n_samples * n_channels . Pour diviser les données en canaux individuels, nous pouvons utiliser une petite astuce astucieuse :

>>> l_channel = signal_array[0::2]
>>> r_channel = signal_array[1::2]

Maintenant, nos canaux gauche et droit sont séparés, contenant tous deux 5 384 326 nombres entiers représentant l'amplitude du signal.

Ensuite, nous montrons quelques exemples de la façon de tracer les valeurs du signal. Ici, nos données sont stockées dans des tableaux, mais pour de nombreuses applications de science des données, les pandas sont très utiles. Consultez cet article sur la visualisation des données stockées dans un DataFrame .

Tracé de l'amplitude du signal

Avant de tracer les valeurs du signal, nous devons calculer l'heure à laquelle chaque échantillon est prélevé. Il s'agit simplement de la longueur totale de la piste en secondes, divisée par le nombre d'échantillons. Nous pouvons utiliser linspace() à partir de numpy pour créer un tableau d'horodatage :

>>> times = np.linspace(0, n_samples/sample_freq, num=n_samples)

Pour le tracé, nous allons utiliser le pyplot classe de matplotlib . Si vous avez besoin de matériel de base sur le traçage en Python, nous avons quelques articles. Voici la partie 1 et la partie 2 d'une introduction à matplotlib .

Pour plus de simplicité, nous ne traçons que le signal d'un canal. Configurons la figure et traçons une série chronologique comme suit :

>>> import matplotlib.pyplot as plt
>>> plt.figure(figsize=(15, 5))
>>> plt.plot(times, l_channel)
>>> plt.title('Left Channel')
>>> plt.ylabel('Signal Value')
>>> plt.xlabel('Time (s)')
>>> plt.xlim(0, t_audio)
>>> plt.show()

Cela ouvre la figure suivante dans une nouvelle fenêtre :

Nous voyons l'amplitude s'accumuler dans les 6 premières secondes, moment auquel les cloches et les effets d'applaudissements commencent. Il y a deux brèves pauses dans le jingle à 31,5 et 44,5 secondes, qui sont évidentes dans les valeurs du signal. Après la deuxième pause, l'instrument principal alterne entre une guitare et un piano, ce qui se voit à peu près dans le signal, où la partie de guitare a des amplitudes plus faibles. Ensuite, il y a une sortie de moindre amplitude à la fin du morceau.

Tracé du spectre de fréquences

Examinons maintenant le spectre de fréquences, également appelé spectrogramme. Il s'agit d'une représentation visuelle de la force du signal à différentes fréquences, nous montrant quelles fréquences dominent l'enregistrement en fonction du temps :

>>> plt.figure(figsize=(15, 5))
>>> plt.specgram(l_channel, Fs=sample_freq, vmin=-20, vmax=50)
>>> plt.title('Left Channel')
>>> plt.ylabel('Frequency (Hz)')
>>> plt.xlabel('Time (s)')
>>> plt.xlim(0, t_audio)
>>> plt.colorbar()
>>> plt.show()

Le tracé suivant s'ouvre dans une nouvelle fenêtre :

Dans le code de traçage ci-dessus, vmin et vmax sont choisis pour faire ressortir les basses fréquences qui dominent cet enregistrement. En effet, les fréquences dominantes pour l'ensemble de la piste sont inférieures à 2,5 kHz. Vous voyez l'effet de différents instruments et effets sonores, en particulier dans la gamme de fréquences d'environ 10 kHz à 15 kHz. Chaque instrument et effet sonore a sa propre signature dans le spectre de fréquences.

Où aller à partir d'ici

Le traçage de la forme d'onde et du spectre de fréquences avec Python constitue une base pour une analyse plus approfondie des données sonores. Peut-être pouvez-vous quantifier davantage les fréquences de chaque partie de l'enregistrement. Quelle est la fréquence moyenne de la partie guitare par rapport à la partie piano ? Et ici, nous n'avons regardé qu'un seul canal. Une autre extension du matériel ici consiste à tracer les deux canaux et à voir comment ils se comparent. Essayez de tracer la différence entre les canaux et vous verrez de nouvelles fonctionnalités intéressantes ressortir de la forme d'onde et du spectre de fréquences.