c++ 将QAudioBuffer转换为QByteArray:信息丢失?

s4n0splo  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(251)

我有一个用QAudioDecoder解码的WAV文件。因此我有一个QAudioBuffer对象。我想把QAudioBuffer中存储的数据存储在QIODevice派生类的QByteArray中。我想在派生类的ReadData方法中使用这些数据进行音频输出。现在我有两个问题:

  • 如何从QAuddioBuffer中获取QByteArray?我使用了以下代码,但不幸的是,这是不正确的。QAudioBuffer中的数据被编码为2Bytes,但QByteArray中的每个元素被编码为1Byte(对吗?)。我们是否丢失了信息?为了测试QByteArray是否包含WAV文件中的原始数据,我将其保存为TXT文件。
  • 这种方法合适吗?我实际上想对存储在QAudioBuffer中的数据应用一些操作(例如,过滤器),并真实的听取结果。

先谢了。
下面是代码

QAudioFormat *format_decoder;
format_decoder = new QAudioFormat;
format_decoder->setSampleRate(44100);
format_decoder->setChannelCount(1);
format_decoder->setSampleFormat(QAudioFormat::Int16);

QAudioDecoder decoder;
decoder.setSource(filenameSource);
decoder.setAudioFormat(*format_decoder);
decoder.start();

QObject::connect(&decoder, &QAudioDecoder::bufferReady, this, &MainWindow::slot_bufReady);

并且所述槽

void MainWindow::slot_bufReady(){

QAudioBuffer buffer = m_audioDecoder->read();
QByteArray buffer_ByteArray(buffer.constData<char>(), buffer.byteCount());

QFile file(filenameTest1);
if(!file.open(QIODevice::WriteOnly|QIODevice::Append)) {
        qDebug() << "ERRO ";  }

QTextStream strem(&file);
for(auto const dat: buffer_ByteArray)  {
        strem<< qreal(dat)/128.0<< "\r\n";
    }
file.cloe();
rkttyhzu

rkttyhzu1#

这看起来很可疑:

for(auto const dat: buffer_ByteArray)  {
        strem<< qreal(dat)/128.0<< "\r\n";
    }

您的音频格式是16位单声道。逐个字节读取是不可能的。逐个样本读取。也就是说,一次读取两个字节并进行转换。更可能的做法是:

int16_t* data = (int16_t*)(buffer.data());
int samples = buffer.sampleCount();
for (int i = 0; i < samples; i++)
{
    strem << data[i] << "\r\n";
}

上面的程序会把你的样本保存到一个文本文件中。你可以用Excel来绘制它。但是就像其他人说的那样,这没有保存为二进制文件那么有用。你可以预先添加一个WAV文件头,这样它就可以用其他工具来播放和分析。

    • 更新**

如果您打算将代码从16位转换为8位,您可能会这样做:

int16_t* data = (int16_t*)(buffer.data());
 QByteArray buffer_ByteArray(buffer.sampleCount(), '\0');
 for (size_t i = 0; i < samples; i++) {
     buffer_ByteArray[i] = (char)(data[i] / 256); // 16-bit to 8-bit
 }

注意:一些音频平台对8位音频使用无符号整数。即零振幅样本为0x80。这是8位WAV文件的情况。如果正在使用,则更改此行:

buffer_ByteArray[i] = (char)(data[i] / 256); // 16-bit to 8-bit

对此:

char c = (char)(data[i] / 256); // 16-bit to 8-bit signed
const unsigned char mask = 0x80;
buffer_ByteArray[i] = (char)(mask ^ c);

相关问题