|
|
@@ -140,8 +140,6 @@ qint64 AudioInfo::writeData(const char* data, qint64 len)
|
|
|
QtAudioCapturer::QtAudioCapturer(QObject* parent)
|
|
|
: QObject(parent)
|
|
|
, m_deviceType(Microphone)
|
|
|
- , m_callback(nullptr)
|
|
|
- , m_userInfo(nullptr)
|
|
|
, m_isRunning(false)
|
|
|
, m_audioDevice(nullptr)
|
|
|
{
|
|
|
@@ -157,14 +155,10 @@ QtAudioCapturer::~QtAudioCapturer()
|
|
|
Stop();
|
|
|
}
|
|
|
|
|
|
-bool QtAudioCapturer::Init(Type deviceType, CallBack callback, void* userInfo)
|
|
|
+bool QtAudioCapturer::Init(Type deviceType)
|
|
|
{
|
|
|
m_deviceType = deviceType;
|
|
|
- m_callback = callback;
|
|
|
- m_userInfo = userInfo;
|
|
|
-
|
|
|
setupAudioFormat();
|
|
|
-
|
|
|
if (m_deviceType == Microphone) {
|
|
|
return initMicrophone();
|
|
|
} else {
|
|
|
@@ -188,57 +182,15 @@ bool QtAudioCapturer::Start()
|
|
|
<< (m_deviceType == Microphone ? "麦克风" : "扬声器");
|
|
|
|
|
|
if (m_deviceType == Microphone && m_audioInput) {
|
|
|
- // 设置更合理的缓冲区大小
|
|
|
- // int bufferSize = 8192;
|
|
|
- // 或者使用计算值:m_qtAudioFormat.sampleRate() * m_qtAudioFormat.channelCount() * 2 / 5;
|
|
|
- // m_audioInput->setBufferSize(bufferSize);
|
|
|
- // qDebug() << "QtAudioCapturer::Start - 设置缓冲区大小:" << bufferSize;
|
|
|
-
|
|
|
- // qDebug() << "QtAudioCapturer::Start - 缓冲区大小:" << m_audioInput->bufferSize();
|
|
|
-
|
|
|
- // 设置更短的通知间隔,提高响应性
|
|
|
- // m_audioInput->setNotifyInterval(20); // 20毫秒
|
|
|
-
|
|
|
- // 启动音频输入
|
|
|
m_audioDevice = m_audioInput->start();
|
|
|
if (!m_audioDevice) {
|
|
|
qWarning() << "QtAudioCapturer::Start - 启动音频输入失败";
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
- // qDebug() << "QtAudioCapturer::Start - 麦克风启动成功,缓冲区大小:"
|
|
|
- // << m_audioInput->bufferSize();
|
|
|
-
|
|
|
- // 连接信号
|
|
|
+ qDebug() << "QtAudioCapturer::Start - QAudioInput state:" << m_audioInput->state();
|
|
|
+ qDebug() << "QtAudioCapturer::Start - QAudioInput error:" << m_audioInput->error();
|
|
|
connect(m_audioDevice, &QIODevice::readyRead, this, &QtAudioCapturer::handleReadyRead);
|
|
|
-
|
|
|
- // 添加一个定时器,定期检查音频状态
|
|
|
- QTimer* statusTimer = new QTimer(this);
|
|
|
- connect(statusTimer, &QTimer::timeout, [this]() {
|
|
|
- // qDebug() << "QtAudioCapturer::StatusCheck - 音频输入状态:" << m_audioInput->state()
|
|
|
- // << "错误:" << m_audioInput->error()
|
|
|
- // << "处理字节数:" << m_audioInput->processedUSecs()
|
|
|
- // << "可用字节数:" << (m_audioDevice ? m_audioDevice->bytesAvailable() : 0);
|
|
|
-
|
|
|
- // 如果状态不是活动状态,尝试重新启动
|
|
|
- if (m_audioInput->state() != QAudio::ActiveState) {
|
|
|
- qDebug() << "QtAudioCapturer::StatusCheck - 尝试重新启动音频输入";
|
|
|
- m_audioInput->stop();
|
|
|
- m_audioDevice = m_audioInput->start();
|
|
|
- if (m_audioDevice) {
|
|
|
- connect(m_audioDevice,
|
|
|
- &QIODevice::readyRead,
|
|
|
- this,
|
|
|
- &QtAudioCapturer::handleReadyRead);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- statusTimer->start(2000); // 每2秒检查一次
|
|
|
- } else if (m_deviceType == Speaker) {
|
|
|
- // 系统声音捕获的实现
|
|
|
- qDebug() << "QtAudioCapturer::Start - 尝试启动扬声器捕获";
|
|
|
}
|
|
|
-
|
|
|
m_isRunning = true;
|
|
|
return true;
|
|
|
}
|
|
|
@@ -272,42 +224,36 @@ const AudioFormat& QtAudioCapturer::GetFormat() const
|
|
|
|
|
|
void QtAudioCapturer::handleReadyRead()
|
|
|
{
|
|
|
- // qDebug() << "handleReadyRead" << m_audioDevice << m_audioDevice->bytesAvailable();
|
|
|
+ //qDebug() << "handleReadyRead called, m_audioDevice:" << m_audioDevice;
|
|
|
if (m_audioDevice) {
|
|
|
QByteArray data = m_audioDevice->readAll();
|
|
|
- // qDebug() << "QtAudioCapturer::handleReadyRead - 收到数据大小:" << data.size() << "字节";
|
|
|
-
|
|
|
- // 检查数据是否有效
|
|
|
+ //qDebug() << "handleReadyRead: read data size:" << data.size();
|
|
|
if (data.size() > 0) {
|
|
|
- // 计算音量级别用于调试
|
|
|
- // float volume = calculateVolume(data);
|
|
|
- // qDebug() << "QtAudioCapturer::handleReadyRead - 计算的音量级别:" << volume;
|
|
|
-
|
|
|
- // 确保回调被调用
|
|
|
- if (m_callback) {
|
|
|
- m_callback(data.data(), data.size(), m_userInfo);
|
|
|
- } else {
|
|
|
- qWarning() << "QtAudioCapturer::handleReadyRead - 回调函数为空";
|
|
|
- }
|
|
|
+ QMutexLocker locker(&m_mutex);
|
|
|
+ m_dataBuffer.append(data);
|
|
|
+ //qDebug() << "Audio data appended, buffer size now:" << m_dataBuffer.size();
|
|
|
}
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // 不再需要将数据写入缓冲区,因为已经直接处理了
|
|
|
- // m_buffer.write(data);
|
|
|
- } else {
|
|
|
- // 减少日志输出频率,只在调试时启用
|
|
|
- // qDebug() << "QtAudioCapturer::handleReadyRead - 没有可用数据";
|
|
|
+int QtAudioCapturer::readAudioData(char* buf, int maxLen)
|
|
|
+{
|
|
|
+ QMutexLocker locker(&m_mutex);
|
|
|
+ int toRead = qMin(maxLen, m_dataBuffer.size());
|
|
|
+ // qDebug() << "readAudioData called, buffer size:" << m_dataBuffer.size() << ", toRead:" << toRead;
|
|
|
+ if (toRead > 0) {
|
|
|
+ memcpy(buf, m_dataBuffer.constData(), toRead);
|
|
|
+ m_dataBuffer.remove(0, toRead);
|
|
|
}
|
|
|
+ return toRead;
|
|
|
}
|
|
|
|
|
|
void QtAudioCapturer::processAudioData()
|
|
|
{
|
|
|
QByteArray data = m_buffer.buffer();
|
|
|
- if (data.size() > 0 && m_callback) {
|
|
|
- qDebug() << "QtAudioCapturer::processAudioData - 处理缓冲区数据,大小:" << data.size()
|
|
|
- << "字节";
|
|
|
-
|
|
|
- // 如果没有在 handleReadyRead 中直接调用回调,则在这里调用
|
|
|
- // m_callback(data.data(), data.size(), m_userInfo);
|
|
|
+ if (data.size() > 0) {
|
|
|
+ // qDebug() << "QtAudioCapturer::processAudioData - 处理缓冲区数据,大小:" << data.size()
|
|
|
+ // << "字节";
|
|
|
|
|
|
// 清空缓冲区
|
|
|
m_buffer.buffer().clear();
|
|
|
@@ -329,9 +275,9 @@ void QtAudioCapturer::onAudioNotify()
|
|
|
buffer.resize(len);
|
|
|
|
|
|
// 调用回调函数
|
|
|
- if (m_callback) {
|
|
|
- m_callback(buffer.data(), buffer.size(), m_userInfo);
|
|
|
- }
|
|
|
+ // if (m_callback) {
|
|
|
+ // m_callback(buffer.data(), buffer.size(), m_userInfo);
|
|
|
+ // }
|
|
|
}
|
|
|
}
|
|
|
}
|