Qt-如何同时录制和播放声音 [英] Qt - how to record and play sound simultaneously

查看:80
本文介绍了Qt-如何同时录制和播放声音的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Qt论坛上发布了这个问题,但没有得到答案.这就是为什么我在这里发布它.

I posted this question on the Qt forum, but got no answers. That's why I am posting it here.

我想知道有什么方法可以在Qt中同时录制和播放声音.我想录制来自麦克风的声音,同时又想在扬声器/耳机中播放声音.

I wanted to know is there any way to record and play sound at the same time in Qt. I want to record sound from a microphone and at the same time I want to play it in the speaker/headphone.

在Qt中有什么方法可以做到这一点吗?还是我需要使用其他任何库?

Is there any way to do this in Qt? Or do I need to use any other library?

如果解决方案是跨平台的,那就太好了(我需要介绍Windows,Linux和Mac).如果不可能,那么可以使用Linux解决方案.

It would be great if the solution is cross-platform (I need to cover windows, linux and mac). If it isn't possible, then a linux solution will do.

我正在使用Qt 4.7.

I am using Qt 4.7 by the way.

修改

此处给出了我的最新实现.我创建了 QIODevice 的子类,并重新实现了 writeData 此建议进行了此操作.该代码也不起作用,因为 QAudioOutput 实例面对 Unrunrun错误,根据此文档的含义,-

My latest implementation is given here. I have created a sub-class of the QIODevice and re-implemented its writeData and readData method so that reading and writing can be done with a circular buffer. I have done this as per this suggestion. This code also doesn't work because the QAudioOutput instance faces Underrun Error, which according to this documentation means -

音频数据没有以足够快的速度馈送到音频设备

Audio data is not being fed to the audio device at a fast enough rate

我已应用骇客来暂时解决此问题.在 outputStateChanged 方法中,我检查输出的状态是否已更改为 IDLE ,如果已更改,我再次调用 start()方法,指定公共缓冲区.我不想将其用作永久性解决方案,因为它确实很笨拙,并且因为我在没有适当调查其原因的情况下吞下了一个错误.

I have applied a hack to solve this problem temporarily. In the outputStateChanged method, I am checking to see if the state of the output has changed to IDLE and if it has, I am again calling start() method, specifying the common buffer. I don't want to use this as a permanent solution because it feels really hacky and because I am swallowing an error without properly investigating its reasons.

我应该怎么做才能解决这个问题?

What should I do to solve this problem?

我还尝试使用 Phonon 解决此问题,但失败了,因为我对该模块没有足够的知识.

I also tried to solve this using Phonon but failed because I do not have sufficient knowledge of this module.

推荐答案

我对Qt不太了解,但是我在处理媒体方面很满意,所以如果我的回答不是很具体,请原谅我,而是从更普遍的观点.

I'm not very experienced with Qt, but I am with handling media, so forgive me if my answer isn't very specific but instead addresses your problem from a more general point of view.

我查看了您的代码,并且我认为总体上您的想法应该可行.我看到了一些问题:

I looked at your code, and I think in general your idea should work. I see some problems though:

  • writeData 方法似乎没有准备好处理缓冲区已满的情况.当循环缓冲区填满时,它只会覆盖旧数据,并错误地继续增加 currentBufferLength 变量.我认为正确的做法是更新 readPosition 以跳过丢失的数据,并防止 currentBufferLength 超过缓冲区大小.

  • the writeData method doesn't seem to be prepared to handle a buffer full condition. When the circular buffer fills it'll just overwrite old data, and incorrectly continue to increment the currentBufferLength variable. I think the correct thing to do here is to update the readPosition to skip over the data that was lost, and to prevent currentBufferLength from ever growing past the buffer size.

您几乎同时启动了作者和读者.相反,您应该启动编写器并准备循环缓冲区,然后启动读取器.请记住,您将永远无法以零延迟进行录制和播放.至少,您的等待时间将是单个缓冲区写入的大小,但实际上,您可能需要写入器领先一些缓冲区,以免出现打ic.

You are starting both the writer and the reader at pretty much the same time. Instead, you should start the writer and prime the circular buffer, then start the reader. Keep in mind that you will never be able to record and play with zero latency. At the very least your latency will be the size of an individual buffer write, but in practice you'll probably need the writer to be ahead by a few buffers to avoid hiccups.

您应该分别调试读取器和写入器.仅设置编写器,并验证是否定期地写入循环缓冲区(如我上面建议的那样首先修复溢出条件).要进行调试,您可以将缓冲区转储到文件中,然后在音频播放器(例如,Audacity)中检查该文件,或者可以使用printf调试来确保不断获取数据.然后只用读者做类似的事情.

You should debug the reader and the writer separately. Set up only the writer and verify that the circular buffer is getting written to at regular intervals (first fix the overflow condition as I suggested above). To debug, you can dump the buffers to a file and then check the file in an audio player (Audacity, for example), or you can use printf debugging to ensure you are constantly getting data. Then do something similar with only a reader.

最终思想.调用您的 readData writeData 方法的代码可能正在其他线程上运行,可能是两个不同的线程,一个用于读取器,另一个用于写入器.如果我的猜测是正确的,那么您的圆形结构就有很大的问题.您必须保护对确定读写位置和大小的变量的访问,否则,您将具有竞争条件.

Final thought. The code that calls your readData and writeData methods is probably running on other threads, likely two different threads, one for the reader and another one for the writer. If my guess is correct, then you have a big problem with your circular structure. You have to protect access to the variables that determine the read and write positions and sizes, if not you will have race conditions.

祝你好运.

这篇关于Qt-如何同时录制和播放声音的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