从麦克风捕获声音时不执行 QAudioInput::notify()

Posted

技术标签:

【中文标题】从麦克风捕获声音时不执行 QAudioInput::notify()【英文标题】:QAudioInput::notify() isn't executed while capturing sound from mic 【发布时间】:2015-03-14 20:33:58 【问题描述】:

我想使用QAudioInput 从麦克风捕捉声音,处理它然后播放。据我了解,我需要连接到notify 信号和内部处理程序,以便用户readAll() 函数获取原始数据。但问题是,这个处理函数永远不会被执行。这是我的代码:

void MainWindow::on_pushButton_clicked()


    QList<QAudioDeviceInfo> list = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);

    if(list.isEmpty())
    
        qDebug() << "No audio input device";
        return;
    

    QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();

    QAudioFormat format;
    // Set up the desired format, for example:
    format.setSampleRate(44100);
    format.setChannelCount(1);
    format.setSampleSize(32);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::UnSignedInt);

    if (!info.isFormatSupported(format)) 
        qWarning() << "Default format not supported, trying to use the nearest.";
        format = info.nearestFormat(format);
    

    qDebug() << "input device :" << info.deviceName();

    audio = new QAudioInput(info, format);
    qDebug("created()");

    connect(audio, SIGNAL(notify()), this, SLOT(onNotify()));
    audio->setNotifyInterval(10);

    bufferInput = audio->start();


void MainWindow::onNotify()

    qDebug() << "onNotify()";
    //QByteArray array = bufferInput->readAll();
    //bufferOutput->write(array);

audioQAudioInput* 类型,bufferInputQIODevice* 类型)

当我单击按钮时,会显示“input device =”和“created()”消息,但不会显示“onNotify()”。

我做错了什么?

【问题讨论】:

可能是您计算机上的音频输入设备不支持您要求它播放的 QAudioFormat,因此无法启动。我建议将 QAudioInput 的 stateChanged(QAudio::State) 信号连接到一个插槽并让该插槽打印出新的状态值,这样您就可以更好地了解设备发生了什么(或没有发生)。跨度> 向 stateChanged 信号添加了类似的处理程序:qDebug() &lt;&lt; newState; qDebug() &lt;&lt; (audio-&gt;error());,它显示的只是“IdleState NoError” 奇怪的事情,将bufferInput = audio-&gt;start(); 更改为bufferInput = new QBuffer(); bufferInput-&gt;open(QIODevice::ReadWrite);audio-&gt;start(bufferInput); 使其工作,但我仍然不明白为什么。 【参考方案1】:

QAudioInput 似乎很糟糕。或者我完全误解了一些东西。

对我来说唯一可靠的方法是使用start() 返回的QIODevice 缓冲区的readyRead() 信号。不幸的是,这在我的系统上并不经常触发(在我的系统上大约每 40 到 60 毫秒)。


我发现当我在QAudioInput 上调用resume()notify() 开始触发(因为在调用start() 后它处于空闲状态)或在QIODevice 上执行readAll() (!)。但至少对于 PyQt,这会在大约一分钟后导致堆栈溢出。

我怀疑平台也很重要,因为实际的 QAudioInput 实现取决于所使用的平台和音频系统(在我的例子中是 Fedora 32 上的 PulseAudio)。

【讨论】:

【参考方案2】:

将插槽连接到 QAudioInput 的 readyRead 信号并使用 readAll 从 QIODevice 读取是正确的解决方案。为什么你认为 40 或 60 毫秒的间隔是不合适的? QAudioInput 对象必须在此时间间隔内捕获一些音频并在其后发送信号。

【讨论】:

以上是关于从麦克风捕获声音时不执行 QAudioInput::notify()的主要内容,如果未能解决你的问题,请参考以下文章

音频单元从麦克风捕获声音,添加混响,然后发送到扬声器

Java Sound API:从目标端口捕获声音输出

QtCreate中使用QAudioInput获取默认麦克风的音频数据

从串行端口 (COM) 播放实时声音

如何以 mp3 格式从麦克风流式传输声音?

捕捉当前正在播放的声音