最近在做一个录音工具,录音前0.5秒会偶尔出现底噪过大,波形上沉下浮等状况。虽然我们团队审核的时候可以把前0.5秒截掉, 但是如果音频过多会花费很长的时间。 现要求App直接把录音的前0.5秒截取掉,,这样就会避免了上述诸多麻烦。
首先介绍一下AVAudioRecorder: 这是一个录音的工具类,一般情况下我们会设置声道, 采样率,格式(kAudioFormatLinearPCM),然后调用record方法就会自动转为wav格式的音频。其实pcm格式转成wav格式只是在音频的前面加上一个44位的头文件,这44位的头文件会记录音频的一些基本信息。话不多说,现在我们来进行截取。
1、直接剪切
这种方法适合 “音频后面不拼接任何data数据”
当我们查看AVAudioRecorder官方API的时候会发现 它并没有提供关于删除的方法, 不要急,其实我们可以换个思路, 用“替换”来实现删除的功能,这时我们会用到replaceBytesInRange这个方法,如下图1
图1(44,16044)的意思是44位到16044位的范围,之所以从44位开始是因为前44位是wav的头文件,16044代表的是第16044位,录音的时候我设置的采样率是16k,用的short类型占两位,这样我们录制1秒就是32k,0.5秒就是16k(可以微调) 我们把这个范围的内容的长度变成0,这样就相当于把这个范围的内容截取掉了
2、剪切后修改wav头文件
由于我们音频后要拼接一个txt文件,txt里记录音频的相关信息,所以语音后面要拼接一段data数据,这样再用上面的方法就会出现如图2这样的问题,后边有个细长的尾巴,我现在解释一下为什么会出现这个尾巴。当我们在录音转成wav格式的时候 头文件里就记录了这个音频的信息, 包括语音时长,文件大小等。如果我们剪去一段音频,那么头文件里还是会记录剪切之前的文件大小, 例如: 语音文件是100k 我们剪去前16k,这样只剩下84k,但是头文件里记录的音频文件还是100k,这样就会导致头文件把拼接的txt文件当做语音文件来处理。txt文件越大波形的尾巴越长,所以我们现在要把头文件里的100k也变成84k,这样就会避免这种问题。
图2首先我们截取前16044位,这里面包括0.5s(16k)的音频和前44位头文件,然后把剩余的音频拼接自己修改过的头文件,头文件格式如图3
这种文件网上有很多,里面的算法我也没太搞清楚,如果有懂音频的大神还望麻烦做个解答
图3引用方法如下: targetData就是剩余音频的流文件
NSData *header = WriteWavFileHeader(targetData.length,targetData.length + 36,16000,1,32000)
这样头文件再拼接剪切过的音频就会重新生成一个新的wav格式文件,这个文件就是剪切前0.5s后的音频文件
NSMutableData *wavDatas = [[NSMutableData alloc]init];
[wavDatas appendData:header];
[wavDatas appendData:targetData];
然后写入路径文件 over。
网友评论