J'essaie actuellement de recueillir des données audio décodées (à partir de plusieurs formats) pour effectuer certaines manipulations audio (en utilisant un fichier * .wav pour les tests).Recueillir l'audio décodé de libav en double
J'ai une classe qui gère tout le décodage via FFmpeg libav. Si j'extraire les données comme unit8_t dans un vecteur, et
for (int i = 0; i < bytevector.size(); i++) {
fwrite(&bytevector[i], sizeof (uint8_t), 1, outfile2);
}
à un fichier brut et jouer via play -t raw -r 44100 -b16 -c 1 -e signed sound.raw
ça sonne parfaitement bien.
Cependant, comment est-il possible d'avoir toutes les informations correctes en double lorsque le fichier est par exemple 2 octets par échantillon et que uint8_t reçoit des informations frame->data
? Les fichiers wav que j'ai testés sont 44100/16bits/1 canal. (J'ai déjà un code qui va changer uint8_t * en un double)
Ouvrir les mêmes fichiers avec Scilab montrera la moitié de la taille du vecteur d'octets en double.
fichier wav dans Scilab comme un tableau de doubles montre:
-0,1, -0,099, -0,098, ..., 0,099, +0,1par rapport octet vecteur:
51, 243, 84, 243, 117, 243, ...
Can 51 et 243 forment-ils réellement un double? Des suggestions sur la façon de surmonter ce problème?
code ci-dessous pour référence:
while ((av_read_frame(formatContext, &readingPacket)) == 0) {
if (readingPacket.stream_index == audioStreamIdx) {
AVPacket decodingPacket = readingPacket;
while (decodingPacket.size > 0) {
int gotFrame = 0;
int result = avcodec_decode_audio4(context, frame, &gotFrame, &decodingPacket);
if (result < 0) {
break;
}
decoded = FFMIN(result, decodingPacket.size);
if (gotFrame) {
data_size = (av_get_bytes_per_sample(context->sample_fmt));
if (data_size < 0) {
}
// Only for 1 channel temporarily
for (int i = 0; i < frame->nb_samples; i++) {
for (int ch = 0; ch < context->channels; ch++) {
for (int j = 0; j < data_size; j++) {
bytevector.push_back(*(frame->data[ch] + data_size * i + j));
}
}
}
} else {
decodingPacket.size = 0;
decodingPacket.data = NULL;
}
decodingPacket.size -= result;
decodingPacket.data += result;
}
}
av_free_packet(&readingPacket);
}
'double'? C'est probablement 52 bits de précision, 11 bits de gamme dynamique ou 6000 dB. C'est fou. Et '-b16' dans votre ligne de commande signifie 16 bits, ** pas ** 8 bits. – MSalters
Double est définitivement exagéré pour ce qui est fait à l'audio. J'ai été découragé par le fait que Scilab affiche les valeurs en "double" lorsque le tableau est ouvert dans la visionneuse. Mais oui, ci-dessous est la réponse sur la façon de représenter les données de deux uint8_t (ou 2 octets) de la même manière que Scilab (allant de -1.0 à +1.0). Merci. – gapc
@MSalters - les applications DAW les plus décentes utilisent un traitement interne 64 bits, de cette façon vous perdez moins de précision, même si vous continuez à produire un master 24 bits. – dtech