【问题标题】:C++ Qt QAudioInput + QIODeviceC++ Qt QAudioInput + QIODevice
【发布时间】:2018-07-21 23:07:33
【问题描述】:

我的目的是从麦克风捕捉声音并实时播放。问题是当我按下开始按钮时,应用程序输出中有一些消息,如 QAudioInput: IOError, can't write to QIODevice。 我正在查看示例 "qaudioinput" 。 在注释每一行的方式中,我发现问题在行 音频输入->开始(开发输入); 当下一行 音频输出->开始(开发输出); 工作正常。 还有一个,任何人都可以在 qaudioinput 示例中解释推拉模式吗?互联网上没有关于它的信息。

主窗口.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>
#include <QDialog>
#include <QHBoxLayout>
#include <QPushButton>
#include <QtMultimedia/QAudioFormat>
#include <QtMultimedia/QAudioInput>
#include <QtMultimedia/QAudioOutput>
#include <QByteArray>
#include <QIODevice>

class audioIn : public QIODevice
{
    Q_OBJECT
public:
    audioIn(const QAudioFormat &format, QObject *parent);
    ~audioIn();
    qint64 writeData(const char *data, qint64 len);
    qint64 readData(char *data, qint64 maxlen);
    void start();
    void stop();
private:
    const QAudioFormat m_format;
};
class audioOut : public QIODevice
{
    Q_OBJECT
public:
    audioOut(const QAudioFormat &format, QObject *parent);
    ~audioOut();
    qint64 writeData(const char *data, qint64 len);
    qint64 readData(char *data, qint64 maxlen);
    void start();
    void stop();
private:
    const QAudioFormat m_format;
};

class mainwindow:public QDialog
{
    Q_OBJECT
public:
    mainwindow(QWidget *parent = 0);
    ~mainwindow();
private:
    QHBoxLayout* layout;
    QPushButton* start;
    QByteArray buffer;
    QAudioFormat m_format;
    QAudioInput* audioInput;
    QAudioOutput* audioOutput;
    audioIn* devInput;
    audioOut* devOutput;
    QIODevice* m_input;
    QIODevice* m_output;

public slots:
    void startrec();
    void readMore();
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"

audioIn::audioIn(const QAudioFormat &format, QObject *parent):QIODevice(parent), m_format(format)
{

}
audioIn::~audioIn()
{
}
void audioIn::start()
{
    open(QIODevice::WriteOnly);
}
void audioIn::stop()
{
    close();
}
qint64 audioIn::readData(char *data, qint64 maxlen)
{
    Q_UNUSED(data);
    Q_UNUSED(maxlen);
    return 0;
}
qint64 audioIn::writeData(const char *data, qint64 len)
{
    Q_UNUSED(data);
    Q_UNUSED(len);
    return 0;
}

audioOut::audioOut(const QAudioFormat &format, QObject *parent):QIODevice(parent), m_format(format)
{

}
audioOut::~audioOut()
{
}
void audioOut::start()
{
    open(QIODevice::ReadOnly);
}
void audioOut::stop()
{
    close();
}
qint64 audioOut::readData(char *data, qint64 maxlen)
{
    Q_UNUSED(data);
    Q_UNUSED(maxlen);
    return 0;
}
qint64 audioOut::writeData(const char *data, qint64 len)
{
    Q_UNUSED(data);
    Q_UNUSED(len);
    return 0;
}

mainwindow::mainwindow(QWidget *parent): QDialog(parent)
{
    layout = new QHBoxLayout;
    start = new QPushButton("Start");
    layout->addWidget(start);
    setLayout(layout);
    connect(start, SIGNAL(clicked(bool)), this, SLOT(startrec()));
}
mainwindow::~mainwindow()
{

}

void mainwindow::startrec()
{
    m_format.setByteOrder(QAudioFormat::LittleEndian);
    m_format.setChannelCount(2);
    m_format.setSampleRate(44100);
    m_format.setSampleSize(16);
    m_format.setCodec("audio/pcm");
    m_format.setSampleType(QAudioFormat::UnSignedInt);

    QAudioDeviceInfo infoIn(QAudioDeviceInfo::defaultInputDevice());
    if(!infoIn.isFormatSupported(m_format))
        m_format = infoIn.nearestFormat(m_format);
    devInput = new audioIn(m_format, this);
    audioInput = new QAudioInput(infoIn, m_format, this);

    QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());
    if(!infoOut.isFormatSupported(m_format))
        m_format = infoOut.nearestFormat(m_format);
    devOutput = new audioOut(m_format, this);
    audioOutput = new QAudioOutput(infoOut,m_format, this);

    devInput->start();
    devOutput->start();
    m_input = audioInput->start();
    m_output = audioOutput->start();

    connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
}

void mainwindow::readMore()
{
    qint64 len = audioInput->bytesReady();
    if(len > 7056)
        len = 7056;
    qint64 l = m_input->read(buffer.data(), len);
    if(l > 0)
        m_output->write(buffer.constData(), l);
}

【问题讨论】:

  • 而不是 devInput->start();开发输出->开始(); m_input = audioInput->start(); m_output = 音频输出->start();有 devInput->start();开发输出->开始();音频输入->开始(开发输入);音频输出->开始(开发输出);而在 readMore 中,m_input 和 m_output 有 devInput 和 devOutput
  • 错误是自我解释的IOError, can't write to QIODevice ..您的设备需要在write模式下打开
  • Qt 和“实时”不能叠加。尤其是在 Windows 上。
  • audioIn 已经以写入模式打开
  • void audioIn::start() { open(QIODevice::WriteOnly); }

标签: c++ qt microphone


【解决方案1】:

这是你的问题:

void audioIn::start()
{
    open(QIODevice::WriteOnly);
}

如果您想从设备读取,最好在 ReadOnly 或 ReadWrite 模式下打开它....

(显然您的 audioIn 类需要读取数据,而不是写入)。

【讨论】:

  • 你是对的,但问题是这部分代码取自 Qt 示例。 OP 正在尝试扩展功能.. 但对于 对我而言 尚不清楚
  • 好的,明天我会尝试检查我的代码并修复它。谢谢
  • 如果我将 audioIn::start() 设置为 ReadOnly,它会显示:QIODevice::write (audioIn): ReadOnly device QAudioInput: IOError
  • 等一下……audioIn 实际上是做什么的?你创建它,它是从 QIODevice 派生的,但你从不指定它应该打开的 what。我认为您需要重新考虑您的代码;为什么你有 devInput 和 audioInput??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
  • 2019-12-26
  • 1970-01-01
  • 2015-01-11
相关资源
最近更新 更多