J'aime penser à la manière dont tout peut être représenté par des chiffres. Par exemple, le texte en clair est représenté par un code tel que ASCII et les images par des valeurs RVB. Ce sont les moyens les plus simples de représenter du texte et des images.
Quelle est la manière la plus simple de représenter l'audio avec des nombres? Je veux apprendre à écrire des programmes qui fonctionnent avec de l'audio et j'ai pensé que ce serait une bonne façon de commencer. Je n'arrive pas à trouver de bonnes explications sur Internet, cependant.
Physiquement, comme vous le savez probablement, l'audio est une vibration. En règle générale, nous parlons de vibrations de l'air comprises entre environ 20Hz et 20 000Hz. Cela signifie que l'air se déplace 20 à 20 000 fois par seconde.
Si vous mesurez cette vibration et la convertissez en un signal électrique (par exemple, à l'aide d'un microphone), vous obtiendrez un signal électrique dont la tension variera dans la même forme d'onde que le son. Dans notre hypothèse pure-ton, cette forme d'onde correspondra à celle de la fonction sinus.
Maintenant, nous avons un signal analogique, la tension. Toujours pas numérique. Mais nous savons que cette tension varie entre (par exemple) -1V et + 1V. Nous pouvons, bien sûr, attacher un voltmètre aux fils et lire la tension.
Arbitrairement, nous allons changer l'échelle sur notre voltmètre. Nous allons multiplier les volts par 32767. Il appelle maintenant -1V -32767 et + 1V 32767 . Oh, et ça va arrondir à l'entier le plus proche.
Nous connectons maintenant notre voltmètre à un ordinateur et lui demandons de lire le compteur 44 100 fois par seconde. Ajoutez un deuxième voltmètre (pour l’autre canal stéréo) et nous avons maintenant les données stockées sur un CD audio.
Ce format est appelé stéréo 44,100 Hz, 16 bits PCM linéaire . Et ce n’est vraiment que quelques mesures de tension.
L'audio peut être représenté par des échantillons numériques. Essentiellement, un échantillonneur (également appelé convertisseur analogique-numérique) saisit une valeur d'un signal audio tous les 1/fs, où fs est la fréquence d'échantillonnage. L’ADC quantifie ensuite le signal, ce qui constitue une opération d’arrondi. Ainsi, si votre signal est compris entre 0 et 3 volts (gamme complète), un échantillon sera arrondi à, par exemple un nombre de 16 bits. Dans cet exemple, un nombre de 16 bits est enregistré une fois tous les 1/fs /
Ainsi, par exemple, la plupart des fichiers WAV/MP3 reçoivent un signal audio échantillonné à 44 kHz. Je ne sais pas à quel point vous voulez des détails, mais il existe un truc appelé "taux d'échantillonnage de Nyquist" qui dit que la fréquence d'échantillonnage doit être au moins deux fois supérieure à la fréquence souhaitée. Ainsi, sur votre fichier WAV/MP3, vous pourrez au mieux entendre jusqu'à 22 kHz.
Vous pouvez entrer beaucoup de détails dans ce domaine. La forme la plus simple serait certainement le format WAV. C'est de l'audio non compressé. Les formats tels que mp3 et ogg doivent être décompressés avant de pouvoir les utiliser.
Exemple de génération audio en C minimal
L'exemple ci-dessous génère un sinus pur à 1 000 kHz au format brut. À un taux d'échantillonnage de 44,1 kHz, il durera 4 secondes.
principal c:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void) {
FILE *f;
const double PI2 = 2 * acos(-1.0);
const double SAMPLE_FREQ = 44100;
const unsigned int NSAMPLES = 4 * SAMPLE_FREQ;
uint16_t ampl;
uint8_t bytes[2];
unsigned int t;
f = fopen("out.raw", "wb");
for (t = 0; t < NSAMPLES; ++t) {
ampl = UINT16_MAX * 0.5 * (1.0 + sin(PI2 * t * 1000.0 / SAMPLE_FREQ));
bytes[0] = ampl >> 8;
bytes[1] = ampl & 0xFF;
fwrite(bytes, 2, sizeof(uint8_t), f);
}
fclose(f);
return EXIT_SUCCESS;
}
Générer out.raw
:
gcc -std=c99 -o main main.c -lm
./main
Jouez out.raw
directement:
Sudo apt-get install ffmpeg
ffplay -autoexit -f u16be -ar 44100 -ac 1 out.raw
ou convertir en un format audio plus commun, puis jouer avec un lecteur audio plus commun:
ffmpeg -f u16be -ar 44100 -ac 1 -i out.raw out.flac
vlc out.flac
Paramètres expliqués sur: https://superuser.com/a/1063230/128124
Voici un synthé Canon en D plus intéressant: Synthétiser par programmation une programmation musicale?
Testé sur Ubuntu 18.04. GitHub en amont .
Physique
L'audio est codé sous la forme d'un numéro unique pour chaque instant. Comparez cela à une vidéo, qui a besoin des chiffres WIDTH * HEIGHT par moment.
Ce nombre est ensuite converti en déplacement linéaire du diaphragme de votre enceinte:
| /
| /
|-/
| | A I R
|-\
| \
| \
<-> displacement
| /
| /
|---/
| | A I R
|---\
| \
| \
<---> displacement
| /
| /
|-----/
| | A I R
|-----\
| \
| \
<-----> displacement
Le déplacement pousse l'air en avant et en arrière, ce qui crée des différences de pression qui se propagent dans l'air sous forme de ondes P .
Seul le déplacement compte: un signal constant, même maximal, ne produit aucun son: le diaphragme reste dans une position fixe.
La fréquence d'échantillonnage détermine la vitesse à laquelle les déplacements doivent être effectués.
44,1kHz est une fréquence d'échantillonnage courante car les humains peuvent entendre jusqu'à 20 kHz et à cause du théorème d'échantillonnage de Nyquist – Shannon .
La fréquence d'échantillonnage est analogue à la FPS pour la vidéo, bien qu'elle ait une valeur bien supérieure à celle des 25 (cinéma) à 144 (moniteurs de jeu hardcore) que nous voyons couramment pour la vidéo.
Formats
.raw
est un format non spécifié qui contient uniquement les octets d'amplitude et aucune métadonnée.
Nous devons passer quelques paramètres de métadonnées sur la ligne de commande, tels que la fréquence d'échantillonnage, car le format ne contient pas ces données.
Il existe également d'autres formats non compressés contenant toutes les métadonnées nécessaires, par exemple: .wav
, voir: Synthèse de fichiers WAV partir de Scratch - C
Cependant, dans la pratique, la plupart des gens traitent exclusivement avec des formats compressés, ce qui réduit considérablement la taille des fichiers/flux. Certains de ces formats prennent en compte les caractéristiques de l'oreille humaine pour compresser davantage l'audio de manière pénible.
Biologie
Les humains perçoivent le son principalement par décomposition de leur fréquence (AKA transformée de Fourier ).
Je pense que c'est parce que l'oreille interne a des parties qui résonnent à différentes fréquences (confirme TODO).
Par conséquent, lors de la synthèse musicale, nous pensons plus en termes d’addition de fréquences plutôt que de points dans le temps. Ceci est illustré dans cet exemple .
Cela conduit à penser en termes de vecteur 1D compris entre 20Hz et 20kHz pour chaque instant donné.
La transformée mathématique de Fourier perd la notion de temps. Par conséquent, lors de la synthèse, nous prenons des groupes de points, nous résumons les fréquences de ce groupe et y effectuons la transformée de Fourier.
Heureusement, la transformée de Fourier est linéaire, nous pouvons donc additionner et normaliser directement les déplacements.
La taille de chaque groupe de points conduit à un compromis de précision temps-fréquence, basé sur les mêmes mathématiques que principe d'incertitude de Heisenberg .
Ondelettes est peut-être une description mathématique plus précise de cette description temps-fréquence intermédiaire.
Le moyen le plus simple de représenter le son sous forme de nombres est PCM (Pulse Code Modulation). Cela signifie que l'amplitude du son est enregistrée à une fréquence définie (chaque valeur d'amplitude est appelée échantillon). Le son de qualité CD, par exemple, est constitué d’échantillons 16 bits (en stéréo) à la fréquence 44100 Hz.
Un échantillon peut être représenté sous la forme d'un nombre entier (généralement 8, 12, 16, 24 ou 32 bits) ou d'un nombre à virgule flottante (16 bits flottants ou 32 bits doubles). Le numéro peut être signé ou non signé.
Pour les échantillons signés sur 16 bits, la valeur 0 serait au milieu et -32768 et 32767 seraient les amplitudes maximales. Pour les échantillons non signés 16 bits, la valeur 32 768 serait au milieu et 0 et 65 535 seraient les amplitudes maximales.
Pour les échantillons à virgule flottante, le format habituel est que 0 est au milieu et -1.0 et 1.0 sont les amplitudes maximales.
Les données PCM peuvent ensuite être compressées, par exemple à l'aide de MP3.
Je pense que des échantillons de la forme d'onde à une fréquence d'échantillonnage spécifique seraient la représentation la plus élémentaire.
Avez-vous déjà regardé une forme d'onde de près? L'axe des ordonnées est simplement représenté sous forme d'entier, généralement sur 16 bits.
Recherchez des éléments comme la conversion analogique-numérique. Cela devrait vous aider à démarrer. Ces appareils peuvent convertir un signal audio (ondes sinusoïdales) en représentations numériques. Ainsi, un CAN 16 bits serait capable de représenter un sinus compris entre -32768 et 32768. Ceci est en virgule fixe. Il est également possible de le faire en virgule flottante (bien que cela ne soit pas recommandé pour des raisons de performances, mais peut être nécessaire pour des raisons de portée). Le contraire (conversion numérique-analogique) se produit lorsque nous convertissons des nombres en ondes sinusoïdales. Ceci est géré par quelque chose appelé un DAC.
Je pense qu'un bon moyen de commencer à jouer avec l'audio serait avec Processing et Minim . Ce programme dessine le spectre de fréquence du son de votre microphone!
import ddf.minim.*;
import ddf.minim.analysis.*;
AudioInput in;
FFT fft;
void setup()
{
size(1024, 600);
noSmooth();
Minim.start(this);
in = Minim.getLineIn();
fft = new FFT(in.bufferSize(), in.sampleRate());
}
void draw()
{
background(0);
fft.forward(in.mix);
stroke(255);
for(int i = 0; i < fft.specSize(); i++)
line(i*2+1, height, i*2+1, height - fft.getBand(i)*10);
}
void stop()
{
in.close();
Minim.stop();
super.stop();
}
La conversion de l’audio analogue réel en une forme numérique se fait en 2 étapes.
Échantillonnage
Le taux d'échantillonnage d'une forme d'onde continue (dans ce cas, l'audio) est appelé taux d'échantillonnage. La plage de fréquence perçue par l'homme est comprise entre 20 et 20 000 Hz. Cependant, les CD utilisent le théorème d'échantillonnage de Nyquist, qui signifie un taux d'échantillonnage de 44 100 Hz, couvre les fréquences comprises entre 0 et 22 050 Hz.
Quantification
L'ensemble discret de valeurs reçues à partir de la phase d'échantillonnage doit maintenant être converti en un nombre fini de valeurs. Une quantification sur 8 bits fournit 256 valeurs possibles, tandis qu'une quantification sur 16 bits fournit jusqu'à 65 536 valeurs.
Les réponses concernent toutes la fréquence d'échantillonnage, mais ne répondent pas à la question. J'imagine qu'un instantané particulier d'un son inclurait des amplitudes individuelles pour de nombreuses fréquences différentes (disons que vous frappez simultanément un A et un C sur un clavier, le A étant plus fort). Comment cela est-il enregistré dans un nombre de 16 bits? Si vous ne faites que mesurer l’amplitude (quelle est la puissance du son), comment obtenez-vous les différentes notes?
Ah! Je pense que je comprends cela de ce commentaire: "Ce nombre est ensuite converti en déplacement linéaire du diaphragme de votre haut-parleur." Les notes apparaissent à la vitesse à laquelle le diaphragme vibre. C'est pourquoi vous avez besoin de 44 000 valeurs différentes par seconde. Une note est de l'ordre de 1000 hertz, donc une note pure ferait bouger le diaphragme environ 1000 fois par seconde. Un enregistrement de tout un orchestration contient de nombreuses notes différentes, qui peuvent être transformées miraculeusement en une seule histoire du mouvement du diaphragme. 44 000 fois par seconde, le diaphragme a pour instruction d'entrer et de sortir un peu, et cette simple (longue) liste de nombres peut représenter Beyonce à Beethoven!