FAAC源码阅读(2)——AAC的编解码流程

1、AAC(高级音频编码)是一种音频编码标准,常见的开源软件为libfaac

2、ACC的解码过程就是编码的逆操作,流程如下:
     (1)无噪解码(哈夫曼解码,也就是熵解码、Noisless Decoding)
     (2)反量化(Dequantize)
     (3)联合立体声(joint stereo)
     (4)知觉噪声替换(PNS)
     (5)瞬时噪声整形(TNS)
     (6)反离散余弦变换(IMDCT)
     (7)频段复制(SBR)

3、无噪解码(哈夫曼解码)
     (1)无噪编码的目的在于进一步减少尺度因子和量化后频谱的冗余。就是把尺度因子和量化后的频谱信息进哈夫曼编码。全局增益编码成8位的无符号整数,第一个尺度因子与全局增加值进行差分编码后,再使用尺度因子编码表进行哈夫曼编码。后续的尺度因此都与前一个尺度因子进行差分编码。另外,量化频谱的无噪编码有两个频谱系数的划分:①4元组合2元组的划分。确定了一次哈夫曼表,查找出的数值是4个还是2个;②节划分。确定了应该用哪一个哈夫曼表,一届中含有若干的尺度因此带并且每节只使用一个哈夫曼表。
        分节:无噪声编码将输入的1024个量化频谱系数分为几个段(section),段内的各点均使用同一个哈夫曼表,考虑到编码效率,每一段的边界最好同尺度因子带的边界重合。所以每一段必段传送信息应该有:段长度,所在的尺度因子带,使用的哈夫曼表。
        分组:分组是指忽略频谱系数所在窗,将连续的,具有相同尺度因子带的频谱系数分为一组放在一起,共享一个尺度因子从而得到更好的编码效率。这样做必然会引起交替,即本来是以c[组][窗][尺度因子带][系数索引]为顺序的系数排列,变为将尺度因子带同的系数放在一起:c[组][尺度因子带][窗][系数索引]。这样就引起了相同窗的系数的交替。
        大量化值的处理:大量化值在AAC中有两种处理方法:在哈夫曼编码表中使用escape标志或使用脉冲escape方法。前者跟mp3编码方法相似,在许多大量化值出现时采用专门的哈夫曼表,这个表暗示了它的使用将会在哈夫曼编码后面跟跟一对escape值及对值的符号。在用脉冲escape方法时,大数值被减去一个差值变为小数值,然后使用哈夫曼表编码,后面会跟一个脉冲结构来帮助差值的还原.

4、反量化
    在AAC编码中,量化是是通过一个非均匀的量化器来实现的。在频域调整量化噪声的基本方法是用尺度因子来进行噪声整形。尺度因子是一个用来改变在一个尺度因子带的所有频谱系数的振幅增益值,使用尺度因子这种机制是为了使用非均匀量化器在频域中改变量化噪声的比特分配。
    尺度因子带:频率根据人耳的特性被分成多个组,每个组对应若干尺度因子,这些组就叫做尺度因子带,为了减少信息含有短窗的边信息,连续的短窗可能会被分为一组,即将若干短窗当成一个窗口一起传送,然后尺度因子将会作用到所有分组后的窗口去。

5、联合立体声
    联合立体声是对原来的取样进行一定的渲染工作,使声音更好听些

6、知觉噪声替换
    知觉噪声替换是一种以参数编码的方式模拟噪声的方法。在判别出音频值中的噪声后,将噪声不尽兴量化编码,而是采用一些参数告诉解码器端这是某种噪声,然后解码器将会对这些噪声用一些随机的编码来制造出这一类型的噪声
    在具体操作上,PNS模块对每一个尺度因子带侦测频率4kHZ一下的信号成分,如果这个信号既不是音调,在时间上也无抢劫的能量的变动,就被认为是噪声信号,器信号的音调以及能力的变化都在心理声学模型中算出。

