利用faac编码int32以及float原始音频数据

之前音频采集使用16位双声道(都快过去10年了)。利用faac编码没什么问题,现在心血来潮,想用更高级的32位,float进行采样,本以为依葫芦画瓢就行,没想到完全不行。这里看了源码,才知道怎么用,
避免之后的同胞入坑
demo见https://gitcode.net/bener2008zj/MediaDemo/-/tree/master/faacdemo

源码main.c中所有的采样都转化为float格式,跟WAV中读取的无关

 myFormat->inputFormat = FAAC_INPUT_FLOAT;

读取函数可看input.c中,不管WAV原来是什么读取都为float,关键WAV是本身就是float还是要重新处理下

size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map)
......
 if (sndf->isfloat)
      {
          switch (sndf->samplebytes) {
          case 4:
              buf[cnt] *= 32768.0;
              break;
          default:
              return 0;
          }
          continue;
      }

修改方案
判断采样类型

	if(waveFormat.wFormatTag==3){
		pFaacConf->inputFormat=FAAC_INPUT_FLOAT;	
	}else{
		if(waveFormat.wBitsPerSample==16){
			pFaacConf->inputFormat=FAAC_INPUT_16BIT;
		}else{
			pFaacConf->inputFormat=FAAC_INPUT_32BIT;
		}
	}

处理采样数据

        inputSamples=RealInputBytes/(waveFormat.wBitsPerSample/8);
		if(waveFormat.wFormatTag==1&&waveFormat.wBitsPerSample==32){
			int i=0;
			int32_t*in=(int32_t*)inputbuffer;
			for(i=0;i<inputSamples;i++){
				in[i]/=256;
				//库函数还会/256,最后等价于16位
			}
		}	
		if(waveFormat.wFormatTag==3){
			int i=0;
			float *buf=(float*)inputbuffer;
			for(i=0;i<inputSamples;i++){
				buf[i]*=32768.0;
			}
		}

各版本可能会有不同,当前看的版本为faac-1.29.9.2
主要看frame.c文件就行
在函数faacEncSetConfiguration中有这样的判断

switch( hEncoder->config.inputFormat )
    {
        case FAAC_INPUT_16BIT:
        //case FAAC_INPUT_24BIT:
        case FAAC_INPUT_32BIT:
        case FAAC_INPUT_FLOAT:
            break;

        default:
            return 0;
            break;
    }

    if (hEncoder->config.aacObjectType != LOW)
        return 0;

意味着只支持3种输入格式,24位的不支持
并且aacObjectType只能用LOW(以前用的旧版本没有这个限制)

输入格式FAAC_INPUT_16BIT是支持的,不用二次处理
输入格式FAAC_INPUT_FLOAT需要二次处理
输入格式FAAC_INPUT_32BIT也需要二次处理
faacEncEncode中有如下代码

 switch( hEncoder->config.inputFormat )
			{
                case FAAC_INPUT_16BIT:
					{
						short *input_channel = (short*)inputBuffer + hEncoder->config.channel_map[channel];

						for (i = 0; i < samples_per_channel; i++)
						{
							hEncoder->next3SampleBuff[channel][i] = (double)*input_channel;
							input_channel += numChannels;
						}
					}
                    break;

                case FAAC_INPUT_32BIT:
					{
						int32_t *input_channel = (int32_t*)inputBuffer + hEncoder->config.channel_map[channel];
						
						for (i = 0; i < samples_per_channel; i++)
						{
							hEncoder->next3SampleBuff[channel][i] = (1.0/256) * (double)*input_channel;
							input_channel += numChannels;
						}
					}
                    break;

                case FAAC_INPUT_FLOAT:
					{
						float *input_channel = (float*)inputBuffer + hEncoder->config.channel_map[channel];

						for (i = 0; i < samples_per_channel; i++)
						{
							hEncoder->next3SampleBuff[channel][i] = (double)*input_channel;
							input_channel += numChannels;
						}
					}
                    break;

                default:
                    return -1; /* invalid input format */
                    break;
            }

int32之前已经除以了一次256(不这样得到的声音不对),库自身又除以256,相当于将32位减少到16位(源码不索性直接除65536得了,float也完全可以内部处理,不需要我们预处理,毕竟开源,只能睁只眼闭只眼)

总结:
float肯定是要二次处理的,
int32也需要二次处理,内部还要再处理,相当于就是使用int16
直接使用int16效率是最高的,其它2个最终也等价于int16,并不会有实质性的效果提升
真的需要高标准就都有专业的设备采集,自带接口支持硬编码,如果再用软编码这效率效果就低了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值