[英]Collect decoded audio from libav as doubles
我目前正在尝试收集解码的音频数据(来自多种格式)以执行某些音频操作(使用* .wav文件进行测试)。
我有一个通过FFmpeg libav处理所有解码的类。 如果我将数据作为unit8_t提取到向量中,并且
for (int i = 0; i < bytevector.size(); i++) {
fwrite(&bytevector[i], sizeof (uint8_t), 1, outfile2);
}
到原始文件并通过play -t raw -r 44100 -b16 -c 1 -e signed sound.raw
它听起来很不错。
但是,当文件为每个样本2个字节并且frame->data
信息指定为uint8_t时,如何将所有正确的信息加倍? 我测试过的wav文件是44100 / 16bits / 1通道。 (我已经有将uint8_t *更改为double的代码)
使用Scilab打开相同的文件将显示字节向量大小的一半为两倍。
Scilab中的wav文件以双精度数组形式显示:
-0.1,-0.099,-0.098,...,0.099,+ 0.1与字节向量:
51、243、84、243、117、243,...
51和243真的可以构成双倍吗? 关于如何解决这个问题有什么建议吗?
以下代码供参考:
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);
}
将两个字节转换为浮点数的快速方法:
byte bits[] = {195,255}; //first sample in the test s16 wav file
int16_t sample;
memcpy(&sample,&bits,sizeof(bits));
std::cout<<sample*(1.0f/32768.0f)<<std::endl;
打印时(更精确的-0.001861572265625
(xx);),此代码产生-0.001861572265625
,这是Scilab使用相同文件给出的第一个数字。
希望这对遇到类似问题的人有所帮助。
音频数据以许多不同的格式存储。 获得uint8_t[]
数组的意义很小。 不是每个数组一个字节。 相反,您需要知道格式。 这里-b16
告诉我uint8_t[]
数据实际上是16位PCM编码的数据,即从-32768到+32767的范围。 Scilab似乎更喜欢浮点刻度,因此可以除以32768.0。 那只是表象的改变。 只是将比例缩小为-1.0,+ 1.0。
将其与角度进行比较:pi / 2弧度上的直角为90度; 确切的数字无关紧要,但是两者都是一个完整圆的1/4。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.