7、瞬时噪声整形(TNS)
    这项技术可以通过在频域上的预测,来修整时域上量化噪音的分布。在一些特殊的语言和剧烈变换信号的量化上,TNS技术对音质的提高贡献巨大。
    TNS瞬时噪声整形用于控制一个转换窗口内瞬时噪声形态。它是用一个对单通道的滤波过程来实现的。传统的变换编码方案常常遇到信号在时域变换非常剧烈的问题,特别是语言信号,这个问题是因为量化后的噪声分布虽然在频域上得到控制,但是在时域上却以一个常数分布在一个转换块内。如果这种块中信号变化得很剧烈却又不转向一个短块去,那这个常数分布的噪声将会被听到。
    TNS的原理利用了时域和频域的二元性和LPC(线性预测编码)的时频对称性,即在其中的任意一个域上做编码与在另一个域上做预测编码等效,也就是说,在一个域内做预测编码可以在另一个域内增加其解析度。量化噪声是在频域产生的,降低了时域的解析度,因此需要在频域上做预测编码。

8、反离散余弦变换(IMDCT)
    将音频数据从频域转换到时域的过程主要是由将频域数据填入一组IMDCT滤波器来实现的。在进行IMDCT之后,输出数值经过加窗、叠加、最后得到时域数值。

9、频段复制(SBR)
    音乐的主要频谱集中在低频段,高频段幅度很小,但是很重要,决定了音质。如果对整个频段编码,弱势为了保护高频就会造成低频段编码过细导致文件太大;若是保存了低频的主要成分而丢失高频成分就会丧失音质。SBR把频谱切割开了,低频单独编码保存主要成分,高频单独放大编码保存音质,因此可以在减少文件大小的情况下还保存了音质

10、参数立体声(PS)
    对于立体声来说,其文件大小是单声道的两倍,但是两个声道的声音存在某种相似性,根据香农信息熵编码定力,相关性应该被去掉擦能减少文件大小,所以PS技术存储了一个声道的全部信息,然后用很少的字节当参数来描述另一个声道和它的不同

