当前位置: 首页 > news >正文

Qt源码-Qt多媒体音频框架

Qt 多媒体音频框架

  • 一、概述
  • 二、音频设计
    • 1. ALSA 基础
    • 2. Qt 音频类
      • 1. 接口实现
      • 2. alsa 插件实现

一、概述

环境详细
Qt版本Qt 5.15
操作系统Deepin v23
代码工具Visual Code
源码https://github.com/qt/qtmultimedia/tree/5.15

这里记录一下在Linux下Qt 的 Qt Multimedia 模块的设计,我目前先记录与音频相关的库的设计。不同Qt版本的设计有些不一样,需要看对应版本的源码设计。

二、音频设计

1. ALSA 基础

ALSA是 Advanced Linux Sound Architecture的缩写,即高级Linux声音架构。在Linux 2.6的内核版本后,ALSA目前已经成为了Linux的主流音频体系结构。
在这里插入图片描述

2. Qt 音频类

1. 接口实现

最重要的就是 QAudioInput和QAudioOutput两个类,作为音频输入输出的类。
在这里插入图片描述
这个类的源码位置在

src/multimedia/audio/qaudioinput.cpp

那我们开始看 QAudioInput 类的关键实现吧,在 qaudioinput.cpp 中都是使用的 qaudioinput.h 头文件中 QAbstractAudioInput 类型的 d 的成员方法。

如 QAudioInput::start() 实际使用的是 d->start();

// qaudioinput.h
private:QAbstractAudioInput* d;
// qaudioinput.cpp
void QAudioInput::start(QIODevice* device)
{d->start(device);
}
....
QAudioFormat QAudioInput::format() const
{return d->format();
}

在 QAudioInput 构造函数中,得知是d 是由工厂类 QAudioDeviceFactory 创建的

src/multimedia/audio/qaudiodevicefactory.cpp
QAudioInput::QAudioInput(const QAudioFormat &format, QObject *parent):QObject(parent)
{d = QAudioDeviceFactory::createDefaultInputDevice(format);...
}

QAudioDeviceFactory 工厂通过 createDefaultInputDevice() ⇒ \Rightarrow createInputDevice() 函数调用。所以具体就看 createInputDevice() 函数实现 就可以了。

QAbstractAudioInput* QAudioDeviceFactory::createDefaultInputDevice(QAudioFormat const &format)
{return createInputDevice(defaultDevice(QAudio::AudioInput), format);
}
QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format)
{if (deviceInfo.isNull())return new QNullInputDevice();#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)QAudioSystemFactoryInterface* plugin =qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(deviceInfo.realm()));if (plugin) {QAbstractAudioInput* p = plugin->createInput(deviceInfo.handle());if (p) p->setFormat(format);return p;}
#endifreturn new QNullInputDevice();
}

上面 createInputDevice 中 QAbstractAudioInput *p 就是 通过 audioLoader 加载的插件 plugin 创建出的。这样不同系统可以实现不同的插件,根据系统做到跨平台性。

QAudioSystemFactoryInterface* plugin 就是插件的接口父类。

在创建失败的时候,QAudioDeviceFactory 工厂也通过定义 QNullInputDevice 类。保证插件系统正常运行。

让我们看看QNullInputDevice 在 qaudiodevicefactory.cpp 的定义

