QT编程之PCM音频处理

news/2025/3/26 1:05:28/

一、高级播放接口(未压缩编码的音频文件)

  1. QMediaPlayer

    • 支持MP3/WMA等压缩格式及网络流媒体播放,集成媒体控制(播放/暂停/进度调节)
    • 需设置QAudioOutput指定输出设备,支持播放速度调节(setPlaybackRate)‌
    • 代码示例:
      QMediaPlayer player;
      player.setSource(QUrl::fromLocalFile("audio.mp3"));
      player.play();  // 开始播放‌
  2. QSoundEffect
    1.专为低延迟音效设计,适合游戏/UI反馈音,支持WAV格式
    2.支持循环播放(setLoopCount)和实时音量调节‌
    3.代码示例:
    QSoundEffect effect;
    effect.setSource(QUrl::fromLocalFile("beep.wav"));
    effect.play();  // 延迟低于50ms‌

二、底层音频控制

  • QAudioOutput/QAudioSink
    • 直接处理PCM数据流,适合FFmpeg解码后的原始音频播放
    • Qt5使用QAudioOutput,Qt6重命名为QAudioSink,需指定采样率/声道数等参数‌
    • 典型应用:
      QAudioFormat format;
      format.setSampleRate(44100);
      format.setChannelCount(2);
      QAudioSink sink(format);
      sink.start(data_device);  // data_device提供PCM数据流‌

三、PCM音频播放

Qt5/Qt6通用方案

// 头文件包含
#include <QFile>
#include <QAudioFormat>
#include <QAudioOutput>  // Qt5
#include <QAudioSink>    // Qt6// 创建音频格式
QAudioFormat format;
format.setSampleRate(44100);       // 采样率需与PCM文件一致‌
format.setChannelCount(2);         // 声道数(1=单声道,2=立体声)‌
format.setSampleFormat(QAudioFormat::Int16);  // 位深(必须与PCM编码匹配)‌// 打开PCM文件
QFile pcmFile("audio.pcm");
if(pcmFile.open(QIODevice::ReadOnly)) {// 检查设备支持QAudioDevice device = QMediaDevices::defaultAudioOutput();if(!device.isFormatSupported(format)) {qWarning() << "不支持的音频格式";  // 需调整参数重试‌return;}// 创建播放对象(Qt5用QAudioOutput, Qt6用QAudioSink)#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QAudioOutput* audioOutput = new QAudioOutput(format);audioOutput->start(&pcmFile);  // 启动播放‌#elseQAudioSink* audioSink = new QAudioSink(format);audioSink->start(&pcmFile);    // Qt6新版API‌#endif
}

关键参数说明

参数典型值注意事项
采样率8000/44100/48000 Hz必须与PCM文件生成时一致‌
样本格式Int16/UInt8/FloatFFmpeg常用s16le对应Int16‌
缓冲区大小4000-8192 bytes过小导致卡顿,过大会增加延迟‌

四、 PCM转WAV

// 添加WAV文件头(44字节)
struct WAVHeader {char riff‌[] = {'R','I','F','F'};uint32_t fileSize;      // 文件总大小-8char wave‌[] = {'W','A','V','E'};// ... 其他字段根据参数填充‌
};QFile wavFile("audio.wav");
wavFile.open(QIODevice::WriteOnly);
wavFile.write((char*)&header, sizeof(WAVHeader));  // 写入头信息‌
wavFile.write(pcmData);  // 追加PCM数据‌

五、开发注意事项

  1. 跨平台兼容性

    • Linux需安装pulseaudioalsa-lib驱动‌
    • Windows/Mac需确认音频设备支持指定格式‌
    • 结构体使用#pragma pack(1)避免对齐问题‌
  2. 实时音频处理

    • 采集使用QAudioInput,与播放代码结构类似‌
    • 网络传输时建议分块发送(每帧1024样本)‌
  3. 性能优化

    • 启用QIODevice::Unbuffered模式降低延迟‌
    • 多线程处理:解码/采集与播放分离‌


http://www.ppmy.cn/news/1582605.html

相关文章

React优化性能的hooks,Class类组件,zustand--Redux平替

文章目录 useReducer基础用法 useMemoReact.memoprops的比较机制 useCallbackReact.forwardRefuseInperativeHandleClass API类组件基础结构类组件的生命周期类组件的组件通信 zustand---Redux平替使用方法异步支持切片模式 useReducer 和useState作用类似&#xff0c;用来管理…

JVM垃圾回收算法有哪些

标记-清除算法&#xff1a;标记-清除算法分为"标记"和"清除"两个阶段&#xff0c;首先通过可达性分析&#xff0c;标记出所有需要回收的对象&#xff0c;然后统一回收所有被标记的对象。标记-清除算法有两个缺陷&#xff0c;一个是效率问题&#xff0c;标记…

银联无感支付实现

云闪付无感支付&#xff0c;又称云闪付APP/云微小程序免密支付&#xff0c;用户授权签约后即可在额度范围内进行免密支付。商户凭借签约协议号发起后台扣款&#xff0c;扣款根据用户在云闪付APP/云微小程序上排列的银行卡顺序进行依次扣款&#xff0c;直至扣款成功或失败。 1.整…

黑客攻击deepseek服务原理解析

黑客可通过操纵大模型的连续对话上下文回顾机制&#xff0c;构造恶意请求以触发模型进入无限思考循环或超长上下文处理&#xff0c;从而形成对对话服务的DoS攻击&#xff08;拒绝服务攻击&#xff09;。这一攻击方式的核心在于利用大模型对上下文处理机制的脆弱性&#xff0c;通…

Android Coil3阶梯preload批量Bitmap拼接扁平宽图,Kotlin

Android Coil3阶梯preload批量Bitmap拼接扁平宽图&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-p…

ES如果要查10条数据需要从各个分片上各取多少条数据?

目录 ES如果要查10条数据需要从各个分片上各取多少条数据? 简单查询(如 match_all 或 term 查询) 深度分页查询(如 from + size 查询) 聚合查询 什么叫聚合查询? 聚合查询的基本结构 常见的聚合类型 聚合查询的执行过程 聚合查询的示例 聚合查询的应用场景 注意…

⭐算法OJ⭐判断二叉搜索树【树的遍历】(C++实现)Validate Binary Search Tree

图论入门【数据结构基础】&#xff1a;什么是树&#xff1f;如何表示树&#xff1f; 之前我们有分别讲解二叉树的三种遍历的相关代码实现&#xff1a; ⭐算法OJ⭐二叉树的前序遍历【树的遍历】&#xff08;C实现&#xff09;Binary Tree Preorder Traversal ⭐算法OJ⭐二叉树的…

《深度学习》—— YOLOv1

文章目录 YOLO简介YOLOv1简介核心思想网络结构评价指标非极大值抑制损失函数检测流程优缺点 YOLO简介 YOLOv1简介 YOLOv1&#xff08;You Only Look Once version 1&#xff09;是一种用于目标检测的开创性实时算法&#xff0c;由 Joseph Redmon 等人在 2016 年提出。它将目标…