瀏覽代碼

添加全局的默认混音配置

zhuizhu 8 月之前
父節點
當前提交
cfc2645ef9

+ 25 - 1
AvRecorder/basic/basic.h

@@ -74,10 +74,34 @@ inline void SleepMs(int timeMs)
     std::this_thread::sleep_for(std::chrono::milliseconds(timeMs));
 }
 
-// 对于音频编码器的全局设置
+// =================== 音频全局设置 ===================
+// 此处配置影响全局的音频捕获和编码参数,旨在平衡音质与文件大小。
+
+// --- 采样率 (Sample Rate) ---
+// 48000 Hz: 专业音频和视频的标准,提供高质量的音频。
+// 44100 Hz: CD音质标准,兼容性好。
+// 16000 Hz: 通讯领域常用,适用于纯语音,体积小。
+// 推荐使用 48000 或 44100。
 constexpr int AUDIO_SAMPLE_RATE = 48000;
+
+// --- 声道数 (Channels) ---
+// 1 (Mono): 单声道。体积小,适用于语音、旁白等场景。兼容性最佳。
+// 2 (Stereo): 立体声。提供空间感,适用于音乐、游戏等场景。体积是单声道的两倍。
+// 为了平衡音质和文件大小,推荐使用单声道。
 constexpr int AUDIO_CHANNEL = 1;
+
+// --- 采样格式 (Sample Format) ---
+// FFmpeg编码器期望的输入格式。捕获的PCM数据会被重采样成此格式。
+// AV_SAMPLE_FMT_FLTP: 浮点型,平面存储。可以提供更大的动态范围。
 constexpr AVSampleFormat AUDIO_FMT = AV_SAMPLE_FMT_FLTP;
+
+// --- 捕获采样位深 (Capture Bit Depth) ---
+// 从系统音频设备请求的原始PCM数据的位深度。
+// 16-bit (Signed Integer): 兼容性极好,是大多数音频设备和API的标准格式。
+// 编码时,此格式数据会被转换为上面定义的 AUDIO_FMT (如32-bit float)。
+constexpr int AUDIO_CAPTURE_BITS_PER_SAMPLE = 16;
+
+// --- 设备索引 ---
 constexpr int MICROPHONE_INDEX = 0;
 constexpr int SPEAKER_INDEX = 1;
 

+ 21 - 81
AvRecorder/capturer/audio/audio_qt_capturer.cpp