——以上转载自网络,已经忘记出处
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java是一种广泛应用于软件开发中的编程语言,而FAAC是一款常用的开源编码器,可以将PCM(脉冲编码调制)格式的音频转换成AAC(高级音频编码)格式。下面是一种使用Java和FAAC库进行PCM转AAC的简单示例。 首先,需要在Java项目中引入FAAC库的依赖。可以通过Maven等构建工具来添加FAAC库的依赖项。然后,在Java代码中调用FAAC库提供的方法来实现PCM转AAC的功能。 ```java import com.googlecode.mp4parser.authoring.Sample; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; import java.util.ArrayList; public class PCM2AACConverter { // PCM转AAC的方法 public static void pcmToAac(String inputPath, String outputPath) { try { FileInputStream fis = new FileInputStream(inputPath); FileOutputStream fos = new FileOutputStream(outputPath); int channels = 2; // 音频通道数 int sampleRate = 44100; // 采样率 int bitRate = 128000; // 码率 // 创建FAAC编码器 com.googlecode.mp4parser.authoring.Sample sample = new com.googlecode.mp4parser.authoring.Sample(); sample.begin(channels, sampleRate, bitRate); byte[] data = new byte[1024]; int bytesRead = 0; while ((bytesRead = fis.read(data)) > 0) { // 将PCM数据转换成short类型的数组 ShortBuffer shortBuffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); short[] pcmData = new short[shortBuffer.remaining()]; shortBuffer.get(pcmData); // 将PCM数据添加到FAAC编码器 sample.add(pcmData); } // 完成PCM数据添加操作 sample.end(); // 获取AAC编码后的数据 ArrayList<byte[]> aacData = sample.getAACData(); // 将AAC数据写入输出文件 for (byte[] aacFrame : aacData) { fos.write(aacFrame); } fis.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String inputPath = "input.pcm"; // 输入PCM文件的路径 String outputPath = "output.aac"; // 输出AAC文件的路径 pcmToAac(inputPath, outputPath); } } ``` 上述代码使用了FAAC库提供的`Sample`类来进行PCM转AAC操作。通过`pcmToAac`方法,将输入的PCM文件转换成AAC格式并输出到指定路径。在此过程中,需要指定音频的通道数、采样率和码率等参数。 要使用上述方法,首先需要确保Java项目已经引入FAAC库的依赖,同时将输入的PCM文件和输出的AAC文件放置在正确的路径下。 以上是一个简单的示例,仅供参考。实际应用中,可能需要根据具体需求对代码进行修改和优化。 ### 回答2: Java FAAC PCM转AAC可以通过使用FAAC库和Java编程语言来实现。以下是一个简单的示例代码来演示如何使用Java FAAC库将PCM音频文件转换为AAC格式: ```java import com.googlecode.faac.Faac; import com.googlecode.faac.FaacConfig; import com.googlecode.faac.FaacConfigParams; import com.googlecode.faac.FaacInstance; public class PCMtoAACConverter { public static void main(String[] args) { String pcmFile = "input.pcm"; String aacFile = "output.aac"; // 初始化FAAC库 Faac faac = Faac.getInstance(); // 创建FAAC实例 FaacInstance faacInstance = faac.faacEncOpenDefault(48000, 2); // 设置FAAC配置参数 FaacConfig faacConfig = faac.faacEncGetCurrentConfiguration(faacInstance); FaacConfigParams configParams = new FaacConfigParams(); configParams.setBitrate(128000); configParams.setInputFormat(Faac.FAAC_INPUT_FORMAT_16BIT); faacConfig.setParams(configParams); faac.faacEncSetConfiguration(faacInstance, faacConfig); // 打开PCM文件和AAC文件 faac.faacEncOpenFile(faacInstance, pcmFile, aacFile); // 开始转换 faac.faacEncEncode(faacInstance); // 关闭文件和FAAC实例 faac.faacEncClose(faacInstance); faac.faacEncCloseFile(faacInstance); System.out.println("PCM转AAC完成!"); } } ``` 上述代码示例使用了FAAC库提供的相关函数来实现PCM文件转换为AAC文件的功能。其中,需先准备好待转换的PCM音频文件和指定的输出AAC文件路径。代码中的配置参数可根据需求进行调整,例如比特率、通道数等。 需要注意的是,使用FAAC库需要先下载并导入合适的FAAC库文件到项目中,并进行相关的配置。此外,FAAC库是一个开源的第三方库,使用时需了解其许可证限制和相关文档。 ### 回答3: 要使用Java将PCM音频文件转换为AAC格式,可以使用FAAC库。FAAC是一个用于将音频文件编码AAC格式的开源库。 首先,需要确保已经下载并安装了FAAC库。然后,可以在Java项目中使用JNI(Java Native Interface)来调用FAAC库的功能。 在Java中使用JNI调用FAAC库时,可以使用JNIWrapper库。这个库提供了一种方便的方式来与C/C++代码进行交互。 首先,需要编写一个调用FAAC的Java类。在这个类中,可以使用JNIWrapper库提供的函数来加载FAAC库和调用它的函数。可以编写一个Java方法来将PCM文件转换为AAC文件。 示例代码如下: ```java import com.jniwrapper.*; import com.jniwrapper.win32.jni.*; import com.jniwrapper.util.*; public class FaacConverter { private static final String LIBRARY_NAME = "your_FAAC_library_name"; static { NativeLibraryLoader.loadLibrary(LIBRARY_NAME); } public static native int convertPcmToAac(String pcmFilePath, String aacFilePath); public static void main(String[] args) { String pcmFilePath = "/path/to/pcm/file.pcm"; String aacFilePath = "/path/to/aac/file.aac"; int result = convertPcmToAac(pcmFilePath, aacFilePath); if (result == 0) { System.out.println("PCM file converted to AAC successfully."); } else { System.out.println("Failed to convert PCM file to AAC."); } } } ``` 要使用这个示例代码,需要将FAAC库文件与Java项目一起编译,并将LIBRARY_NAME变量设置为FAAC库的名称。 编写完Java类后,可以使用Java编译器将其编译为可执行的Java程序。 然后,可以通过运行这个程序来将PCM文件转换为AAC文件。在main方法中,可以设置PCM文件的路径和要生成的AAC文件的路径。 运行这个程序后,如果转换成功,将会在控制台打印出"PCM file converted to AAC successfully."的消息,否则将会打印出"Failed to convert PCM file to AAC."的消息。 这就是使用Java将PCM音频文件转换为AAC格式的基本步骤。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值