Perché, mentre il buffer è espresso in
Short (ossia nel tipo di dati che occupa 2 Byte, cioè 16-bit), il 3° parametro della funzione esterna di Alsa,
snd_pcm_readi( ), è di tipo nativo-ALSA, ossia "
snd_pcm_uframes_t", che rappresenta la quantità di
frames letti o scritti.
Vedi al riguardo:
http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gab01fcfe9b97382a8d3f2027c664b8b8aRiprendendo l'immagine da te proposta, e leggendo le seguenti righe:
"
For 16 bit per channel stereo data, one ALSA frame has a length of four bytes (32 bits). "
presenti in questa pagina:
http://nairobi-embedded.org/alsa_terminology.html#alsa-frames-and-periodsrisulta che, essendo un "
frame" composto da due campioni per ciascun canale, Destra/Sinistra, si ha che (1 campione/canale/destro * Sizeof(gb.Short) byte) + (1 campione/canale/sinistro * SizeOf(gb.Short) byte) =
4 byte (32 bit).
Va da sé, dunque, che il valore attribuito per instanziare l'array di tipo Short, ossia il buffer contenente i dati audio, non assume il medesimo valore in byte di memoria occupati, se è posto al 3° parametro.
Infatti se - ad esempio - instanziamo un buffer_audio_dati come array di tipo
Short con 1024 elementi, occupiamo in totale 1024 * 2 byte di memoria (
rectius: 1024 * SizeOf(gb.Short) byte).
Se andassimo a porre il medesimo valore 1024 all'interno del 3° parametro della funzione esterna di Alsa,
snd_pcm_readi( ), esso verrà così interpretato:
1024 frames = 1024 * (2 byte + 2 byte)......... che è appunto il doppio dell'array.
Questo accade, lo ripeto per chiarezza, perché:
1 campione_audio_L_o_R = 1 * SizeOf(gb.Short) =
16 bit
1 frames_audio_ALSA = 1 * (1_campione_audio_destra + 1_campione_audio_sinistra) =
32 bit
In pratica come si vede anche nell'immagine da te proposta, 1 frame contiene 2 campioni audio (1 del canale destro e 1 del canale sinistro):
|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro|16-bit destro| 16-bit sinistro| etc............ (interleaved)
[ Frame ][ Frame ][ Frame ][ Frame ][ etc............
Quindi il nostro amico deve dividere per 2 per rendere omogenei i byte di memoria occupati definiti nel 2° parametro con i byte di memoria occupati definiti nel 3° parametro:
(1_campione_audio_destra + 1_campione_audio_sinistra) / 2 = 16 = SizeOf(gb.Short)