Esempio minimo C generazione audio
L'esempio seguente genera un puro sinusale 1000K Hz in formato raw. A 44,1 kHz frequenza di campionamento, durerà 4 secondi:
#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 & 8;
fwrite(bytes, 2, sizeof(uint8_t), f);
}
fclose(f);
return EXIT_SUCCESS;
}
Giocare con:
sudo apt-get install ffmpeg
ffplay -autoexit -f u16be -ar 44100 -ac 1 out.raw
Parametri spiegato a: https://superuser.com/a/1063230/128124
testato su Ubuntu 15.10. Più fun examples on GitHub, incluso un semplice sintetizzatore Canon.
Fisica
audio è codificato come numero unico per ogni momento nel tempo. Confrontalo con un video, che richiede un numero di WIDTH * HEIGHT per momento nel tempo.
Questo numero viene poi convertito allo spostamento lineare del diaphragm dell'altoparlante:
| /
|/
|-/
| | A I R
|-\
| \
| \
<-> displacement
| /
| /
|---/
| | A I R
|---\
| \
| \
<---> displacement
| /
| /
|-----/
| | A I R
|-----\
| \
| \
<-----> displacement
Lo spostamento dell'aria spinge avanti e indietro, creando differenze di pressione, che viaggiano attraverso l'aria come P-waves.
Solo lo spostamento ha importanza: un segnale costante, anche se massimale, non produce alcun suono: il diaframma rimane in posizione fissa.
Il sampling frequency determina la velocità con cui devono essere eseguiti gli spostamenti.
44,1kHz è una frequenza di campionamento comune perché gli esseri umani possono udire fino a 20kHz e a causa dello Nyquist–Shannon sampling theorem.
La frequenza di campionamento è analoga a quella dell'FPS per video, sebbene abbia un valore molto più alto rispetto alla gamma 25 (cinema) - 144 (monitor da gioco hardcore) che comunemente vediamo per i video.
Formati
.raw
è un formato underspecified contenente solo i byte di ampiezza, e non metadati.
Dobbiamo passare alcuni parametri di meta-dati sulla riga di comando come la frequenza di campionamento perché il formato non contiene quei dati.
Esistono anche altri formati non compressi che contengono tutti i metadati necessari, ad es. , vedere: WAV File Synthesis From Scratch - C
In pratica, tuttavia, la maggior parte delle persone si occupa esclusivamente di formati compressi, che rendono i file/streaming molto più piccoli. Alcuni di questi formati prendono in considerazione le caratteristiche dell'orecchio umano per comprimere ulteriormente l'audio in modo smorzato.
Biologia
gli esseri umani percepiscono il suono per lo più da loro decomposizione frequenza (AKA Fourier transform).
Penso che questo sia dovuto al fatto che l'orecchio interno ha parti che risuonano a frequenze diverse (conferma TODO).
Pertanto, quando sintetizziamo la musica, pensiamo di più in termini di aggiunta di frequenze anziché di punti nel tempo. Questo è illustrato in this example.
Questo porta a pensare in termini di un vettore 1D tra 20Hz e 20kHz per ogni punto nel tempo.
La trasformata di Fourier matematica perde la nozione di tempo, quindi ciò che facciamo quando si sintetizza è prendere gruppi di punti e sommare le frequenze per quel gruppo e prendere lì la trasformata di Fourier.
Fortunatamente, la trasformata di Fourier è lineare, quindi è possibile sommare e normalizzare direttamente gli spostamenti.
La dimensione di ciascun gruppo di punti porta a un compromesso di precisione in termini di tempo, mediato dalla stessa matematica di Heisenberg's uncertainty principle.
Wavelets può essere una descrizione matematica più precisa di questa descrizione intermedia di tempo/frequenza.
Spiegazione molto bella, grazie! –
Tecnicamente parlando si tratta di una serie di misurazioni di ampiezza. Accade semplicemente che la maggior parte degli ADC usano la tensione per rappresentare l'ampiezza. –
@SteveKuo tecnicamente parlando, è corretto, ma sembra aggiungere che in qualsiasi modo significativo complicherebbe notevolmente la questione. E poiché questo non è un sito di ingegneria elettrica ... – derobert