从麦克风捕获声音时不执行 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);
(audio
是 QAudioInput*
类型,bufferInput
是 QIODevice*
类型)
当我单击按钮时,会显示“input device =”和“created()”消息,但不会显示“onNotify()”。
我做错了什么?
【问题讨论】:
可能是您计算机上的音频输入设备不支持您要求它播放的 QAudioFormat,因此无法启动。我建议将 QAudioInput 的 stateChanged(QAudio::State) 信号连接到一个插槽并让该插槽打印出新的状态值,这样您就可以更好地了解设备发生了什么(或没有发生)。跨度> 向 stateChanged 信号添加了类似的处理程序:qDebug() << newState; qDebug() << (audio->error());
,它显示的只是“IdleState NoError”
奇怪的事情,将bufferInput = audio->start();
更改为bufferInput = new QBuffer(); bufferInput->open(QIODevice::ReadWrite);audio->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()的主要内容,如果未能解决你的问题,请参考以下文章