Qt音頻輸出:QAudioOutput詳解與示例

1. 簡介

QAudioOutput是Qt多媒體框架中的一個關鍵類,它提供了將PCM(脈沖編碼調制)原始音頻數據發送到音頻輸出設備的接口。作為Qt多媒體組件的一部分,QAudioOutput允許開發者在應用程序中實現音頻播放功能,支持多種音頻格式和設備配置。

QAudioOutput的主要作用是將音頻數據流傳輸到系統音頻輸出設備,如揚聲器或耳機。它與QAudioInput類相對應,后者用于從音頻輸入設備(如麥克風)捕獲音頻數據。這兩個類共同構成了Qt音頻處理的基礎,為實現完整的音頻錄制、處理和播放流程提供了必要的工具。

在Qt多媒體架構中,QAudioOutput屬于較低級別的音頻處理API,它提供了對音頻硬件的直接訪問,使開發者能夠實現低延遲的音頻播放。相比之下,QMediaPlayer類則提供了更高層次的抽象,適用于播放常見格式的音頻和視頻文件,但可能無法滿足實時性和低延遲的需求。


2. 環境準備

  • 模塊依賴: 在.pro文件中添加?QT += multimedia

  • 頭文件:?#include <QAudioOutput>;#include<QAudioFormat>;#include<QAudioDeviceInfo>


3. 核心類介紹

3.1 QAudioOutput

  • 功能: 管理音頻輸出設備,控制播放狀態(播放/暫停/停止)。

  • 關鍵方法:

    • start(QIODevice*): 綁定輸入設備并開始播放。

    • stop(): 停止播放并釋放資源。

    • setVolume(float): 設置音量(0.0~1.0)。

3.2 QAudioFormat

  • 作用: 定義音頻格式參數,包括采樣率、聲道數、樣本大小等。

  • 常用設置:

    QAudioFormat format;
    format.setSampleRate(44100);     // 44.1kHz
    format.setChannelCount(2);       // 立體聲
    format.setSampleSize(16);        // 16位
    format.setCodec("audio/pcm");    // PCM編碼
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::SignedInt);

3.3 QIODevice

  • 角色: 作為音頻數據的來源(如文件、網絡流或內存緩沖區)。


4. 使用步驟

4.1 初始化音頻設備

// 創建音頻格式對象
QAudioFormat format;
// ...(設置format參數)// 檢查設備是否支持該格式
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format)) {qWarning() << "音頻格式不支持!";format = info.nearestFormat(format);  // 自動匹配最接近的格式
}// 創建QAudioOutput實例
QAudioOutput* audioOutput = new QAudioOutput(format, this);

4.2 準備音頻數據

 QFile audioFile("path/to/audio.pcm");if (!audioFile.open(QIODevice::ReadOnly)) {qDebug() << "無法打開音頻文件";return -1;}

4.3 播放音頻

audioOutput->start(&audioFile);  // 開始播放

5. 完整示例代碼

    // 配置音頻格式QAudioFormat format;format.setSampleRate(44100);format.setChannelCount(2);format.setSampleSize(16);format.setCodec("audio/pcm");format.setByteOrder(QAudioFormat::LittleEndian);format.setSampleType(QAudioFormat::SignedInt);// 檢查設備是否支持該格式QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());if (!info.isFormatSupported(format)) {qWarning() << "音頻格式不支持!";format = info.nearestFormat(format);  // 自動匹配最接近的格式}// 創建QAudioOutput對象QAudioOutput *audioOutput = new QAudioOutput(info,format, this);// 打開音頻文件QFile audioFile("path/to/audio.pcm");if (!audioFile.open(QIODevice::ReadOnly)) {qDebug() << "無法打開音頻文件";return -1;}
#if 1 //直接播放文件audioOutput->start(&audioFile);
#else //通過QIODevice的write寫入播放音頻,精準控制 // 獲取QIODevice用于數據傳輸QIODevice *device = audioOutput->start();if (!device) {qDebug() << "無法啟動音頻輸出";delete audioOutput;return -1;}// 傳輸音頻數據char buffer[4096];qint64 bytesWritten;while ((bytesWritten = audioFile.read(buffer, sizeof(buffer))) > 0) {// 寫入數據qint64 bytesFree = audioOutput->bytesFree();if (bytesFree >= bytesWritten) {device->write(buffer, bytesWritten);} else {// 如果緩沖區已滿,等待并重試QThread::msleep(10);device->write(buffer, bytesWritten);}}// 完成播放device->close();
#endifaudioOutput->stop();delete audioOutput;audioFile.close();

6. 常見問題與解決方案

