概述

最近在对接百度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文件头信息的更多相关文章

  1. sublime 设置新建文件自动添加author(作者)等文件头信息

    很多时候, sublime 自带自动添加文件头信息, 但是并不是我们想要比如下面这样的:新建一个python文件 自动添加的author 信息== 上面并不是我想要的, 我想要下面这样的效果:== 这 ...

  2. 给pcm格式文件加wav文件头

    #include <stdlib.h>#include <stdio.h>#include <string.h>void main(){ //wav头的结构如下所示 ...

  3. eclipse快速配置spring相关xml文件头信息

    通过spring tools 插件工具来快速配置xml头信息 ctrl +n 创建-----------> 输入spring 选中spring Beann Configuration File ...

  4. FFmpeg命令行工具学习(一):查看媒体文件头信息工具ffprobe

    一.简述 ffprobe是ffmpeg命令行工具中相对简单的,此命令是用来查看媒体文件格式的工具. 二.命令格式 在命令行中输入如下格式的命令: ffprobe [文件名] 三.使用ffprobe查看 ...

  5. Pycharm中.py文件头信息配置

    在社区版的Pycharm开发软件中设置每次新建.py文件都会自动生成如下信息 #! /usr/bin/env python # -*- coding:utf-8 -*- # Author: Tdcqm ...

  6. WAV文件头相关资料

    http://stackoverflow.com/questions/6284651/avaudiorecorder-doesnt-write-out-proper-wav-file-header h ...

  7. DCMTK读取DICOM文件头信息的三种方法

    Howto: Load File Meta-Header Here's an example that shows how to load the File Meta Information Head ...

  8. php通过文件头检测文件类型通用类(zip,rar…)(转)

    在做web应用时候,通过web扩展名判断上存文件类型,这个是我们常使用的.有时候我们这样做还不完善.可能有些人上存一些文件,但是他通过修改 扩展名,让在我们的文件类型之内. 单实际访问时候又不能展示( ...

  9. java通过文件头来判断文件类型

    import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.ut ...

  10. pycharm新建py文件时,自动补充文件头注释信息

    步骤: 1.File -->Settings 2.选择 File and Code Templates -> Files -> Python Script 文件头注释信息代码样式: ...

随机推荐

  1. [CF1416F] Showing Off

    题目链接 如果把方向看做有向边,整个图是一个内向基环树. 所以考虑哪些点有可能放在基环树的非环部分上,当且仅当一个点周围有严格小于他的点. 由于图一定是二分图(黑白染色),没有奇环,所有偶环一定可以拆 ...

  2. 01 MyBatis第一个应用程序

    1.MyBatis是什么? mybatis是一个基于java的持久层框架. 2.什么是持久化 数据由瞬态状态变为持久状态. 3.持久层: 完成持久化工作的代码块. -- DAO层,将数据存到数据库 4 ...

  3. POJ1006、hdu1370

    思路:中国剩余定理.纯粹的用暴力求逆元. 1 #include<iostream> 2 #include<string.h> 3 #include<string> ...

  4. Celery架构和主要模块

    **任务模块 ** 包含异步任务和定时任务.其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列. **消息中间件 Broker * ...

  5. Windows Server 2016 Standard RemoteApp应用发布配置举例

    RemoteApp 应用发布介绍 RemoteApp 是微软在Windows Server 2008 之后,在其系统中集成的一项服务功能,用户可以通过远程桌面访问远端服务器的桌面与程序,客户端本机在无 ...

  6. BFS(二)转动转盘锁

    对应 LeetCode 752.转动转盘锁 ### 问题定义 你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', ...

  7. Android 事件分发介绍

    目录 一.目的 二.环境 三.相关概念 3.1 事件分发 四.详细设计 4.1应用布局 4.1.1 应用布局结构 4.1.2 LayoutInspector 4.2 关键View&方法 4.2 ...

  8. 深入剖析 Linux Cgroups 子系统:资源精细管理

    本章主要演示以下 cgroups 下各个 subsystem 的作用. 根据难易程度,依次演示了 pids .cpu 和 memory 3 个 subsystem 的使用. 注:本文所有操作在 Ubu ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (144)-- 算法导论12.1 4题

    四.用go语言,对于一棵有 n 个结点的树,请设计在 O(n)时间内完成的先序遍历算法和后序遍历算法. 我个人喜欢 灵小智 . 文心一言: 在 Go 语言中,我们可以使用递归来实现树的前序遍历和后序遍 ...

  10. LeetCode DFS、BFS篇(102、200、111、752)

    102. 二叉树的层序遍历 给你一个二叉树,请你返回其按 层序遍历 得到的节点值. (即逐层地,从左到右访问所有节点). 示例: 二叉树:[3,9,20,null,null,15,7], 3 / 9 ...