背景及功能介绍
今天有一个任务是分割wav成pcm文件,以及把pcm加上头成为wav文件。因为部分功能有现成的C语言程序,所以就用C语言做了。
当我对wav文件格式了解后突然发现完全可以用ruby来实现这些操作,正好自己对ruby操作二进制文件有些疑惑(这个疑惑原来使用Array#pack解决),于是就重写今天主要实现的功能。
程序实现如下,希望对做语音的同学有些帮助:
class WAV_aux
def initialize(channels = 1,bits = 16,sample_rate = 8000)
@channels=channels
@bits=bits
@sample_rate=sample_rate;
end
def seg_wav(f_wav_name,f_pcm_name,bg,ed)
mul=@sample_rate/1000
mul*=2
File.open f_pcm_name,"wb" do |w|
File.open f_wav_name,"rb" do |f|
f.seek( 44 + bg*mul)
w.syswrite( f.sysread( (ed-bg+1)*mul ) )
end
end
end
def add_pcm_head(f_wav_name,f_pcm_name)
pcmHEADER=Array.new(3)
pcmFMT=Array.new(8)
pcmDATA=Array.new(2)
pcmHEADER[0]="RIFF"
pcmHEADER[1]=44
pcmHEADER[2]="WAVE"
pcmFMT[0]="fmt "
pcmFMT[1]=[16].pack("L")
pcmFMT[2]=[1].pack("S")
pcmFMT[3]=[@channels].pack("S")
pcmFMT[4]=[@sample_rate].pack("L")
pcmFMT[5]=[@sample_rate * 2 ].pack("L")
pcmFMT[6]=[2].pack("S")
pcmFMT[7]=[@bits].pack("S")
pcmDATA[0]="data"
pcmDATA[1]=0
data=""
File.open f_pcm_name,"rb" do |f|
pcmDATA[1]=f.size
data=f.sysread(pcmDATA[1])
end
pcmHEADER[1]+=pcmDATA[1]
pcmHEADER[1]=[pcmHEADER[1]].pack("L")
pcmDATA[1]=[pcmDATA[1]].pack("L")
File.open f_wav_name,"wb+" do |w|
pcmHEADER.each do |x|
w.syswrite(x)
end
pcmFMT.each do |x|
w.syswrite(x)
end
pcmDATA.each do |x|
w.syswrite(x)
end
w.syswrite(data)
end
end
end
para=["28919.wav","lx.pcm",2000,20000]
wav_aux=WAV_aux.new
para=["lx.wav","lx.pcm"]
wav_aux.add_pcm_head(*para)
附
- ruby的Array有个sample方法可以随机选取指定数目的数组内容且不重复。
- 第一次用markdown写,感觉不好用(预览正常最后显示不正常)