Qt C ++创建方波音频波.播放并保存 [英] Qt C++ Creating a square audio tone wave. Play and saving it

查看:382
本文介绍了Qt C ++创建方波音频波.播放并保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

早安专家,我需要指导. 我的情况分为两个部分. 首先,我需要在使用Qt C ++指定的特定时间内生成方波音频,即使在哪里开始我也完全迷失了.

第二,我还需要将音频导出到.wav或mp3. 我读过某个地方,在导出数据之前,需要将WAV标头写入文件.我的第二个问题是如何将QBuffer中的音频导出到wav文件.

我在Git上找到了以下项目. 但是,这仅生成一个正弦波,而不生成一个方波. https://github.com/picaschaf/Soundgenerator

查看此项目中的功能

void QxtSoundGenerator::appendSound(qreal amplitude, float frequency, int msecs)
{

msecs = (msecs < 50) ? 50 : msecs;

qreal singleWaveTime = 1.0 / frequency;

qreal samplesPerWave = qCeil(format->sampleRate() * singleWaveTime);

quint32 waveCount = qCeil(msecs / (singleWaveTime * 1000.0));

quint32 sampleSize = static_cast<quint32>(format->sampleSize() / 8.0);

QByteArray data(waveCount * samplesPerWave * sampleSize * format->channelCount(), '\0');

unsigned char* dataPointer = reinterpret_cast<unsigned char*>(data.data());

for (quint32 currentWave = 0; currentWave < waveCount; currentWave++)
{
    for (int currentSample = 0; currentSample < samplesPerWave; currentSample++)
    {
        double nextRadStep = (currentSample / static_cast<double>(samplesPerWave)) * (2 * M_PI);

        quint16 sampleValue = static_cast<quint16>((qSin(nextRadStep) + 1.0) * 16383.0);

        for (int channel = 0; channel < format->channelCount(); channel++)
        {
            qToLittleEndian(sampleValue, dataPointer);
            dataPointer += sampleSize;
        }
    }
}

soundBuffer->append(data);
}

在项目中,您可以添加不同的频率,然后一个接一个地播放,这非常完美.它只需要是一个方波.

有人可以建议我,因为我在数学方面不太擅长,或者可以帮助我理解这段代码,或者告诉我如何在Qt C ++中以这种方式创建方波.任何帮助将不胜感激.

解决方案

就像eyllanesc一样,您可以使用正弦波发生器,在零以下时使用最小值,在零以上时使用最大值.但是要注意的一件事是,这将产生幼稚的方波.这将产生伪影,因为您进行的值更改超出了奈奎斯特限制.为了获得更好的声音,您应该寻求创建一个频带受限的方波.通过将奈奎斯特以下的正弦波谐波相加产生带限方波.

进一步阅读:

奈奎斯特: https://en.wikipedia.org/wiki/奈奎斯特率

频带有限的方波: https://www.nayuki.io/页面/频带有限的方波

Good day experts I need guidance. I have a situation that is two part. Firstly, I need to generate a square wave audio tone for a specific time specified using Qt C++ and I'm completely lost on even where to start.

Secondly I also need to export the audio to a .wav or mp3. I read somewhere that I'll need to write WAV headers to the file before I can export the data. My second question is how to export the audio in the QBuffer to a wav file.

I have found the following project on Git. However this generates a sine wave only and not a square wave. https://github.com/picaschaf/Soundgenerator

Looking at the function in this project

void QxtSoundGenerator::appendSound(qreal amplitude, float frequency, int msecs)
{

msecs = (msecs < 50) ? 50 : msecs;

qreal singleWaveTime = 1.0 / frequency;

qreal samplesPerWave = qCeil(format->sampleRate() * singleWaveTime);

quint32 waveCount = qCeil(msecs / (singleWaveTime * 1000.0));

quint32 sampleSize = static_cast<quint32>(format->sampleSize() / 8.0);

QByteArray data(waveCount * samplesPerWave * sampleSize * format->channelCount(), '\0');

unsigned char* dataPointer = reinterpret_cast<unsigned char*>(data.data());

for (quint32 currentWave = 0; currentWave < waveCount; currentWave++)
{
    for (int currentSample = 0; currentSample < samplesPerWave; currentSample++)
    {
        double nextRadStep = (currentSample / static_cast<double>(samplesPerWave)) * (2 * M_PI);

        quint16 sampleValue = static_cast<quint16>((qSin(nextRadStep) + 1.0) * 16383.0);

        for (int channel = 0; channel < format->channelCount(); channel++)
        {
            qToLittleEndian(sampleValue, dataPointer);
            dataPointer += sampleSize;
        }
    }
}

soundBuffer->append(data);
}

In the project you can append different frequencies then play them one after the other which is perfect. It just needs to be a Square wave.

Can someone please advice me as I'm not very good at math in this regard, or help me understand this block of code or show me how to go about creating a square wave in this fashion in Qt C++. Any help would be greatly appreciated.

解决方案

Like eyllanesc mentioned, you can take the sine wave generator and use the min value when below zero, and the max value when above zero. However one thing to note is that this will produce a naive square wave. This will have artifacts because you have value changes that are above the Nyquist limit. To get a better sound you should be looking to create a band-limited square wave. A band-limited square wave is produced by adding up sine wave harmonics that are below Nyquist.

Further reading:

Nyquist: https://en.wikipedia.org/wiki/Nyquist_rate

Band limited Square waves: https://www.nayuki.io/page/band-limited-square-waves

这篇关于Qt C ++创建方波音频波.播放并保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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