6.1 無聲音輸出

可能原因

  • 音頻格式配置不正確

  • 設備選擇錯誤

  • 緩沖區管理不當

解決方案

  • 確保音頻格式配置正確,特別是采樣率、通道數和樣本格式

  • 檢查是否選擇了正確的音頻輸出設備

  • 確保音頻數據確實被正確傳輸到設備

6.2 音頻抖動或延遲

可能原因

  • 緩沖區大小不合適
  • 系統資源不足
  • 線程優先級設置不當

解決方案

  1. 調整緩沖區大小以平衡延遲和穩定性
  2. 確保應用有足夠資源
  3. 設置適當的線程優先級
// 調整緩沖區大小
format.setBufferSize(1024); // 嘗試較小的緩沖區以減少延遲

6.3 實時音頻處理

  • 建議: 繼承QIODevice并重寫readData(),動態生成或處理音頻流。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76985.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76985.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76985.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【計算機網絡】Linux配置SNAT/DNAT策略

什么是NAT&#xff1f; NAT 全稱是 Network Address Translation&#xff08;網絡地址轉換&#xff09;&#xff0c;是一個用來在多個設備共享一個公網 IP上網的技術。 NAT 的核心作用&#xff1a;將一個網絡中的私有 IP 地址&#xff0c;轉換為公網 IP 地址&#xff0c;從而…

Redis淘汰策略詳解!

目錄 一、為什么需要淘汰策略&#xff1f; &#x1f914;二、Redis 的淘汰策略詳解 &#x1f447;三、如何選擇合適的淘汰策略&#xff1f; &#x1f914;???四、如何切換 Redis 的淘汰策略&#xff1f; ??&#x1f527;五、總結 &#x1f389; &#x1f31f;我的其他文章…

存儲基石:深度解讀Linux磁盤管理機制與文件系統實戰

Linux系列 文章目錄 Linux系列前言一、磁盤1.1 初識磁盤1.2 磁盤的物理結構1.3 磁盤的存儲結構1.4 磁盤的邏輯結構 二、文件系統2.1 系統對磁盤的管理2.2 文件在磁盤中的操作 前言 Linux 文件系統是操作系統中用于管理和組織存儲設備&#xff08;如硬盤、SSD、USB 等&#xff…

本節課課堂總結

匿名子類&#xff1a; 說明 和 Java 一樣&#xff0c;可以通過包含帶有定義或重寫的代碼塊的方式創建一個匿名的子類。 單例對象&#xff08;伴生對象&#xff09; Scala語言是完全面向對象的語言&#xff0c;所以并沒有靜態的操作&#xff08;即在Scala中沒有靜態的概念&a…

I2C、SPI、UART、CAN 通信協議詳解

一、協議基本特性對比 特性ICSPIUARTCAN通信類型同步、半雙工同步、全雙工異步、全雙工異步、多主多從信號線SDA&#xff08;數據&#xff09;、SCL&#xff08;時鐘&#xff09;MOSI、MISO、SCK、SS&#xff08;片選&#xff09;TX&#xff08;發送&#xff09;、RX&#xff…

【diffusers 進階(十五)】dataset 工具,Parquet和Arrow 數據文件格式,load dataset 方法

系列文章目錄 【diffusers 極速入門&#xff08;一&#xff09;】pipeline 實際調用的是什么&#xff1f; call 方法!【diffusers 極速入門&#xff08;二&#xff09;】如何得到擴散去噪的中間結果&#xff1f;Pipeline callbacks 管道回調函數【diffusers極速入門&#xff0…

第十三章:持久化存儲_《鳳凰架構:構建可靠的大型分布式系統》

第十三章 持久化存儲 一、Kubernetes存儲設計核心概念 &#xff08;1&#xff09;存儲抽象模型 PersistentVolume (PV)&#xff1a;集群級別的存儲資源抽象&#xff08;如NFS卷/云存儲盤&#xff09;PersistentVolumeClaim (PVC)&#xff1a;用戶對存儲資源的聲明請求&#…

以太網安全

前言&#xff1a; 端口隔離可實現同一VLAN內端口之間的隔離。用戶只需要將端口加入到隔離組中&#xff0c;就可以實現隔離組內端口之間的二層數據的隔離端口安全是一種在交換機接入層實施的安全機制&#xff0c;旨在通過控制端口的MAC地址學習行為&#xff0c;確保僅授權設備能…

跨域問題前端解決

由于瀏覽器的同源策略&#xff0c;前后端分離的項目&#xff0c;調試的時候總是會遇到跨域的問題&#xff0c;這里通過修改前端代碼解決跨域問題。 首先先查看前端代碼的根目錄下&#xff0c;有沒有vue.config.js文件, 若有&#xff0c;使用方法1&#xff0c;若沒有此文件&…

