wav文件头信息
概述
最近在对接百度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文件格式相对简单,对于理解音频文件的打包封装有一定帮助。
空空如常
求真得真
wav文件头信息的更多相关文章
- sublime 设置新建文件自动添加author(作者)等文件头信息
很多时候, sublime 自带自动添加文件头信息, 但是并不是我们想要比如下面这样的:新建一个python文件 自动添加的author 信息== 上面并不是我想要的, 我想要下面这样的效果:== 这 ...
- 给pcm格式文件加wav文件头
#include <stdlib.h>#include <stdio.h>#include <string.h>void main(){ //wav头的结构如下所示 ...
- eclipse快速配置spring相关xml文件头信息
通过spring tools 插件工具来快速配置xml头信息 ctrl +n 创建-----------> 输入spring 选中spring Beann Configuration File ...
- FFmpeg命令行工具学习(一):查看媒体文件头信息工具ffprobe
一.简述 ffprobe是ffmpeg命令行工具中相对简单的,此命令是用来查看媒体文件格式的工具. 二.命令格式 在命令行中输入如下格式的命令: ffprobe [文件名] 三.使用ffprobe查看 ...
- Pycharm中.py文件头信息配置
在社区版的Pycharm开发软件中设置每次新建.py文件都会自动生成如下信息 #! /usr/bin/env python # -*- coding:utf-8 -*- # Author: Tdcqm ...
- WAV文件头相关资料
http://stackoverflow.com/questions/6284651/avaudiorecorder-doesnt-write-out-proper-wav-file-header h ...
- DCMTK读取DICOM文件头信息的三种方法
Howto: Load File Meta-Header Here's an example that shows how to load the File Meta Information Head ...
- php通过文件头检测文件类型通用类(zip,rar…)(转)
在做web应用时候,通过web扩展名判断上存文件类型,这个是我们常使用的.有时候我们这样做还不完善.可能有些人上存一些文件,但是他通过修改 扩展名,让在我们的文件类型之内. 单实际访问时候又不能展示( ...
- java通过文件头来判断文件类型
import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.ut ...
- pycharm新建py文件时,自动补充文件头注释信息
步骤: 1.File -->Settings 2.选择 File and Code Templates -> Files -> Python Script 文件头注释信息代码样式: ...
随机推荐
- [ABC263E] Sugoroku 3
Problem Statement There are $N$ squares called Square $1$ though Square $N$. You start on Square $1$ ...
- Git提交修正
应用场景 日常开发中我们可能会遇到这样的问题 1.提交了代码有错误 2.提交的信息写错了 3.漏了一些文件没有提交 ...... 再或者我们写一个功能时,中间有很多小的提交,这中间就会产生特别多的co ...
- 数字孪生系统如何整合CesiumJS?整合后会产生怎样的化学反应?
数字孪生有关的项目中,智慧城市一直是一个比较重要的类型,但是这类智慧城市项目往往包含了大量的GIS相关数据,例如倾斜摄影.DEM.DOM.地形数据等.这时,将GIS系统融合进数字孪生系统的需求就出现了 ...
- 【Python】【OpenCV】Cameo项目(一)实时显示摄像头帧
Cameo项目介绍: 1.实时捕获并显示摄像头帧. 2.具备截图.保存视频和退出三个功能键. 要求存在文件:manager.py 和 cameo.py 一.manager.py 两个类:Capture ...
- 递归产生StackOverflowError
package com.guoba.digui; public class Demo01 { public void A(){ A();//自己调用自己,递归没用好,产生错误java.lang.Sta ...
- Python 潮流周刊第 34 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- 人大金仓驱动包kingbasejdbc8.6.0.jar V8驱动jar包
人大金仓驱动包kingbasejdbc8.6.0.jar V8驱动jar包 工作上要将kingbaseV8数据库整合到项目,我在官网找了半天,连个jdbc驱动包下载入口都找不到,简直就是官方文档毫无诚 ...
- 解决 cv2.destroyAllWindows() 无效问题
方法一 示例代码: import cv2 import numpy as npimg = np.zeros((512,512),np.uint8)#生成一个空灰度图像 cv2.line(img,(0, ...
- 跑AI大模型的K8s与普通K8s有什么不同?
本文分享自华为云社区<跑AI大模型的K8s与普通K8s有什么不同?>,作者:tsjsdbd. 得益于AI开始火的时候,云原生体系已经普及,所以当前绝大多数的AI底层都是基于Kubernet ...
- 浅谈DWS函数出参方式
摘要:DWS的PL/pgSQL函数/存储过程中有一个特殊的语法PERFORM语法,用于执行语句但是丢弃执行结果的场景,常用于一些状态判断的场景. 本文分享自华为云社区<GassDB(DWS)功能 ...