@@ -158,7 +158,6 @@ QtAudioCapturer::~QtAudioCapturer()
 bool QtAudioCapturer::Init(Type deviceType)
 {
     m_deviceType = deviceType;
-    setupAudioFormat();
     if (m_deviceType == Microphone) {
         return initMicrophone();
     } else {
@@ -284,76 +283,33 @@ void QtAudioCapturer::onAudioNotify()
 
 bool QtAudioCapturer::initMicrophone()
 {
-    // 获取默认输入设备
-    QAudioDeviceInfo deviceInfo = QAudioDeviceInfo::defaultInputDevice();
-
-    qDebug() << "QtAudioCapturer::initMicrophone - 默认输入设备:" << deviceInfo.deviceName();
-
-    // 检查设备是否有效
-    if (deviceInfo.isNull()) {
-        qWarning() << "QtAudioCapturer::initMicrophone - 没有可用的音频输入设备";
-        return false;
-    }
-
-    // 列出所有可用的音频输入设备
+    qDebug() << "QtAudioCapturer::initMicrophone - 默认输入设备: "
+             << QAudioDeviceInfo::defaultInputDevice().deviceName();
+    QList<QAudioDeviceInfo> availableDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
     qDebug() << "QtAudioCapturer::initMicrophone - 可用的音频输入设备:";
-    for (const auto& device : QAudioDeviceInfo::availableDevices(QAudio::AudioInput)) {
-        qDebug() << "  " << device.deviceName();
+    for (const QAudioDeviceInfo& deviceInfo : availableDevices) {
+        qDebug() << "  " << deviceInfo.deviceName();
     }
 
-    // 检查格式是否支持
-    if (!deviceInfo.isFormatSupported(m_qtAudioFormat)) {
-        qWarning() << "QtAudioCapturer::initMicrophone - 默认格式不支持,尝试使用最接近的格式";
-
-        // 尝试几种常用格式
-        QList<int> sampleRates = {44100, 48000, 16000, 8000};
-        QList<int> channelCounts = {2, 1};
-        QList<int> sampleSizes = {16, 8};
-
-        bool formatFound = false;
-
-        for (int rate : sampleRates) {
-            for (int channels : channelCounts) {
-                for (int size : sampleSizes) {
-                    QAudioFormat format;
-                    format.setSampleRate(rate);
-                    format.setChannelCount(channels);
-                    format.setSampleSize(size);
-                    format.setCodec("audio/pcm");
-                    format.setByteOrder(QAudioFormat::LittleEndian);
-                    format.setSampleType(QAudioFormat::SignedInt);
-
-                    if (deviceInfo.isFormatSupported(format)) {
-                        m_qtAudioFormat = format;
-                        formatFound = true;
-                        qDebug() << "QtAudioCapturer::initMicrophone - 找到支持的格式:"
-                                 << "采样率=" << rate << "通道数=" << channels
-                                 << "采样大小=" << size;
-                        break;
-                    }
-                }
-                if (formatFound)
-                    break;
-            }
-            if (formatFound)
-                break;
-        }
+    AudioFormat defaultFormat = IAudioCapturer::GetDefaultFormat();
+    QAudioFormat format;
+    format.setSampleRate(defaultFormat.sampleRate);
+    format.setChannelCount(defaultFormat.channels);
+    format.setSampleSize(defaultFormat.bitsPerSample);
+    format.setCodec("audio/pcm");
+    format.setByteOrder(QAudioFormat::LittleEndian);
+    format.setSampleType(QAudioFormat::SignedInt);
 
-        if (!formatFound) {
-            // 使用设备支持的最接近的格式
-            m_qtAudioFormat = deviceInfo.nearestFormat(m_qtAudioFormat);
-            qDebug() << "QtAudioCapturer::initMicrophone - 使用最接近的格式:"
-                     << "采样率=" << m_qtAudioFormat.sampleRate()
-                     << "通道数=" << m_qtAudioFormat.channelCount()
-                     << "采样大小=" << m_qtAudioFormat.sampleSize();
-        }
-
-        // 更新 AudioFormat
-        m_audioFormat = AudioFormat(m_qtAudioFormat.sampleRate(),
-                                    m_qtAudioFormat.channelCount(),
-                                    m_qtAudioFormat.sampleSize());
+    QAudioDeviceInfo deviceInfo = QAudioDeviceInfo::defaultInputDevice();
+    if (!deviceInfo.isFormatSupported(format)) {
+        qWarning() << "QtAudioCapturer::initMicrophone - 默认格式不支持,尝试使用最接近的格式";
+        format = deviceInfo.nearestFormat(format);
     }
 
+    m_qtAudioFormat = format;
+    m_audioFormat = AudioFormat(m_qtAudioFormat.sampleRate(), m_qtAudioFormat.channelCount(),
+                                m_qtAudioFormat.sampleSize());
+
     // 创建音频输入
     m_audioInput = std::make_unique<QAudioInput>(deviceInfo, m_qtAudioFormat, this);
 
@@ -372,22 +328,6 @@ bool QtAudioCapturer::initSpeaker()
     return false;
 }
 
-void QtAudioCapturer::setupAudioFormat()
-{
-    // 设置Qt音频格式
-    m_qtAudioFormat.setSampleRate(44100); // 与原代码中的 DEFAULT_SAMPLE_RATE 保持一致
-    m_qtAudioFormat.setChannelCount(1);   // 改为单声道,提高兼容性
-    m_qtAudioFormat.setSampleSize(16);    // 与原代码中的 DEFAULT_BITS_PER_SAMPLE 保持一致
-    m_qtAudioFormat.setCodec("audio/pcm");
-    m_qtAudioFormat.setByteOrder(QAudioFormat::LittleEndian);
-    m_qtAudioFormat.setSampleType(QAudioFormat::SignedInt);
-
-    // 设置IAudioCapturer使用的格式
-    m_audioFormat = AudioFormat(m_qtAudioFormat.sampleRate(),
-                                m_qtAudioFormat.channelCount(),
-                                m_qtAudioFormat.sampleSize());
-}
-
 float QtAudioCapturer::calculateVolume(const QByteArray& data)
 {
     // 计算音频数据的音量级别

+ 0 - 1
AvRecorder/capturer/audio/audio_qt_capturer.h

@@ -56,7 +56,6 @@ private slots:
 private:
     bool initMicrophone();
     bool initSpeaker();
-    void setupAudioFormat();
     float calculateVolume(const QByteArray& data);
 
 private:

+ 8 - 0
AvRecorder/capturer/audio/iaudiocapturer.h

@@ -4,6 +4,8 @@
 #include <cstdint>
 #include <functional>
 
+#include "basic/basic.h"
+
 // 平台无关的音频格式结构
 struct AudioFormat
 {
@@ -36,6 +38,12 @@ struct AudioFormat
 class IAudioCapturer
 {
 public:
+    // 默认音频格式
+    static AudioFormat GetDefaultFormat()
+    {
+        return AudioFormat(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_CAPTURE_BITS_PER_SAMPLE);
+    }
+
     enum Type { Microphone, Speaker };
 
     virtual ~IAudioCapturer() = default;

+ 37 - 27
AvRecorder/capturer/audio/wasapi_loopback_capturer.cpp

@@ -5,10 +5,6 @@
 #include <windows.h>
 #include <QDebug>
 
-#define DEFAULT_SAMPLE_RATE 48000  // 默认采样率:48kHz
-#define DEFAULT_BITS_PER_SAMPLE 16 // 默认位深:16bit
-#define DEFAULT_CHANNELS 1         // 默认音频通道数:1
-
 #undef min
 
 class WASAPILoopbackCapturerPrivate
@@ -56,22 +52,7 @@ public:
         }
         return true;
     }
-    // 检查并获取首选格式
-    bool getPreferredFormat() {
-        HRESULT hr = pAudioClient->GetMixFormat(&pwfx);
-        if (FAILED(hr)) {
-            qDebug() << "Failed to GetMixFormat, HRESULT:" << QString::number(hr, 16);
-            return false;
-        }
-        qDebug() << "Audio Format Info:";
-        qDebug() << "  Sample Rate:" << pwfx->nSamplesPerSec;
-        qDebug() << "  Channels:" << pwfx->nChannels;
-        qDebug() << "  Bits Per Sample:" << pwfx->wBitsPerSample;
-        qDebug() << "  Format Tag:" << pwfx->wFormatTag;
-        qDebug() << "  Block Align:" << pwfx->nBlockAlign;
-        qDebug() << "  Avg Bytes Per Sec:" << pwfx->nAvgBytesPerSec;
-        return true;
-    }
+
     // 初始化音频客户端
     bool initializeAudioClient()
     {
@@ -241,16 +222,45 @@ bool WASAPILoopbackCapturer::Init(Type deviceType)
         qDebug() << "Failed to initialize WASAPI components";
         return false;
     }
-    
-    // 总是获取首选格式,因为我们需要 pwfx 来初始化音频客户端
-    if (!d->getPreferredFormat()) {
-        qDebug() << "Failed to get preferred format";
+
+    // 尝试使用默认格式
+    AudioFormat defaultFormat = IAudioCapturer::GetDefaultFormat();
+    WAVEFORMATEX* formatToUse = (WAVEFORMATEX*)CoTaskMemAlloc(sizeof(WAVEFORMATEX));
+    if (!formatToUse) {
+        qDebug() << "Failed to allocate memory for WAVEFORMATEX";
         return false;
     }
-    
+    formatToUse->wFormatTag = WAVE_FORMAT_PCM;
+    formatToUse->nChannels = defaultFormat.channels;
+    formatToUse->nSamplesPerSec = defaultFormat.sampleRate;
+    formatToUse->wBitsPerSample = defaultFormat.bitsPerSample;
+    formatToUse->nBlockAlign = (formatToUse->nChannels * formatToUse->wBitsPerSample) / 8;
+    formatToUse->nAvgBytesPerSec = formatToUse->nSamplesPerSec * formatToUse->nBlockAlign;
+    formatToUse->cbSize = 0;
+
+    d->pwfx = formatToUse;
+
+    // 尝试使用默认格式初始化,如果失败则回退
     if (!d->initializeAudioClient()) {
-        qDebug() << "Failed to initialize audio client";
-        return false;
+        qWarning("Default audio format not supported, falling back to GetMixFormat.");
+
+        CoTaskMemFree(d->pwfx);
+        d->pwfx = nullptr;
+
+        // 使用GetMixFormat获取系统首选格式
+        HRESULT hr = d->pAudioClient->GetMixFormat(&d->pwfx);
+        if (FAILED(hr)) {
+            qDebug() << "Failed to GetMixFormat on fallback, HRESULT:" << QString::number(hr, 16);
+            return false;
+        }
+
+        // 再次尝试初始化
+        if (!d->initializeAudioClient()) {
+            qDebug() << "Failed to initialize audio client on fallback.";
+            CoTaskMemFree(d->pwfx);
+            d->pwfx = nullptr;
+            return false;
+        }
     }
 
     // 设置音频格式