Elasticsearch 報錯index_closed_exception

index_closed_exception 是 Elasticsearch 中的一個異常類型&#xff0c;它通常發生在嘗試對一個已經被關閉&#xff08;closed&#xff09;的索引執行搜索、寫入或其他操作時。在 Elasticsearch 中&#xff0c;索引是用來存儲和檢索數據的邏輯命名空間&#xff0c;可以將其類比…

LearnOpenGL-筆記-其九

今天讓我們完結高級OpenGL的部分&#xff1a; Instancing 很多時候&#xff0c;在場景中包含有大量實例的時候&#xff0c;光是調用GPU的繪制函數這個過程都會帶來非常大的開銷&#xff0c;因此我們需要想辦法在每一次調用GPU的繪制函數時盡可能多地繪制&#xff0c;這個過程就…

PDF預覽-搜索并高亮文本

在PDF.js中實現搜索高亮功能可以通過自定義一些代碼來實現。PDF.js 是一個通用的、基于Web的PDF閱讀器&#xff0c;它允許你在網頁上嵌入PDF文件&#xff0c;并提供基本的閱讀功能。要實現搜索并高亮顯示文本&#xff0c;你可以通過以下幾個步驟來完成&#xff1a; 1. 引入PDF…

二叉樹——隊列bfs專題

1.N叉樹的層序遍歷 我們之前遇到過二叉樹的層序遍歷&#xff0c;只需要用隊列先進先出的特性就可以達到層序遍歷的目的。 而這里不是二叉樹&#xff0c;也就是說讓節點的孩子入隊列時不僅僅是左右孩子了&#xff0c;而是它的所有孩子。而我們看這棵多叉樹的構造&#xff0c;它…

Python高級爬蟲之JS逆向+安卓逆向1.1節-搭建Python開發環境

目錄 引言&#xff1a; 1.1.1 為什么要安裝Python? 1.1.2 下載Python解釋器 1.1.3 安裝Python解釋器 1.1.4 測試是否安裝成功 1.1.5 跟大神學高級爬蟲安卓逆向 引言&#xff1a; 大神薯條老師的高級爬蟲安卓逆向教程&#xff1a; 這套爬蟲教程會系統講解爬蟲的初級&…

Windows 安裝和使用 ElasticSearch

SpringBoot3 整合 Elasticsearch 1. ElasticSearch 1.1 ES &#xff08;1&#xff09;ES 是一個開源的分布式搜索和分析引擎&#xff0c;專為處理大模型數據而設計&#xff0c;它能夠實現近乎實時的數據檢索、分析和可視化&#xff0c;廣泛用于全文搜索、日志分析和監控&…

matplotlib初探

庫引入 import matplotlib.pyplot as pltpyplot.figure 創建新圖形或激活現有圖形

NVM 多版本Node.js 管理全指南(Windows系統)

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、全棧領域優質創作者、高級開發工程師、高級信息系統項目管理師、系統架構師&#xff0c;數學與應用數學專業&#xff0c;10年以上多種混合語言開發經驗&#xff0c;從事DICOM醫學影像開發領域多年&#xff0c;熟悉DICOM協議及…

實驗室預約|實驗室預約小程序|基于Java+vue微信小程序的實驗室預約管理系統設計與實現(源碼+數據庫+文檔)

實驗室預約小程序 目錄 基于微信小程序的實驗室預約管理系統設計與實現 一、前言 二、系統功能設計 三、系統實現 1、微信小程序前臺 2、管理員后臺 &#xff08;1&#xff09;管理員登錄 &#xff08;2&#xff09;實驗室管理 &#xff08;3&#xff09;公告信息管理…

SpringBoot底層-數據源自動配置類

SpringBoot默認使用Hikari連接池&#xff0c;當我們想要切換成Druid連接池&#xff0c;底層原理是怎樣呢 SpringBoot默認連接池——Hikari 在spring-boot-autoconfiguration包內有一個DataSourceConfiguraion配置類 abstract class DataSourceConfiguration {Configuration(p…

面試算法高頻03-遞歸

認識遞歸 遞歸的概念與特性&#xff1a;遞歸本質類似循環&#xff0c;是通過函數體進行的循環操作。借助電影《盜夢空間》類比&#xff0c;遞歸如同主角在不同夢境層穿梭&#xff0c;向下進入不同遞歸層&#xff0c;向上能回到原來一層&#xff0c;每一層環境和周圍元素相似&a…