class QNullInputDevice : public QAbstractAudioInput
{
public:void start(QIODevice*) override { qWarning()<<"using null input device, none available";}QIODevice *start() override { qWarning()<<"using null input device, none available"; return nullptr; void setBufferSize(int ) override {}int bufferSize() const override  { return 0; }
...void setVolume(qreal) override {}qreal volume() const override {return 1.0f;}
};

2. alsa 插件实现

那让我们继续看看音频功能的具体实现,音频插件的源码工程位置在 `

src/pligins/alsa/alsa.pro

在下面我们可以看到,不同平台的不同实现,有Linux、Windows、Android等。在我WIndows电脑的Qt5.14.2 上音频库则是使用的
windowsaudio 工程
在这里插入图片描述

我们找到Linux的alsa工程,从工程文件可以得到这个插件的名字叫 qtaudio_alsa
在这里插入图片描述
这个插件最后生成的名字叫 libqtaudio_alsa.so

在我的系统中安装的位置在

/usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtaudio_alsa.so	

在这里插入图片描述

下面继续介绍这个插件

qalsaplugin.cpp:就是生成插件的接口类,对外使用,内部使用了ALSA实现功能

qalsaaudiodeviceinfo.cpp:封装的 音频设备信息,功能QAudioDeviceInfo 功能
qalsaaudioinput.cpp :音频输入类,实际 QAudioInput 的实现
qalsaaudiooutput.cpp:音频输出类,实际的 QAudioOutput 的实现

下面就是 qalsaaudioinput 的open函数实现,可以看到open函数使用了 snd_pcm_open 函数:

bool QAlsaAudioDeviceInfo::open()
{int err = 0;QString dev;if (!availableDevices(mode).contains(device.toLocal8Bit()))return false;#if SND_LIB_VERSION < 0x1000e  // 1.0.14if (device.compare(QLatin1String("default")) != 0)dev = deviceFromCardName(device);else
#endifdev = device;if(mode == QAudio::AudioOutput) {err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0);} else {err=snd_pcm_open( &handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);}if(err < 0) {handle = 0;return false;}return true;
}

相关文章:

Qt源码-Qt多媒体音频框架

Qt 多媒体音频框架 一、概述二、音频设计1. ALSA 基础2. Qt 音频类1. 接口实现2. alsa 插件实现 一、概述 环境详细Qt版本Qt 5.15操作系统Deepin v23代码工具Visual Code源码https://github.com/qt/qtmultimedia/tree/5.15 这里记录一下在Linux下Qt 的 Qt Multimedia 模块的设…...

卸载PLSQL及标准卸载流程

目录 1. 卸载PLSQL2. 删除注册表3. 删除数据信息 1. 卸载PLSQL 等待进度条走完 2. 删除注册表 regedit 右击删除 3. 删除数据信息 由于AppData是隐藏文件&#xff0c;需要勾选隐藏的项目。 重启电脑&#xff0c;PLSQL就卸载成功了。...

如何使用ssm实现办公OA系统0

TOC 10907ssm办公OA系统10907ssm0 第一章 绪 论 1.1背景及意义 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于办公OA系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;主页、个人中心、公司公告管理、设备分类管理、办公设备管理、…...

IPguard与Ping32—选择合适的企业数据保护解决方案

在数字化时代&#xff0c;企业面临着各种数据安全挑战&#xff0c;选择合适的保护工具至关重要。IPguard与Ping32是两款备受关注的数据保护软件&#xff0c;但它们各自的功能和适用场景有所不同&#xff0c;企业在选择时需根据自身需求做出明智决策。 Ping32&#xff1a;全面的…...

2024 kali虚拟机安装教程,分两大步骤,图文讲解(2)

准备工作&#xff1a; 按照图文讲解&#xff08;1&#xff09;搭建好虚拟机&#xff0c;继续以下步骤 2024 kali虚拟机安装教程&#xff0c;分两大步骤&#xff0c;图文讲解&#xff08;1&#xff09;-CSDN博客 正式开始 1.开启&#xff0c;↑ ↓ 方向键&#xff0c;选择第一…...

【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem

git clone 是 Git 版本控制系统中的一个基本命令&#xff0c;用于从远程仓库复制一个完整的版本库到本地。这个命令不仅复制远程仓库中的所有文件&#xff0c;还复制仓库的历史记录&#xff0c;使得你可以在本地进行版本控制操作&#xff0c;如提交&#xff08;commit&#xff…...

基于STM32的智能家居--硬件接线

分配GPIO 1.首先分配串口通讯引脚&#xff0c;该开发板中有三组串口引脚分别分配如图所示。 2.分配SPI。 3.其他为普通GPIO口&#xff0c;B8,B9模拟IIC协议与OLED屏幕进行通讯。...

mac电脑如何删除应用程序?怎么删除苹果电脑里的软件

在使用Mac电脑的过程中&#xff0c;随着时间的推移&#xff0c;我们可能会安装大量的应用程序。然而&#xff0c;这些应用程序中有很多可能只是临时使用&#xff0c;或者已经不再需要了。这些无用的应用程序不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢Mac系统的运行速度。…...

Hive优化操作(一)

Hive SQL 优化指南 在使用 Hive 进行数据分析时&#xff0c;提高查询性能至关重要。以下是一些具体的优化策略&#xff0c;帮助我们在工作中更有效地管理和查询数据。 一、 减少数据量进行优化 1. 分区表优化 分区是一种表的子集&#xff0c;用于按某一列&#xff08;如日期…...

Vue中常用指令——(详解,并附有代码)

文章目录 一.指令合集1.0 概述1.1 插值表达式1.2 v-text/v-html1.3 v-show/ v-if1.4 v-on1.4.1 内联语句1.4.2 事件处理函数 1.5 v-bind1.6 Test1.7 v-for 一.指令合集 内容渲染指令&#xff08;v-html、v-text&#xff09;条件渲染指令&#xff08;v-show、v-if、v-else、v-e…...

redistemplate实现点赞相关功能

使用Redis的SET数据结构来存储每个实体的点赞用户ID列表&#xff0c;方便进行点赞数量的计数和用户点赞状态的检查。以下是一个小demo&#xff0c;只提供简单思路。 Service public class LikeService {Autowiredprivate RedisTemplate redisTemplate;//点赞public Long like(…...

C++ 算法学习——7.4.1 优化算法——双指针

双指针法&#xff08;Two Pointers&#xff09;是一种常用的算法技巧&#xff0c;通常用于解决数组或链表中的问题。这种技巧通过维护两个指针&#xff0c;通常分别指向数组或链表的不同位置&#xff0c;来协同解决问题。双指针法一般有两种类型&#xff1a;快慢指针和左右指针…...

镁光DDR3的命名

64M16的解释如图。 125是指一个时钟周期需要1.25ns走完&#xff0c;1us对应 1MHZ, 1ns对应1000MHZ ,那么1.25ns对应的时钟频率&#xff0c;就先用 1/1.25得到 1.25us对应的时钟频率 0.8 &#xff0c;然后再乘以1000&#xff0c;得到800就是MHZ 带宽的计算就是 800M…...

[Git] Git下载及使用 从入门到精通 详解(附下载链接)

前言 目录 Git概述 简介 下载 Git代码托管服务 Git常用命令 Git全局配置 获取Git仓库 在本地初始化一个Git仓库 从远程仓库克隆 基本概念 工作区文件状态 本地仓库操作 远程仓库操作 分支操作 标签操作 在IDEA中使用Git 在IDEA中配置Git 本地仓库操作 远程仓…...

Linux源码阅读笔记-USB驱动分析

基础层次详解 通用串行总线&#xff08;USB&#xff09;主要用于连接主机和外部设备&#xff08;协调主机和设备之间的通讯&#xff09;&#xff0c;USB 设备不能主动向主机发送数据。USB 总线采用拓扑&#xff08;树形&#xff09;&#xff0c;主机侧和设备侧的 USB 控制器&a…...

【超级详细解释】力扣每日一题 134.加油站 48. 旋转图像

134.加油站 力扣 这是一个很好的问题。这个思路其实基于一种贪心策略。我们从整个路径的油量变化来理解它&#xff0c;结合一个直观的“最低点法则”&#xff0c;来确保找到正确的起点。 问题的核心&#xff1a;油量差值的累积 对于每个加油站&#xff0c;我们有两个数组&…...

数据挖掘基本架构知识点

数据挖掘的基本架构主要包含以下几个部分&#xff1a; 一、数据获取 1. 数据源 - 可以是数据库&#xff08;如关系型数据库MySQL、Oracle等&#xff09;、文件系统&#xff08;如CSV文件、XML文件等&#xff09;、网络数据&#xff08;如网页内容、社交媒体数据&#xff09;等…...

LangChain中使用Prompt01

1.引入提示模板 from langchain.prompts import (SystemMessagePromptTemplate,AIMessagePromptTemplate,HumanMessagePromptTemplate, )2.设置系统提示 system_template_text"你是一位专业的翻译&#xff0c;能够将{input_language}翻译成{output_language}&#xff0c…...

如何使用bpmn-js实现可视化流程管理

介绍 BPMN-JS是一个流行的开源库&#xff0c;用于在Web应用程序中可视化、创建、编辑和分析BPMN&#xff08;Business Process Model and Notation&#xff0c;业务流程建模与表示法&#xff09;2.0 图。BPMN是一种国际标准的图形化语言&#xff0c;用于描述企业中的业务流程&a…...

【PostgreSQL 】实战篇——如何使用 EXPLAIN 和 ANALYZE 工具分析查询计划和性能,优化查询

在数据库管理中&#xff0c;优化查询性能是确保应用程序高效运行的关键因素之一。 随着数据量的不断增长和复杂查询的增多&#xff0c;理解查询的执行计划变得尤为重要。 PostgreSQL 提供了强大的工具 EXPLAIN 和 ANALYZE&#xff0c;帮助开发者分析查询计划和性能&#xff0…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...