Ruby 操作二进制文件,wav与pcm文件转换

来源:互联网 发布:金珠优化就是染色吗 编辑:程序博客网 时间:2024/05/05 05:42

背景及功能介绍

今天有一个任务是分割wav成pcm文件,以及把pcm加上头成为wav文件。因为部分功能有现成的C语言程序,所以就用C语言做了。当我对wav文件格式了解后突然发现完全可以用ruby来实现这些操作,正好自己对ruby操作二进制文件有些疑惑(这个疑惑原来使用Array#pack解决),于是就重写今天主要实现的功能。程序实现如下,希望对做语音的同学有些帮助:
# -*- coding:utf-8 -*-# 格式参考 http://blog.csdn.net/zhihu008/article/details/7854529# C程序参考 http://blog.csdn.net/gavinr/article/details/6957136# ruby pack 参考 http://blog.csdn.net/dazhi_100/article/details/11787177class 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 # 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 # +pcm长度 现在未知        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") # 2表示每个采样点占2个字节        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            #w.syswrite( "RIFF" ) 只有字符串直接可以            #p [1000].pack("L") #能显示就显示字符,否则就 \x            #w.seek( 4 , IO::SEEK_CUR) # 可以直接空开文件            #w.syswrite( [10,22].pack("LC") )            #w.syswrite( [1000].pack("L") )    end #add_pcm_headend #Classpara=["28919.wav","lx.pcm",2000,20000]wav_aux=WAV_aux.new#wav_aux.seg_wav(*para)para=["lx.wav","lx.pcm"]wav_aux.add_pcm_head(*para)

  • ruby的Array有个sample方法可以随机选取指定数目的数组内容且不重复。
  • 第一次用markdown写,感觉不好用(预览正常最后显示不正常)
0 0
原创粉丝点击