Foobar2000 PCM到DSD实时转换软件设置、音质体验与工作原理 [赵宇为],下面一起来看看本站小编Soomal音频影像给大家精心整理的答案,希望对您有帮助
Pcm调制心得体会1无论是随身听播放器还是USB接口的DAC产品,对DSD音频的支持在这一年多里变得越来越普及,而从2011年10月得益于PS3的破解,SACD Rip内容流出至今已经过去了近五年,索尼以默许甚至鼓励的态度来推广这些明明是盗版的SACD的录音制品,支持DSD播放的硬件设备也越来越多,甚至可以说达到了普及的程度。DSD是否带来了更好的音质?可否将所有的PCM音乐全部转换成DSD?这么做是否可以有音质提升?这些答案都是肯定的。而本文主要来讲解如何通过Foobar2000设置,让所有的PCM音乐,包括16bit/44.1kHz或者高清的24bit/96kHz的音乐,都让USB DAC以DSD的形式播放。并且会谈到简单的工作原理。
需要使用的工具与功能
Foobar2000播放DSD应该使用的工具
原本,我们打算先写一篇在Windows10下设置播放DSD的文章,因为在最近测试各种USB声卡时在Windows ASIO下确实遇到了一些问题。如今在Foobar2000下播放DSD和2012年时写的文章内容其实有了一点点变化。虽然工具还是那几个,但版本升级带来了实用方法和界面上的区别。我们在谈到PCM到DSD转换之前,先来简单说明一下这几款工具现在的版本和变化。
首先,整个测试基于Foobar2000的较新版本1.3.10正式版,要在USB模式下播放DSD的音乐,当然需要安装用来识别常见SACD Rip封装文件的插件。在Foobar2000中,这个插件叫做foo_input_sacd版本是0.8.4。同时,USB声卡需要以ASIO的通道来传输数据,需要安装Foobar2000的ASIO插件,目前的版本是2013年的一次更新为2.1.2.由于以上两个小插件的更新,其实如果只是播放DSD,已经不需要安装ASIO Proxy这个插件了。下文我们会谈到。
但是要玩PCM到DSD的实时转换,或者希望切换DSD的工作模式是Native还是DoP,还是需要安装ASIO Proxy,这里推荐安装最新版本0.9.2,这是一个在2016年8月刚刚更新的版本。这个版本其实就解决了0.8.x版本在Windows10下运行不稳定,设置窗口经常无法弹出的问题。
至此,都安装上了最新版本的ASIO插件、SACD插件和ASIO Proxy插件后,Windows10下的Foobar2000播放DSD应该是没有任何问题的。下面我们来聊聊ASIO Proxy这个插件的强大功能。
ASIO Proxy插件的功能
ASIO Proxy插件的名字有点奇怪,听起来以为是给声卡的ASIO做一个设置的代理,但从功能上来说它其实是一个DSD到ASIO的通道管理器。在0.7.x的时代,我们虽然安装了Foobar2000的ASIO插件,但在播放设备中还不能如图下红框内直接看到DSD ASIO播放设备[这是新版插件的功能,2012年-2013年还不可以]。所以,我们必须要安装ASIO Proxy,在里面设置需要用于DSD输出的ASIO声卡设备。而现在已经不需要了。
Foobar2000 DSD播放设置-ASIO/DSD插件下直接可以选择播放设备
那么ASIO Proxy有什么功能呢?在0.7的早期版本,ASIO Proxy除了选择管理声卡ASIO设备外,还可以选择这个设备工作的模式。当年DoP1.0的规范刚刚出现。而现在还有了DoP的1.1规范,DSD ASIO Native规范等等。而在之后某个版本,ASIO Proxy开始加入了DSD to DSD、PCM to DSD的转换功能。至少这在0.8版本中已经出现,这个时间应该已经有两年多了……但我们忽略了这个强大的功能一直没有使用。直到前几个月,Mac上的Audirvana播放器升级,说支持SDM转换了,研究了一下才明白,原来这就是PCM到DSD的实时转换器。也就是说,我们平时使用的PCM规格的音乐,通过ASIO Proxy,经过简单的设置是可以全部以DSD的方式输出播放的。也就是说16bit/44.1kHz的音乐也可以以DSD64或者DSD128格式播放,可是这有意义啊?我们接下来说说它的简单原理。
PCM转DSD音质为什么会更好?
跳过或减少Delta-Sigma DAC的多比特多阶调制器
Delta-Sigma ADC和DAC工作流程图
图片转载自DSD-Guide
如图所示,这是转载自DSDGudie[dsd-guide.com]的一张Delta-Sigma ADC和DAC的工作流程图。我们先来看DAC部分,即后面那个橙色方块的流程。Delta-Sigma是A/D和D/A的一套独特的方法,大概从上世纪80年代起即进入了这一类DAC独当一面的时代,有兴趣可以来看看这个帖子[BBS]Link=00011176[/BBS]。我们目前使用的DAC芯片,全部为这一类DAC。Delta-Sigma的实现方法很难用一个通俗易懂的例子来讲解,目前来看只能用数学的方法来描述,这里先不做讲解。
但从音响发烧友的角度,用发烧友常用的词汇来谈谈Delta-Sigma DAC和我们常见的一些玩法和说法。首先,如上图可以看到它将这个模块标注为Oversampling DAC,即这种类型的DAC是要做升频的。因为44.1kHz的采样率相对较低,而低通滤波又不可能像数字上看到的那么理想,所以必须要把噪声推到更高的频率段。所以,Delta-Sigma DAC要做多阶的调制,对PCM规格的信号进行升频,并且做1bit化的输出。这个过程一般习惯称之为SDM即Sigma-Delta Module.所以,任何Delta-Sigma DAC都具有解码DSD的能力。老产品不支持DSD解码,是因为在设计上的数字通道没有留下硬件上的接口,而不是DAC的问题。
将PCM转换为DSD 1bit输出其实并非SACD之后的专利和产物,从历史角度来说,SACD还应该是从Delta-Sigma DAC上获得了灵感而彻底优化后的产物。我们知道,在80年代很多CD机有1bit的解码技术,例如知名的飞利浦DAC7[这不是一颗芯片],而是TDA1547 DAC和SAA7350芯片的组合。因为设计师看不上TDA1547内的SDM,而外加一颗芯片SAA7350专门做三阶调制和数字滤波。所以,今天一些DIY产品只使用TDA1547是不可能做出DAC7的味道的。而在那个时代,由于集成在DAC内的SDM性能指标差,所以外置SDM和外置数字滤波器的方案很常见。这样看似费力的方案,其实性能确实不输给今天集成度很高的单一DAC芯片。但是,和优秀的DAC相比,例如CS4398已经有五阶的SDM,现代的DAC可能会更好一些。
Delta-Sigma DAC用一种特别的方法对D/A进行处理,升频、波形重整的过程大体上说牺牲了速度而换取了精度。升频的好处对于信噪比来说显而易见,噪声被移到了很高的频率段,对模拟低通滤波来说设计更为方便。但,也正是SDM的多阶过程的每一个变化都会产生相位上,时钟上的失真。也因此我们一直在谈论说,数字音频对时钟要求多么多么高。这其实是Delta-Sigma方法和PCM编码带来的问题,而并不是所有数字音频的问题。当然,在CD机时代,电动机的伺服系统的时钟也同样重要。
我们能否避免SDM带来的失真呢?DAC7和80年代的1bit DAC设备告诉我们一个方法,用更好的芯片来完成这个工作。不同时代有不同的做法。第一,我们在ADC时就直接使用高采样率,对于AD和之后的DAC来说,它可以少做升频,减少失真,降低时钟Jitter的影响。这也就是为什么我们听24bit/96kHz的音乐更好听的道理,并不是因为你听到了什么20kHz-48kHz的超声波,也不是因为96kHz的采样率记录了更多的节目信息,而是降低了SDM的负担,减少了DAC内部的失真[ADC同理]。但这还不彻底。彻底的方式,就是不经过SDM,直接输出。可不可以?
当然可以,播放DSD得到好的音质就是这个道理。而我们现在要用软件来实现SDM更是可以,用电脑的CPU配合播放器软件来完成整个SDM的工作,而只使用DAC芯片内的DSD解码部分。所以,从理论上来说这是完全成立的。
PCM不同规格信号与DSD信号的频域噪声信号分布图
图片转载自DSD-Guide.这张图片的意思不是说高采样率和DSD拥有更多的信息,超声波配合你的超能力,所以听起来就更逼真。而是说,将噪声放在更高的频率段,明显更容易被模拟器件的滤波器滤除干净。
也许你还不相信CPU和软件算法的能力?我们不如回到ADC,即你听到的录音制品制作的过程。即便是DSD64的SACD内容,它也是基于24bit或者32bit的384kHz或者352.8kHz的PCM录音下,通过SDM转换而来的,而不可能是DSD直接录音的。为什么这么说,因为目前DSD音乐无法做后期编辑处理。其实,24bit/352.8kHz已经并不比DSD64差了。
小结:我们这里做一个小结,来说明Delta-Sigma DAC在解码PCM、解码高清PCM、解码DSD时差别的原因是在于它内部的SDM需要工作在什么状态。简单的说,我们使用24bit/96kHz[或更高采样率]是让了DAC内部的整形做更少的工作,而不是听到超声波。而我们用软件的方法做升频,也是同样道理——软件的升频其实是为了DAC内部不升频。而DSD是更彻底的方案,下面要做的就是用软件来实现PCM到DSD转换,让播放音乐完全进入DSD状态。
设置方法与主观听感
Foobar2000 DSD设置之ASIO Proxy 0.9版本 PCM-DSD转换设置
在这套设置中,PCM到DSD转换和播放DSD音乐其实没有什么差别。这里直接进入设置方法,安装的插件请见前文。ASIO Proxy 0.9版本如图所示和0.8版本相比有所变化,看起来更为直观。在安装好该软件后,在ASIO设备中可以看到dsd-asio选项,双击单开,如图看到界面。这个界面顶部可以选择要使用的声卡设备。如图我们使用FiiO ASIO Driver。
Foobar2000 DSD播放设置-ASIO Proxy 0.8版本设置界面
Foobar2000 DSD播放设置-ASIO Proxy 0.8版本设置界面
而图中有五列内容,第一列已经是现成的采样率,标明了Input。它是指一个输入条件,即你在播放该采样率、该格式的音乐时会做以下四个项目的转变。Output是指以什么形式输出,可以选择DSD64、128和256.DSD256或512,必须要DSD Native才可以,DoP1.0是不可以的。
Foobar2000 DSD播放设置-PCM实时转换DSD界面-ASIO Proxy 0.9版本设置界面
Converter内,是四个类型的SDM,Type ABCD,没有找到ABCD的官方说明差别。Sample&Hold,不太明白,好像是DSD to DSD时的升频,似乎没太大必要了。DSD64和DSD128的差别真得听不出来,更不要说DSD512了。DSD Mode有常用的DoP和Natvie,当然还有两个独家的方案。
Foobar2000 DSD播放设置-PCM实时转换DSD界面-ASIO Proxy 0.9版本界面与CPU占用率情况
如图所示虽然是FiiO的Driver,当然只是我们一个实验性的设置,经过测试,飞傲的播放器USB DAC模式是可以支持DoP和Native两种模式DSD的,但最高只可以支持到DSD64.PCM到DSD的SDM需要消耗一定的CPU运算量,如截图所示,我们是在做一个24bit/96kHz到DSD64的转换,在Macbook Air的i5 4250U [1.9GHz 双核超线程,带超线程的i5……] CPU下,需要7%-15%左右的CPU占用率。
而对比macOS下的Audirvana Plus的SDM,Foobar的这套精度应该还比较低,这款播放器下的SDM可以选择7阶和8阶[CS43xx系列是5阶,而DAC7是3阶]的精度,CPU占用率要比这个高2-3倍。我们会单独写一篇Aurvana Plus的滤波器功能的文章。
主观听感
最后,再做一次说明。在看过前文后,我们应该不会纠结44.1kHz如此低采样率的音乐文件转换到高采样率甚至DSD有什么意义?我们以前将44.1kHz升频到352.8kHz或更高,不是要得到更多的信息量,虽然看上去文件是大了不少。它的意义是要让DAC的SDM避免或减少升频、调制工作。而现在我们做的更彻底,把它转换成DSD。这同样或者从来就不是一个信息量的问题,而是对DAC芯片内的工作模式和工作方法有所不同。你听到的完全不是做PCM时DAC工作的单元,而是芯片和电路DSD部分输出的信号。而其实DSD解码基本不需要DAC做什么工作,只是一个通道管理,滤波输出罢了。而PCM是需要做SDM大量的运算工作转换的。而这里,我们用了更高精度的算法让电脑的CPU来完成这部分工作。
主观听感的差别也是相当正面的,这与我们以前玩的升频带来的差别还是较大的。无论是电脑CPU还是随身听、或者声卡专用的芯片进行升频,一般会带来听感上差异的主要特点是声音密度,低频会变得结实,声音厚度会稍有改善。但SDM后直接通过DSD输出,会带来更大改善。
理论上,不同芯片DSD和低通滤波还是有差异,但是我们对比了Mojo、乐之邦02Mark2、06MX,飞傲X7等DAC基本得到了同样的声音变化特征。在DSD模式下,输出整个声音背景的安静程度会有比较大幅度的提升,这对于喜欢追求背景“黑度”的玩家来说和耳机玩家来说是一大福音。其次,整个声音的后延瞬态变得干净而平滑,就是声音收紧的这个瞬态更为自然细腻。如果对比PCM状态,哪怕是24bit/96kHz,也会觉得它的瞬态发糊,这主要发生在中频和低频。而对高频的改善,同样是这部分瞬态,声音的边缘圆滑了很多,相比PCM状态就是毛刺感明显。这种变化不需要你有多么高级的设备,一套入门设备,同样可以轻易的体会得到。
总结
原本我们打算写这篇文章只是谈谈ASIO Proxy新版本对于Windows10兼容稳定性,恰好又发现了SDM转换的魅力,同时也研究了为什么用CPU去做SDM可以带来好声音的简单原理。关于Delta-Sigma DAC和ADC的细节目前还没有找到一个简单易懂的方法阐述,但对于发烧友来说,前文的道理已经说得比较明白了。对于可以支持DSD的声卡用户来说,还不赶快用ASIO Proxy设置一下,听听声音带来的变化。
而每每谈到DSD总会说到版权问题,但索尼作为SACD几乎惟一的技术倡导者,明显是在默许这类软硬件的使用。不然,自家以及众多日本厂商也不会推出支持DSD播放的解码器。所以,我们认为这是索尼开放的态度,以独特的方式让很少一批的发烧友更多领略SACD和DSD的风采。也许在恰当的时候,我们有可能看到DSD音频技术在互联网音频中的应用出现。
Pcm调制心得体会2前面讲过了多媒体容器格式的变迁,这期我们来看看音频编码是如何发展的。在讲编码之前,同样地,让我们来看看现在最为通用的数字音频格式——PCM是怎么来的吧。
声波是一种机械波,在数字时代到来前,录音的原理其实就是将声波的波形、振幅等等特征依样画葫芦给记录到如黑胶唱片、磁带等介质上面,但是这种记录方式并不利于保存,计算机等电子设备的普及使得人们更想使用电子数据的方式来保存音频。但是用于采集声音的麦克风最终将声波转换输出的电流是一种模拟信号,它用电流的大小来表示声波,是连续的;而计算机使用的数字信号系统是一种离散的、非连续的信号系统,在常见的二进制系统中,它只有0和1两种状态,并不能够直接保存模拟信号,两者之间需要经过转换。
怎么转换呢?首先针对一段声音的音频波形,我们可以用一个较为复杂的波形函数来表示,既然它是函数,那让我们回想一下初中高中大学我们都是怎么把函数画出来的,用线把一个个点连接到一起对不对?那么现在我们反过来,在这条已经给定的函数图像上面按照一定的间隔取点,这个过程就叫做采样,取完点之后把它的值用数字给记录下来,这就叫做量化。
在音频编辑软件中将音频波形放大,你可以看到一个个取样点
这种将声波记录成数字数据的方式就叫做PCM调制,这里说的很简化,但是原理其实是一样的,就是用记录下来的点去拟合出声波函数应该有的样子,在PCM调制中,我们记录到的数据是时间与对应的电平值。而上面这两个操作就带来了采样频率和量化位数这两个关键特征。
PCM调制下的音频重要特征
一个波形函数,上面的红点代表采样点,两个红点之间的横向距离一致,距离值就是采样频率的倒数
量化要做的就是将这个红点的y值以一定的规则记录下来
采样频率
由于声波是一种连续的信号,你可以把它看成数学上面的连续函数,从一个点到下一个点之间有无数多个点,我们没有办法全部将这些时间-振幅信息100%记录下来,只能从中挑选一些,那么怎么挑选呢?以一个固定的时间间隔,到点了就记录。而采样频率指的就是每秒记录这些值的次数,用Hz作为单位。
采样频率越高,我们记录下来的原始声波信息越多,我们保存下来的数字信号自然就越贴近于原始音频信号。
量化位数
在确定了采样次数后,我们在这条声波函数上面拥有了一些间隔相同的点,我们知道,在二维函数上面的点可以用一组二维坐标值来表示,这里横轴是时间t,而纵轴一般就是电平值,因为计算机处理能力的限制,我们不可能用一个无限长的数字去记录它,只能用有限位数的数字去记录,而这个位数就是“量化位数”,它决定了数字音频信号的量化精度。
因为这种记录方式用的是近似值的方法,所以量化位数越大,我们记录下的原始模拟信号的电平值就越精确、越贴近于原始音频信号,另外量化位数越大的音频在动态范围上也要比量化位数小的音频要大。
因为数字信号系统记录下的音频信号已经经过了一次采样了,相对于原始的模拟音频信号它已经是“有损”的了,所以我们今天常说的有损无损指的是有损压缩和无损压缩(可以是无压缩)的区别。顾名思义,无损压缩指的是数据在经过压缩之后没有任何的损失,而有损压缩则相对,它在压缩过后相对于原始数据出现了损失。
而原始数据是什么呢?那就要讲到开启人类数字音频时代的CD。
CD:
光、数字、音乐
在上个世纪五六十年代,人们常用的还是黑胶唱片,而随着1965年光盘的问世,这种比黑胶唱片更加小巧精致的记录载体很快受到了大公司的青睐,其中飞利浦和Sony就决定用光盘作为记录数字音频数据的载体,并为它量身定做一种数字音频记录格式,最终他们决定采用LPCM——线性PCM作为编码。
然后飞利浦和Sony这两家在CD要使用的LPCM编码具体参数,也就是采样频率和量化位数上面产生了分歧,进行了一段长时间的拉锯战。
首先因为人耳普遍只能够辨识频率在20Hz~20kHz之间的声音,而根据奈奎斯特–香农采样定理,对于一个连续信号,只要采样率高于(注意,不能等于)原信号带宽的两倍即可通过采样完美(理论上的)重建原信号,所以CD标准的采样频率先被确定到要在40kHz以上。根据这个底线,飞利浦那边提出的标准是44056Hz/14-bit,而Sony则是使用44100Hz/16-bit的标准,双方都是站在自己的利益角度,两种标准都是为保留与原本的电视、录像带系统(NTSC/PAL)的兼容性而提出的。
最终拉锯战以Sony方面的大获全胜而告终,CD音频以44.1kHz/16-bit的双声道LPCM的形式进行记录,这就是Compact Disc Digital Audio(CDDA)标准,它于1980年定稿。
回到我们上面所说的无损、有损的概念。由于CD是我们最早普及的数字音频记录系统,它也是我们普通人能够接触到的最接近原始音频的介质(先不论Hi-Res),所以大家就开始用“无损”来称呼原始的从音频CD上面保存下来的数据,当然它也可以用于无损压缩过的音频。
Hi-Res
CD标准确定之后,它逐渐变成了音乐发行使用的主要介质,但随着时代的发展,有需求的人们还是发现它不够用了,首先16-bit的量化位数限制了CD音频的动态范围,其次44.1kHz的采样频率仍然会在模拟转数字过程中产生人耳可闻的损失。所以制定一种比CD更高的标准就成为了业界的共识。
从CD诞生到现在的短短四十年中,包括它的创造者Sony和飞利浦在内,一直都有新的厂商想要以自己更新更好的编码标准取代掉CD标准,但很可惜他们的努力都没有成功,CD仍然牢牢地占据着业界。虽然没有成功,但这些努力还是引起了行业协会的重视。2014年,美国唱片业协会(RIAA)这家代表着美国唱片业的贸易团体联合了其他几个较为权威的组织一起给比CD更高的音频制式下了定义:
Lossless audio capable of reproducing the full spectrum of sound from recordings which have been mastered from better than CD quality (48kHz/20-bit or higher) music sources which represent what the artists, producers and engineers originally intended.
也就是说,采样频率/量化位数在48kHz/20-bit或其上的音频都可以被称之为"High Resolution Music",简称就是Hi-Res Music。
RIAA的Hi-Res Music Logo
其实在RIAA之前,日本的電子情報技術産業協会(JEITA)在2013年制定了一套适用于日本国内的Hi-Res标准,这套标准规定了Hi-Res音频在模拟和数字处理过程中必须参照使用的规范,其中对于数字处理过程,JEITA要求全过程的音频格式均在96kHz/24-bit及之上。
这个Logo也是我们现在能看到最多的代表Hi-Res的Logo。
而这套标准也被日本的音频器材行业带向了全球。
一张CD翻录下来的大小总会有个500、600MB吧,对于上个世纪90年代还在使用以几MB为单位的软盘的人们来说显然是太大了,另外网络时代早期的带宽还是非常小的,比如当年拨号上网最快也就只有56kbps的带宽,如果想将CD保存到自己电脑里,或者是通过网络跟人分享,在当时几乎是一件不可能的事情。
而有些人说那为什么不做压缩呢?因为在数据压缩软件看来,你这个CD文件的数据几乎没有冗余,传统的数据压缩方式对音频数据是起不了太大效果的,那咋办呢?只能走有损编码的道路了,这其中,MP3是比较早、也是人们用的最多的有损音频编码。
MP3:最常用的,不一定是最好的
MP3的全称为MPEG-1 Audio Layer III,也可以是MPEG-2 Audio Layer III,它是在1993年被标准化的,至今已经有26年的历史了。别看它的岁数大,但它应用的音频压缩思想至今仍然在音频编码领域中发挥着重要的作用。
首先,MP3使用了MDCT算法,这种算法改正了原始DCT算法上面的一些缺点,它将音频原本的时域信息转换成频域信息,是之后对不同频段信号进行处理的前提。
其次,MP3运用了声音心理学模型,这里有三点。第一,人的听觉频率范围大概在20Hz~20kHz,所以可以多去掉一些高频声音;第二,人耳对于不同频率声音的敏感程度不同,大概在2000Hz~5000Hz之间是最灵敏的,而在两端下降的比较厉害,尤其是高频;第三,人耳听声音有遮蔽效应,一个较强的声音会遮蔽掉较弱的声音,比如说手机开同样的音量在闹市中和在自己房中听起来完全是两码事,另外不同频率声音的遮蔽宽度不同。根据以上三点,MP3编码器就可以对不同频段的音频信号进行取舍,给人耳比较敏感的频段多保留一些细节,而去掉人耳不敏感甚至会听不见的一些声音。
最后,MP3运用了哈夫曼算法来对处理过后的音频数据进行压缩,并且编码器会不断地对前面的处理进行调整,以达到用户给出的码率、质量需求。
由于以上三个大的特点还有别的没有提到的原因,MP3在压缩之后仍然拥有相当高的质量,而压缩比一点都不差,大概在1:4~1:6之间,最高可能有个1:10。因此这个已经有26年历史的编码标准时至今日仍未过时,大量在网络上进行传播的音频仍然使用着它,但它并不是没有缺点。
一是它太狠了,对于20kHz以上的声音几乎就是一刀切,比如下面这张图就是一段320kbps CBR编码的MP3音频频谱图,可以看到20kHz上面完全消失了,这种情况主要出现在CBR编码的MP3上面。
使用CBR 320kbps参数进行编码,可以看到编码后的音频频率上限就是20kHz
当然你也可以强行关闭编码器的一刀切行为。
这是开启使用最高品质VBR编码的MP3频谱,可以看到20kHz以上是完整的
一刀切虽然可以大幅减少音频文件的体积,但在实际听感上总会感觉缺了什么。
第二个缺点,其实也不能算是MP3编码自身的缺点而是它使用的标签有问题。肯定有用户在下载网上的MP3资源时遇到过乱码问题,比如:
这是因为MP3文件使用的ID3标签最初没有统一的文本编码,各种语言的系统会以自己当前使用的文本编码标准往里面写数据,导致使用其他文本编码标准的系统无法正确读取文本数据,最终出现乱码。比如图上这个MP3的信息就是日文系统用Shift-JIS文本编码写入的,而我们平时使用的简体中文Windows的文本编码标准是GBK,无法正确读取,所以出现了乱码。ID3标签在之后的v2版本中改进了这一点。
第三个问题是MP3对于多声道的支持较差,常用的MPEG-1 Audio Layer III标准只支持双声道音频,而非主流的MPEG-2 Audio Layer III才支持最高5.1声道,但是它最高只能够支持采样率为24kHz的音频,完全不够用。
其他的缺点可能算不上什么大问题,不然它也不会被用到今天仍然是主流了。
AAC:先进、优秀,但是没能取代MP3
AAC名叫进阶音频编码(Advanced Audio Coding),它本来是开发出来取代MP3的。联合起来开发它的公司有一大堆,个个都是知名大企业或研究机构,比如索尼、微软、杜比实验室、贝尔实验室,等等等等。最终,AAC被MPEG组织接受,写进了他们的MPEG-2和MPEG-4标准中。
相对于MP3,AAC使用了完整的MDCT算法,因此在编码效率上它更胜一筹,一般在同等码率下,AAC的质量比MP3更好一些。而其他的改进点还有支持更大范围的采样率(16~48kHz=>8~96kHz),最多支持高达48个声道,在对频率高于16kHz的音频处理上明显要好等。总之,作为设计目的是取代MP3的编码,它的特性非常优秀,然而,AAC没有如愿以偿的成功取代掉MP3,究其原因可能还是推广力度不够大。另外,尽管用户无需为使用AAC格式进行流式传输或分发而付费,但硬件制造商和软件开发者需要交这笔钱,专利费用也使得在AAC标准确定之初,普通用户手上根本没有能用的AAC编码器,而在这时候,MP3和著名的LAME编码器已经满天下都是了。
实际上我们现在的日常生活中AAC可以说是无处不在的,在线视频的“业界规范”就是以它作为音频编码标准,所以你随便点开一个在线视频,基本上就会听到用AAC编码的音频。另外一个主力推广AAC的公司就是苹果,早在iTunes商店建立之初,他们就使用AAC作为这个数字音乐商店的音频编码标准了,一直到今天都是,包括在前几年推出的Apple Music流媒体服务。
AAC使用两种容器,一般我们见到的都是以.m4a为扩展名的文件,其实就是mp4。而因为使用mp4容器,文件的元数据使用UTF-8编码保存,所以不会出现如MP3那样的乱码。另一种容器现在比较少见,直接以.aac为扩展名,实际上是一种名为ADTS的容器。
除了以上的特性之外,AAC的编码还是可以模块化定制的,在MPEG-2 Part 7中就已经给出了三种模块化编码方式,而到了更加现代化的MPEG-4 Part 3规范中,更是给出了多达11种模块化配置规范,其中不乏有低延迟模式和高效模式(HE-AAC),下面就简单提一下AAC-LC和HE-AAC。
AAC-LC与HE-AAC
AAC-LC,或者叫低复杂度(Low Complexity)AAC,你可以将它看成是原版的AAC编码,它的编码规范写在MPEG-2 Part 7中,在MPEG-4 Part 3中就直接叫做AAC Profile,而HE-AAC全称High-Efficiency AAC,直译就是高效AAC,它的编码规范写在MPEG-4 Part 3中。主要区别是HE-AAC利用了一些新特性,在编码效率上有明显的提高,特别是在低码率情况下。
简单的关系图如上,可以看到HE-AAC包含了很多新特性,这些新特性帮助它实现了更高的压缩比。
WMA:规格很先进,但它是微软的东西
早个十五年,我们在百度上搜索音乐下载的时候,除了MP3,见得最多的一种格式应该就是WMA了,看到开头的WM两个字母就能明白,这是微软的格式。没错,这是“鼎盛”时期的微软开发并强力推广的专有编码,多见于Windows平台。微软最初开发出它的目的很简单,就是为了和MP3和RealAudio竞争,结果大家都知道了,MP3活到了今天,而WMA和RealAudio都已经消逝在历史长河中了。
WMA全称Windows Media Audio,它同样使用了音频心理学对原始音频进行处理,去除人耳不敏感的声音来减小数据体积,思路与MP3大同小异,不过具体实现上面有差异。WMA是与Windows Media紧紧捆绑的一种音频编码格式,不过微软将编解码开放给了第三方,交钱就可以用,所以在十多年前的MP3播放器上我们也可以播放WMA格式的音频。WMA与Windows Media一起升级,它还有个增强版,就是WMA Pro。我们比较熟悉的可能是Windows XP SP2自带的那个Windows Media Player 9.0,实际上在这个版本中,微软还为WMA引入了无损编码,称为WMA Lossless。
Windows 10还带着Windows Media Player,但还有人用吗?
但是随着微软在多媒体格式竞争中的全面失败,Windows Media也不再更新了,WMA也就慢慢的不再流行了。
Dolby Digital(AC-3)与DTS:电影工业的常客
VCD上面用的MP1音频编码效果太差了,还不支持多声道,但这也是因为CD的容量不够大,而从DVD开始,人们终于有机会在自己家里听到影院级别的音效了,因为它的容量足以直接收录电影使用的Dolby Digital或者DTS音频。那么这两种音频是什么呢?先来说Dolby Digital,我们可能更熟知它的另一个名字:AC-3。
Dolby Digital(AC-3)
Dolby实验室是美国一家专注于音频效果、音频编解码领域的公司,原本在模拟时代,它发明的一系列音频编码已经被好莱坞广泛使用,人们在电影院里面最常听到的就是用Dolby技术编码而成的声音。而到了数字时代,他们也紧跟潮流,于1991年推出了Dolby Digital这种数字音频编码。
Dolby Digital的开创性在于它是首个使用MDCT算法进行压缩的编码,同时他们还使用了音频心理学的研究成果对压缩算法进行优化,使得最终压缩后的产物仍然拥有影院级别的效果,但是DD只支持固定码率编码,这使得它的码率一般都会比较高,所以压缩过后的音频体积也较大。常见的DD编码一般有6个声道,称为DD 5.1,而在很多DVD上面我们经常可以看到它的Logo。DD音频的另外一个特点是它的元数据中带有对解码过程进行控制的相关信息,使得它在支持的播放器上可以还原出制片方想要的效果。
随后DD又发展出了很多新分支,其中比较有名的是Dolby Digital Live,它随着另一家老牌音频硬件公司——创新——进入了千家万户。而DD也有自己的后继者——Dolby Digital Plus,我们可能更熟悉它的另一个名字——E-AC-3,它在DD的基础上提升了比特率和声道数量,我们经常可以在下载版的美剧中见到这种编码。
DTS
在电影音频领域中,另一家影响力很广,技术力很强的公司就是DTS了,DVD时代我们经常见到的就是他们以公司名命名的音频编码格式DTS,这种编码推出于1993年,直接竞争对手就是Dolby实验室的产品。
与Dolby Digital选择使用MDCT算法不同的是,DTS选择了ADPCM作为算法基础,这种算法是PCM的变种,与PCM使用固定量化位数记录电平值不同的是,ADPCM有自适应的特征,在音频电平差值较小时用较少的量化位数去记录,而差值大的时候用更多的量化位数进行记录,这样对于存储空间的利用率就更高了,相对于用MDCT算法算出不同的频率段再砍掉人耳不敏感部分的做法,基于ADPCM算法的编码虽然压缩率要低一些,但是对于声音细节的保留肯定是它要做的更好。当然,这就使得它的体积控制比DD要差一些,所以在一般的DVD上,我们更常见到的是DD而不是DTS。
好莱坞电影真的是以Dobly编码居多的
Dolby实验室与DTS的竞争从这时候的DD与DTS开始,一直延续到今天的Dolby TrueHD VS. DTS-HD Master Audio,后面两个都已经是无损编码了,我们放到下面去讲。
Vorbis与Opus:多见于语音编码
说Vorbis这个名字可能大家都不知道是啥,但是一说Ogg那肯定都会“啊我知道”了。其实Ogg是Vorbis编码的音频常用的一种容器,而Vorbis编码则是在2000年公布的一种计划取代所有有损音频压缩的编码,对,它的野心极大。
Vorbis编码的原理与其他有损编码相比也是大同小异,基于MDCT的时频转换,然后过心理声学进行频段舍弃,不过之后的处理有些不同,它使用矢量量化算法,在低码率情况下有着很好的表现,接近于HE-AAC,但没能完成超越。前面也说了,直到今天MP3也仍然稳坐着音频领域第一编码的位置,所以很明显Vorbis没有完成自己的计划。
之后它的主要开发者Xiph.Org基金会又推出了一种新的编码——Opus,这种编码有着比Vorbis更好的低码率表现,在同码率下终于实现了对HE-AAC的超越。而它还有一个低时延的特性,可以做到目前最低的编码延迟,这也使得它在数字语音通信领域中大放异彩,它现在也是IETF标准中的一员。
在自己的硬盘空间逐渐大到放CD原盘都没有问题了之后,新的问题出现了,网速跟不上。回想一下05年左右,国内家庭普遍还是在用ADSL上网,速率可能也就只有1~2Mbps,用这个速度下点MP3还行,但是下原盘就太慢了,但很多音乐爱好者就是想收藏“没有瑕疵”的无损音频,怎么办呢?这时无损音频压缩编码走上了舞台,首先登场的是Monkey's Audio,又叫APE。
APE:无损音频压缩的先行者
APE是Monkey's Audio这个编码使用的扩展名,但是叫得多了大家都只知道APE而不知道Monkey's Audio了。它是可考的、比较早出现的一种无损音频编码,后面要提到的WavPack(.wv)比它出现的还要早,但是APE却是头一个大范围流行起来的无损音频编码,最初版本公开于2000年。
问题来了,前面不是说对传统压缩方式对于音频数据并不能起到很好的效果吗?那APE是怎么在无损的情况下实现如此高的压缩率的?答案也很简单,传统方式不行,那我就用新的针对性算法呗。
APE主要使用了三大算法来实现对原始音频数据的无损压缩,第一个是Joint Coding,简单说就是将左右两个声道的共同信息进行复用,从而减小音频体积;第二个是线性预测编码(Linear Predictive Coding),因为音频信号前后关联性非常大,可以根据前面一段音频波形预测后面的音频波形,如果预测得到的值与真实值有差距,则对差值进行编码,这种算法是音频无损编码的核心杀手级算法,可以做到在没有损失的情况下大幅提升压缩比;第三个就是预测编码所需要的量化位数。
这三种主要算法使得APE可以在没有损失的情况下达到约50%的压缩比,这是之前的无损音频编码做不到的事情。
但是APE也有较大的缺陷,最高只支持双声道、24-bit的量化位数让它在新世代落后于FLAC,因为存在浮点计算,所以对硬件性能的需求要高于FLAC,在编解码上面也更慢,而它也没有针对数据完整性做
另外由于APE虽然标了自由软件,但是它使用的许可证并不能让人们直接使用Monkey's Audio现成的源代码,必须自行动手去实现对它的解码支持,这也限制了它的应用范围。
FLAC:免费开放,新的业界事实标准
FLAC基本上是与APE同时间提出来的,稍微晚了那么一丢丢,它直接将编码的最大特点写在自己的名字里了——Free Lossless Audio Codec,自由、无损。
相对于APE,虽然同样使用了线性预测算法,但它的压缩比稍微差了一点,不过由于FLAC使用全整数的数据计算方式,所以低端电子设备也可轻松对其进行解码,而它在数据结构上考虑到了数据完整性和流传输,它采用帧结构设计确保了即使文件的部分片段遭遇不测,其他部分也能够正常播放,而支持流传输的特性使得它在可以在流媒体时代占据一席之地。并且它对于多声道的支持比APE强很多,最高可以支持8声道。
FLAC身上的种种优点使得它成为了目前最为流行的无损音频压缩编码,Android早就添加了对于FLAC的支持,而iOS也在第11个大版本中放下自己的矜持加入了对它的支持。FLAC已经俨然成为了新的业界通用编码,各大Hi-Res音乐售卖网站也在使用FLAC作为载体传播Hi-Res及普通无损音乐。
Apple Lossless(ALAC)
macOS作为很多音频编辑软件使用的系统环境,对于音频编码自然也是有着很高的要求,其实苹果自己也很早就跟进了无损音频的发展,在2004年的时候他们就推出了自己的无损音频压缩编码——Apple Lossless,但是当时这种格式只有苹果自家的系统和软件才能支持,并且会收取授权费用,这也导致了ALAC错过了无损音频开始发展的萌芽期,直到2011年,FLAC已经成为市场主流的情况下,苹果才将ALAC开放出来,并且取消了它的专利费用。
ALAC在编码方式上与其他几种无损音频压缩编码并没有太大的区别,同样是基于线性预测的算法,不过它的编码器连个压缩率选项都不提供,但编码速度确实挺快的。ALAC与AAC一样使用MP4作为数据容器,所以也继承了MP4良好的标签支持。
但是它的使用范围始终不广,本来就基本限定于苹果设备上,而在iOS和macOS纷纷支持FLAC之后,它的存在意义就更小了。
Dolby TrueHD与DTS-HD Master Audio:蓝光时代电影常用音频编码,新的战场
从DVD到蓝光是一次大的飞跃,光盘这种存储介质在新的蓝色激光的帮助下,大幅度提升了存储密度,也使得它可以记录体积更为庞大的音频,有了大的空间,那肯定就要上无损啊,其实蓝光的容量已经足够放7.1声道、48kHz/24-bit的LPCM了,但是它的体积还是太大,所以Dolby和DTS不约而同的在高清时代推出了新版的音频压缩编码技术,Dolby这边是以Dolby TrueHD系列为主,而DTS是以DTS-HD Master Audio为主,两边都是无损压缩技术,这边就讲的粗略一些了。
Dolby TrueHD
Dolby TrueHD使用与DVD-Audio相同的MLP编码对原始PCM音频数据进行处理,最高支持192kHz/24-bit的规格,另外还支持16个独立声道。与前任Dolby Digital一样,它也带有用于控制播放过程的元数据,提供更加还原的音频效果,Dolby后来推出的Atmos氛围声效果就是通过这些独立于音轨之外的元数据实现的。
DTS-HD Master Audio
这两种多见于蓝光原盘的音频编码都附带了对原来有损编码的兼容,DTS-HD Master Audio内建了一条有损音轨,称为DTS Core Stream,它的无损部分其实是对有损部分的一个补充,在支持的设备上自动就会播放无损的DTS-HD Master Audio,而在不支持的设备上也可以切换到DTS Core Stream,不会影响到正常的播放,而另一边的Dolby TrueHD则是通过附带一条Dolby Digital音轨的方式来解决兼容性。
DTS-HD Master Audio在日本用的比较多一些,尤其是各种动画小圆盘。
TTK,TAK,WavPack等
除了上面三个稍微多见一点的编码以外,无损音频编码界还有很多其他的编码,由于APE推出时间早、FLAC用的人多等原因,这些无损压缩编码最终都没有推广开来,成为了比较小众的编码,虽然它们可能在某些方面有着优势,但很可惜,时势造英雄,取代英雄没有这么容易。
说起PDM(Pulse Density Modulation 脉冲密度调制)可能没学过数字电路的同学会云里雾里,简单一点的说法就是PDM使用0和1来模拟原始波形,怎么模拟呢?通过在单位时间内0和1的堆叠来进行,因为此时0和1的密度代表了波形的振幅,所以叫做脉冲密度调制,它与PCM记录电平值的做法是完全不同的。
基于PDM调制的原理,Sony和飞利浦在1999年推出了用于取代CD的SACD(Super Audio CD),它使用的ΔΣ算法在模拟/数字转换(A/D)过程中会以64倍于CD的采样率(2.8224MHz)对原始音频进行过采样,而由于PDM的特性,量化位数当然就只有1-bit,因为只有每一个采样点都只有开或者关两种状态嘛。
PCM与DSD的对比
DSD解决了传统PCM编码上的高频量化噪声问题,高采样率同时还带来了更加丰富的声音细节,而密度调制的方式也使得它拥有更大的声音动态范围。除了原始的64倍采样率的DSD之外,后来还推出了DSD128、DSD256、DSD512等新格式,它们的采样率逐步上升。
现在我们可以拿到的DSD音频一般都是ISO镜像格式的,使用专门的解码器可以将其转换成PCM音频播放,而支持DSD直通播放的设备还是相当的贵。
SACD的物理介质其实就是DVD,同期其实还有一个DVD-Audio阵营,他们仍然使用了兼容性较好的PCM调制,不过是基于一种新的名为MLP(Meridian Lossless Packing)编码方式,在双声道情况下最高支持192kHz/24-bit的PCM音频流,直到今天,它的规格都是相当高的。
但是Hi-Fi最终也只是少数人的玩物,它的配套解码器、播放器都太贵了,而且Sony当时为了拉拢唱片发行商做出了“永远不会让PC读取SACD”的承诺(后来他们食言了)也限制了SACD的进一步推广,在面对以iPod、iTunes为代表的数字音乐浪潮时,它和DVD-Audio都只能站在一边看着眼馋,事实证明,绝大多数人们需要的是方便快捷的听歌体验,所以便于携带的各种MP3播放器很快就取代掉了CD成为了新的潮流。而后,就是流媒体取代传统MP3的又一股浪潮,我们现在就身处于这股浪潮之中。
要总结的话就是,MP3和AAC这两种有二十多年历史的编码统治着有损音频编码,而FLAC基本上成为了无损音频编码的事实标准,而电影工业中Dolby和DTS仍然在竞争,目前看上去Dolby更占上风。而在开放软件领域中,Vorbis和Opus这两种开放的格式也慢慢在Web领域中得到大量应用。
其实看到最后,你会发现,本文写到的几种基于PCM调制的无损、有损音频压缩编码基本上都是基于类似的编码——有损压缩很多都是基于MDCT,而无损压缩基于线性预测编码。用烹饪打个比方,原始的PCM音频就是主要原料,你可以把MDCT和线性预测编码看成是不同的主要做法,比如MDCT是炒而LPC是蒸,其他的一些算法就像是对于主要原料的小处理方式,比如先过个水或者是先腌制一下,他们与主要做法一起左右着整道菜的口感和味道,而最终得到的菜的营养价值也根据不同的处理手段而改变。
另外,在有损压缩技术中,心理声学(Psychoacoustics)是一大助力剂,它帮助各种编码对原始音频进行取舍,在对听感影响很小的情况下大幅减少体积。而心理学也不只是在音频编码领域中起着作用,在视频和图像编码中,它同样有着重要的贡献,当然,这就是后话了。
因为各种物理极限和自然定律,数字记录方式永远不可能100%还原出现实,但是人类是不会停止研究、应用新技术的脚步的,数字世界将会越来越接近于现实。
实际上在这个网络流媒体时代,我们的需求也逐渐发生了改变,从怎么样带更多的歌变成了怎么样听得更爽,所以现在对于音频压缩技术还是有不小的需求的,一个更为高效的编码可以在节省网络带宽的同时提高人们听音乐的享受程度,而聚沙成塔,每个人那儿节省一点点的带宽最终聚合起来就可以节省巨大的带宽费用,对于用户本身也可以节省流量,双赢的事情何乐而不为呢?这也是为何我们要追求更高效的媒体压缩方式的一个初衷。
Pcm调制心得体会3WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。
PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号,而未经过任何编码和压缩处理。
简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。
有时候需要将录音文件保存为wav格式,这需要手动填充wav的文件头信息
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// WAV Header class
@interface ZZWavHeader : NSObject
/// 数据长度
@property (nonatomic, assign) UInt32 dataLength;
/// 音频数据的编码方式, 1表示PCM编码
@property (nonatomic, assign) UInt16 formatTag;
/// 通道数
@property (nonatomic, assign) UInt16 channels;
/// 采样率
@property (nonatomic, assign) UInt32 samplesPerSec;
/// 精度,即位深
@property (nonatomic, assign) UInt16 bitsPerSample;
/// 获取WAV Header数据
- (NSData *)getData;
@end
NS_ASSUME_NONNULL_END
// http://www.skyfox.org/ios-audio-wav-write-header.html
// https://stackoverflow.com/questions/10914888/recording-wav-format-file-with-avaudiorecorder
#import "ZZWavHeader.h"
@implementation ZZWavHeader
- (NSData *)getData {
UInt32 totalDataLen = self.dataLength + (44 - 8);
UInt16 blockAlign = self.channels * self.bitsPerSample / 8;
UInt32 byteRate = blockAlign * self.samplesPerSec;
Byte header[44];
// RIFF:4字节
header[0] = 'R'; // 0x52
header[1] = 'I'; // 0x49
header[2] = 'F'; // 0x46
header[3] = 'F'; // 0x46
// 文件长度: 4字节
// 这个长度不包括"RIFF"标志(4节节)和文件长度本身所占字节(4字节)
header[4] = (Byte) (totalDataLen & 0xff);
header[5] = (Byte) ((totalDataLen >> 8) & 0xff);
header[6] = (Byte) ((totalDataLen >> 16) & 0xff);
header[7] = (Byte) ((totalDataLen >> 24) & 0xff);
// WAVE:4字节
header[8] = 'W'; // 0x57
header[9] = 'A'; // 0x41
header[10] = 'V'; // 0x56
header[11] = 'E'; // 0x45
// fmt : 4字节,注:fmt后跟一英文空格字符
header[12] = 'f'; // 0x66
header[13] = 'm'; // 0x6d
header[14] = 't'; // 0x74
header[15] = ' '; // 0x20
// 4 bytes: size of 'fmt ' chunk, Length of format data. Always 16
// 文件内部格式信息数据的大小: 4字节
header[16] = 16;
header[17] = 0;
header[18] = 0;
header[19] = 0;
// 音频数据的编码方式: 2字节
// 1:表示是PCM 编码
// format = 1, Wave type PCM
header[20] = self.formatTag;
header[21] = 0;
// 声道数channels: 2字节
header[22] = (Byte)self.channels;
header[23] = 0;
// 采样率: 4字节
header[24] = (Byte) (self.samplesPerSec & 0xff);
header[25] = (Byte) ((self.samplesPerSec >> 8) & 0xff);
header[26] = (Byte) ((self.samplesPerSec >> 16) & 0xff);
header[27] = (Byte) ((self.samplesPerSec >> 24) & 0xff);
// 音频数据传送速率: 4字节
// 播放软件利用此值可以估计缓冲区的大小
// 其值为采样率×每次采样大小
// 传送速率单位是字节,因此采样大小需要位深除以 8,然后乘以通道数
// bytePerSecond = sampleRate(比如16000) * (bitsPerSample(16位深) / 8) * channels
header[28] = (Byte) (byteRate & 0xff);
header[29] = (Byte) ((byteRate >> 8) & 0xff);
header[30] = (Byte) ((byteRate >> 16) & 0xff);
header[31] = (Byte) ((byteRate >> 24) & 0xff);
// 每次采样大小: 2字节
// blockAlign = 通道数(比如1) * bitPerSample(比如位深16) / 8
header[32] = (Byte) (self.channels * self.bitsPerSample / 8);
header[33] = 0;
// 采样精度,即位深
header[34] = self.bitsPerSample & 0xff;
header[35] = 0;
// data: 4字节
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
// 数据长度: 4字节
// 此数据长度即未添加header之前的原始数据长度
// iOS: [attributes fileSize]
header[40] = (Byte)(self.dataLength & 0xff);
header[41] = (Byte)((self.dataLength >> 8) & 0xff);
header[42] = (Byte)((self.dataLength >> 16) & 0xff);
header[43] = (Byte)((self.dataLength >> 24) & 0xff);
return [[NSData alloc] initWithBytes:header length:44];
}
@end
- (void)encode:(NSError * __autoreleasing _Nullable *)error {
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:self.srcFilePath]) {
NSString *message = [NSString stringWithFormat:@"encode wav data fail, file not exists: %@", self.srcFilePath];
NSLog(@"%@", message);
return;
}
NSError *err = nil;
NSDictionary *attributes = [fileManager attributesOfItemAtPath:self.srcFilePath error:&err];
if (!attributes || err) {
NSString *message = [NSString stringWithFormat:@"get file attribute error"];
NSLog(@"%@", message);
return;
}
int totalSize = (int)[attributes fileSize];
ZZWavHeader *header = [[ZZWavHeader alloc] init];
header.channels = _CHANNEL_COUNT;
header.formatTag = 0x0001;
header.samplesPerSec = _SAMPLE_RATE;
header.bitsPerSample = _BIT_DEPTH;
header.dataLength = totalSize;
NSData *headerData = [header getData];
if (headerData.length != 44) {
NSString *message = [NSString stringWithFormat:@"convert to wav fail, header not 44 byte length"];
NSLog(@"%@", message);
return;
}
NSMutableData *data = [NSMutableData dataWithData:headerData];
[data appendData:[NSData dataWithContentsOfFile:self.srcFilePath]];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.srcFilePath];
[fileHandle writeData:data];
[fileHandle closeFile];
NSLog(@"%@", [NSString stringWithFormat:@"转换成功:%@", self.srcFilePath]);
}
上一篇:胶板画心得体会,最新合集
下一篇:观看前浪心得体会,最新合集