wav文件头信息

本文记录了使用Python对接百度TTS接口并将返回的mp3音频数据转换为pcm-8k格式的wav文件的过程。作者通过手动添加wav头部信息实现了转换,并详细介绍了wav文件的格式。最后,提供了实现转换的代码示例和测试结果。
摘要由CSDN通过智能技术生成

 

概述

最近在对接百度TTS的python接口,对接的过程中发现一些问题,记录下解决方案。

百度TTS接口返回的音频数据格式有4种,分别是mp3,pcm-16k,pcm-8k,wav(pcm-16k)。

我们需要的结果是wav(pcm-8k)。

需求对齐后,分析解决方案,主要有以下几个选择。

  1. mp3转码为wav,比如python库AudioSegment。
  2. wav(pcm-16k)重采样为wav(pcm-8k),比如python库wave。
  3. pcm-8k转换为wav格式,比如python库wave。
  4. pcm-8k手动增加wav格式头信息,写入文件。

今天选择第4种方案,并顺便复习了一下wav格式的头部信息。

环境

python 3.10.3

wav文件格式

先复习一下wav文件的格式信息。

下面的截图是根据我的理解画的,仅仅针对pcm编码格式,其他压缩编码格式会多一个fact chunk(在fmt chunk和data chunk中间),有兴趣的可以自行查找资料。

 

源码

之前用c写过wav的头文件信息,用python还是第一次。

其中aip是百度tts的python库,struct是python内建模块,用于python字符串和C语言结构体之间的转换,我们用struct库对字符串和整数做序列化。

#required python3



from aip import AipSpeech

from struct import pack



def tts_baidu(content, filename):

    #init client

    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)



    ## aue:3-mp3, 4-pcm-16k, 5-pcm-8k, 6-wav(pcm-16k)

    result  = client.synthesis(text = content, lang = 'zh', ctp = 1, options = {'aue': 5, 'per': 0, 'vol': 5})



    # 识别正确返回语音二进制 错误则返回dict 参照下面错误码

    if not isinstance(result, dict):

        with open(filename, 'wb') as f:

            ##aue use 5-pcm-8k, write wav header info first

            header = ''

            header = pcm_wav_head(len(result), header)

            f.write(header)

            f.write(result)

            f.close()

    else:

        raise Exception("tts fail, %s" % str(result))



    return



###ONLY for pcm, 8000 sample, 16bits, 1 channel

def pcm_wav_head(data_len, header = ''):

    header = b'RIFF' #WAVE DES, 4

    header += pack('I', (data_len + 36)) #wav chunk len, 4

    header += b'WAVE' # WAVE, 4

    header += b'fmt ' #fmt , 4

    header += pack('I', 16) #PCM fmt info len, 4

    header += pack('H', 1) #fmt type PCM 0x0001, 2

    header += pack('H', 1) #1 channel, 2

    header += pack('I', 8000) #sample 8000, 4

    header += pack('I', int(1 * 8000 * 16 / 8)) #bytes per second, 4

    header += pack('H', int(1 * 16 / 8)) #sampling frame size, 2

    header += pack('H', 16) #bit depth, 2

    header += b'data' #data

    header += pack('I', data_len) #data len



    return header



if __name__ == "__main__":

    content = '123456'

    filename = r'C:\Users\12345\Desktop\101.wav'

   

    tts_baidu(content, filename)

测试

发送tts请求,根据返回结果写wav文件,wav文件用UE打开,见截图。

截图中,我们可以看到几个数据段的标识,“RIFF“,”WAVEfmt “,”data“。

 

总结

简单复习了一下wav格式的头部信息,更加复杂的编解码和压缩格式头部信息也都可以在网上找到详细的描述。

wav是一个封装格式,封包的信息都在wav头中。

pcm编码格式是不压缩的语音编码格式,封装pcm数据的wav文件格式相对简单,对于理解音频文件的打包封装有一定帮助。

空空如常

求真得真

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值