【语音识别】一些音频的使用方法

文章目录

  • [1 多通道PCM字节流单通道PCM字节流【多通道转单通道】](#1 多通道PCM字节流单通道PCM字节流【多通道转单通道】)
  • [2 其他采样率PCM转换为16KHZ PCM](#2 其他采样率PCM转换为16KHZ PCM)
  • [3 采样精度(每个采样点用多少个字节存储)](#3 采样精度(每个采样点用多少个字节存储))
    • [3.1 精度对应解释](#3.1 精度对应解释)
    • [3.2 转换24-bit PCM -> 16-bit PCM](#3.2 转换24-bit PCM -> 16-bit PCM)
    • [3.3 8-bit PCM -> 16-bit PCM](#3.3 8-bit PCM -> 16-bit PCM)
    • [3.4 32-bit PCM -> 16-bit PCM](#3.4 32-bit PCM -> 16-bit PCM)
  • [4 `main`函数](#4 main函数)
  • [5 总结](#5 总结)

1 多通道PCM字节流单通道PCM字节流【多通道转单通道】

python 复制代码
def pcm_multichannel_to_mono(pcm_bytes, channels):
    """
    pcm_bytes: 多通道 PCM byte 流(int16, interleaved)
    channels: 声道数(如 2 / 4)
    """
    # 输入的是PCM二进制字节流 int16格式  输出->int16数组
    pcm = np.frombuffer(pcm_bytes, dtype=np.int16)
    # 确保长度合法
    assert pcm.size % channels == 0, "PCM length not divisible by channels"
    # (frames, channels)
    """
    输出示例:
	    	[[100 200]
	 		[101 201]
	 		[102 202]]
	 """
    pcm = pcm.reshape(-1, channels)
    # 混音:简单平均(防止溢出)
    mono = pcm.mean(axis=1)
    # clip + int16
    # 将数据类型从float 转回 int6
    mono = np.clip(mono, -32768, 32767).astype(np.int16)	# numpy格式
    return mono.tobytes()

 numpy转PCM流:
mono.tobytes()

 PCM流转numpy数组:
pcm = np.frombuffer(pcm_bytes, dtype=np.int16)

2 其他采样率PCM转换为16KHZ PCM

python 复制代码
def pcm8To16(data, input_rate, output_rate):
    pcm = np.frombuffer(data, dtype=np.int16)        # PCM->numpy (int16)
    pcm_16k = soxr.resample(                         # 8K numpy -> 16K numpy
        pcm,
        in_rate=input_rate,
        out_rate=output_rate,
        quality='HQ'
    )
    pcm_16k = np.clip(pcm_16k, -32768, 32767).astype(np.int16)  #
    pcm_bytes_16k = pcm_16k.tobytes()
    return pcm_bytes_16k

3 采样精度(每个采样点用多少个字节存储)

3.1 精度对应解释

数据类型 bit 数 dtype 范围 说明
int16 16 np.int16 -32768 ~ 32767 常见的 PCM 音频,支持正负波形,左右对称,WAV 文件最常用
uint8 8 np.uint8 0 ~ 255 8-bit PCM,没有负数,中值 128 表示静音,0/255 表示最大幅度
float32 32 np.float32 -1.0 ~ 1.0 归一化音频,AI/ASR/深度学习常用

各个采样精度之间的转换

查看音频的原生精度:

python 复制代码
audio_path = r"asr_en.wav"
wf = wave.open(audio_path)
logger.warning(f"原始音频格式:"
               f"{wf.getnchannels(),wf.getframerate(),wf.getsampwidth()}")
print(wf.getsampwidth())

这里的wf.getsampwidth()表示精度。

sampwidth PCM 位深 常见 dtype 是否有坑
1 8-bit PCM uint8 ⚠️ 有偏置
2 16-bit PCM int16 ✅ 标准
3 24-bit PCM ❌ 🚨 大坑
4 32-bit PCM int32 / float ⚠️

3.2 转换24-bit PCM -> 16-bit PCM

python 复制代码
# 24-bit PCM -> 16-bit PCM
def pcm24_to_int16(pcm_bytes, channels):
    # 每个 sample 3 字节
    pcm = np.frombuffer(pcm_bytes, dtype=np.uint8)

    # 对齐
    pcm = pcm[: (pcm.size // 3) * 3]

    pcm = pcm.reshape(-1, 3)

    # 小端拼接(WAV 默认 little-endian)
    samples = (
            pcm[:, 0].astype(np.int32)
            | (pcm[:, 1].astype(np.int32) << 8)
            | (pcm[:, 2].astype(np.int32) << 16)
    )

    # 符号扩展
    samples = np.where(
        samples & 0x800000,
        samples | ~0xFFFFFF,
        samples
    )

    # 24bit → 16bit(右移 8 位)
    pcm_i16 = (samples >> 8).astype(np.int16)

    return pcm_i16

3.3 8-bit PCM -> 16-bit PCM

python 复制代码
def pcmu8_to_int16(pcm_bytes):
    pcm_u8 = np.frombuffer(pcm_bytes, dtype=np.uint8)
    # 去偏置 → 放大
    pcm_i16 = (pcm_u8.astype(np.int16) - 128) << 8
    return pcm_i16

3.4 32-bit PCM -> 16-bit PCM

python 复制代码
def pcmint32_to_int16(pcm_bytes):
    pcm_i32 = np.frombuffer(pcm_bytes, dtype=np.int32)
    pcm_i16 = (pcm_i32 >> 16).astype(np.int16)
    return pcm_i16

4 main函数

python 复制代码
# -------------------------------------
# 保存文件
# -------------------------------------
out_wav = wave.open("output_16k_mono.wav", "wb")
out_wav.setnchannels(1)        # 单声道
out_wav.setsampwidth(2)        # int16 = 2 bytes
out_wav.setframerate(16000)    # 16 kHz

# -------------------------------------
# 读取文件,通道,采样率,PCM位深
# -------------------------------------
audio_path = r"E:\1_ALL_Dataste\音频数据集\本地中文语音训练\印度英文报告-1.wav"
wf = wave.open(audio_path)
logger.warning(f"原始音频格式:"
               f"{wf.getnchannels(),wf.getframerate(),wf.getsampwidth()}")
rawRate = wf.getframerate()
chunk = 960

while True:
    data = wf.readframes(chunk)                                    # (2, 44100, 2)
    data_1channel = pcm_multichannel_to_mono(data, 2)              # 转通道
    data_16K = pcm8To16(data_1channel, rawRate, 16000)          	# 采样率
    if not data_16K:
        break
    out_wav.writeframes(data_16K)
    print(data_16K)

5 总结

 

 
从读取文件开始,音频通常以PCM二进制流,numpy或者base64的格式存在,音频的主要参数有三个:通道数(channel)、采样率(rate)、位深。

 

 

                      写于2026.2.4

相关推荐
秦先生在广东2 分钟前
Orca:并行 AI 代理管理的开源 ADE 深度解析
人工智能
段一凡-华北理工大学5 分钟前
大模型与智能体在工业的应用~系列文章07:多智能体协作:会分工的“AI 团队“
大数据·人工智能·设备巡检·智能体协作·工业智能体·高炉大模型
秦先生在广东8 分钟前
微小型双足鸭形机器人系统深度解析:强化学习驱动的开源架构
人工智能
AI科技先锋报19 分钟前
2026企业级Data Agent开发平台有哪些:主流DataAgent开发框架全景解析
大数据·人工智能
IT_陈寒33 分钟前
Java线程池这破玩意,差点让我周末加班排查到凌晨
前端·人工智能·后端
广州山泉婚姻35 分钟前
Go微服务落地:服务通信、注册发现完整实现分享
人工智能·深度学习·微服务
W***259239 分钟前
2026 企业 AI 办公工具选型指南:适合团队使用的 AI 办公产品有哪些
大数据·人工智能
码农5991 小时前
让 Agent 替你看 Bug:简单示例读懂 MCP 服务
人工智能
AC赳赳老秦1 小时前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
四六的六1 小时前
Agent 长会话设计实战:从对话上下文到持久状态,把记忆写进检查清单
人工智能·个人开发·ai编程·ai产品·长上下文·ai代码生成·ai会话