首页>>后端>>Golang->使用go语言存储pcm格式数据为wav

使用go语言存储pcm格式数据为wav

时间:2023-11-30 本站 点击:0

上次写了存储float类型的wav文件,其实存储PCM的相关数据相对操作更少,难度更小。首先,和存储flaot类型的数据类似,定义一个文件头结构体。

typewaveHeaderstruct{RIFFID[4]byte//内容为""RIFFDwSizeuint32//最后填写,WAVE格式音频的大小FccType[4]byte//内容为"WAVE""FmtID[4]byte//内容为"fmt"FmtDwSizeuint32//内容为WAVE_FMT占的字节数,为16WFormatTaguint16//如果为PCM,值为1WChannelsuint16//通道数,单通道=1,双通道=2DwSamplesPerSecuint32//采样率DwAvgBytesPerSecuint32/*==dwSamplesPerSec*wChannels*uiBitsPerSample/8*/WBlockAlignuint16//==wChannels*uiBitsPerSample/8UiBitsPerSampleuint16//每个采样点的bit数,8bits=8,16bits=16DataID[4]byte//内容为dataDataDwSizeuint32//data的大小}

写入文件分两部分,分别是创建文件头和写入文件数据。下面是我们创建文件并将部分PCM数据写入文件的过程。

funccreateNewWave(urlstring,input[]byte,channelsint,bits_per_sampleint,sample_rateint){inputContext:=inputf,err:=os.Create(url)iferr!=nil{fmt.Println(err.Error())}deferf.Close()inputLen:=len(inputContext)header:=createNewHeader(channels,bits_per_sample,sample_rate)headerPointer:=&headerheaderPointer.DataDwSize+=uint32(inputLen)headerPointer.DwSize+=uint32(inputLen)headerBytes:=*(*[]byte)(unsafe.Pointer(&headerPointer))//headerBytes:=[]byte(&header)f.Write(headerBytes[0:44])fmt.Println(headerBytes[0:44])//f.Seek(0,2)f.Write(inputContext)}

其中input为需要写入的PCM数据,url为存储路径。channels 为声道数, bits_per_sample 为采样点大小, sample_rate 为采样率。

PCM尾添加至已存在的wav文件。

funcp2w(input[]byte,outputstring){inputContent:=inputinputSize:=len(inputContent)fout,err:=os.OpenFile(output,os.O_RDWR,os.ModePerm)iferr!=nil{log.Fatal(err.Error())}deferfout.Close()buff:=make([]byte,44)size,err:=fout.Read(buff)ifsize!=44{fmt.Println("文件损坏")}varheader*waveHeader=*(**waveHeader)(unsafe.Pointer(&buff))header.DataDwSize+=uint32(inputSize)header.DwSize+=uint32(inputSize)resHeader:=headerheaderBytes:=*(*[]byte)(unsafe.Pointer(&resHeader))fout.Seek(0,0)fout.Write(headerBytes[0:44])fout.Seek(0,2)fout.Write(inputContent)}

里面涉及的知识点和上一篇文章大同小异。如果有感兴趣的同学可以留言一起讨论。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4547.html