我的需求是:我想实现一边采集,一边存储,因为我知道一旦我采集的时间比较长,采集的样本点就会越来越多,会导致内存比较大,这样会让程序出现卡顿,甚至崩溃,请你用分块处理数据的方式,提供代码给我
时间: 2024-01-01 08:06:40 浏览: 84
好的,为了实现一边采集一边存储,可以使用分块处理数据的方式,将采集到的样本点分成若干个块,每次处理一个块的数据,避免一次性处理过多数据导致内存过大。下面是处理采集到的样本点并分块存储的代码示例:
```
// 定义每个块的大小
const int blockSize = 8000;
// 定义缓存区和时间数据
QVector<double> audioData;
QVector<double> timeData;
// 定义频谱图数据
QVector<double> frequencyData;
QVector<double> spectrumData;
// 定义块计数器和块缓存区
int blockCount = 0;
QVector<double> blockSamples;
// 在每次采集到新的样本点时进行处理
void MainWindow::processSamples(const QVector<qint16>& newSamples) {
// 将新采集到的样本点转换为QVector<double>类型,并更新缓存区和时间数据
double samplePeriod = 1.0 / audioThread->input->format().sampleRate();
for (int i = 0; i < newSamples.size(); ++i) {
audioData.append(static_cast<double>(newSamples[i]) / std::numeric_limits<qint16>::max());
timeData.append((i + blockCount * blockSize) * samplePeriod);
}
// 将新样本点添加到块缓存区中
blockSamples.append(audioData.right(newSamples.size()));
// 如果块缓存区的大小达到了块大小,则进行处理
if (blockSamples.size() == blockSize) {
// 更新块计数器
++blockCount;
// 处理块数据
processBlock(blockSamples);
// 清空块缓存区
blockSamples.clear();
}
}
// 处理每个块的数据
void MainWindow::processBlock(const QVector<double>& samples) {
// 执行FFT变换
QVector<std::complex<double>> complexData(blockSize);
for (int i = 0; i < blockSize; ++i) {
complexData[i] = std::complex<double>(samples[i], 0.0);
}
cooleyTukeyFFT(complexData);
// 转换为幅度谱数据
spectrumData.resize(blockSize / 2);
for (int i = 0; i < blockSize / 2; ++i) {
spectrumData[i] = std::abs(complexData[i]);
}
// 计算频率刻度
double sampleRate = audioThread->input->format().sampleRate();
double maxFrequency = sampleRate / 2.0;
frequencyData.resize(spectrumData.size());
for (int i = 0; i < spectrumData.size(); ++i) {
frequencyData[i] = (i * maxFrequency) / spectrumData.size();
}
// 将频谱图数据存储到文件中
QString filename = QString("spectrum_%1.dat").arg(blockCount);
QFile file(filename);
if (file.open(QIODevice::WriteOnly)) {
QTextStream stream(&file);
for (int i = 0; i < spectrumData.size(); ++i) {
stream << frequencyData[i] << "\t" << spectrumData[i] << endl;
}
file.close();
}
}
```
在上面的代码中,我们定义了一个块大小为8000的常量blockSize,以及一个块计数器blockCount和一个块缓存区blockSamples。在每次采集到新的样本点时,我们将其转换为QVector<double>类型,并将其添加到缓存区和时间数据中。然后将新样本点添加到块缓存区中,如果块缓存区的大小达到了块大小,则进行处理。在处理块数据时,我们执行FFT变换,得到幅度谱数据,并计算频率刻度。最后,将频谱图数据存储到文件中,文件名为"spectrum_块计数器.dat"。这样,我们就实现了一边采集一边存储,并且避免了一次性处理过多数据导致内存过大的问题。
阅读全文