0
点赞
收藏
分享

微信扫一扫

需要注意的大坑-Qt6录音QIODevice::readAll()返回奇数字节。

主要的问题:
我在一个项目中使用QMultiMedia模块录音,假设了 QIODevice::readAll() 每次必然返回整数组样点。比如立体声,16位,则返回的字节数必然是4的整数倍。这个行为从Qt4、Qt5都没有出问题。结果Qt6时,在Win10下返回了奇数个字节。如果不做缓存,后续的样点字节就被破坏,声音就很怪很怪。

我已经在Qt的社区反馈了这个问题:
A noteworthy issue: QAudioSource returns a QIODevice object, whose QIODevice::readAll() returns an odd bytelength for qint16 sample points.

When I migrated a Qt5 project to Qt6, I ran into this problem. Under Windows 10, My instances of MSYS2 Qt 6.2.0 x64 compilation are not working properly. I traced the debugging and found the problem.

My old code presupposes that readAll must return a complete sample.

//QAudioSource *AudioInputSound = new QAudioSource(dev, format, this);
//QIODevice InputDev = AudioInputSound->start();
//connect(InputDev, SIGNAL(readyRead()), SLOT(OnReadMore()));
void Dialog::OnReadMore()
{
    //...
     QByteArray data = InputDev->readAll();
     const short * spt = (const short * ) data.constData();
     //Audio sample point size will be 4 bytes for stereo, 2 bytes for mono.
     const int point_size = sizeof(short) * channels;
     //Problem Here it is! 
     //This Operation suppose that (data.size() % point_size ==0).
     int points = data.size()/point_size;
     //Do signal process funtions.
     deal_function(spt, point_size, points);
     //When funtion returns, data will be recycled. The lost of odd tail disrupts subsequent samples.
}

But under the new Qt6, it returns an odd number of bytes. This is an issue that I didn’t think through. Currently, it is solved by a cache that preserves the tail data.

//...
QByteArray buffer;
void Dialog::OnReadMore()
{
     //We can put bytes to a buffer first.
     buffer.append(InputDev->readAll());
     const short * spt = (const short * ) data.constData();
     const int point_size = sizeof(short) * channels;     
     //The variable "points" now refers to the maximum number of samples that can be processed. 
     int points = data.size()/point_size;
     deal_function(spt, point_size, points);
     //Remove old data and KEEP the tail. 
     buffer.remove(0,points* point_size);
}

This introduces some performance issues. However, it is not a big problem for low-speed devices such as sound cards.

This is not a BUG, but this behavior of the QAudioInput module can be troubling. Some poorly designed programs crash, just like mine. For Qt, which may be used in medical devices, special attention needs to be paid to this feature.

I wish Qt better and better!

举报

相关推荐

0 条评论