【发布时间】:2019-08-11 15:15:30
【问题描述】:
我正在尝试通过使用 C++ 上的音频队列来使用 SDL2 播放正弦波声音。为了做到这一点,我创建了一个“扬声器”类,它有一个 pushBeep 函数,每次需要生成哔声时都会调用该函数。我已经成功创建了一个 AudioDevice,当我对设备执行 QueueAudio 时它也成功(我已经检查了调试器)但我似乎无法从中获得任何声音。
我已经尝试以多种方式更改生成样本的方式,而且,正如我之前所说,我已经检查了设备是否正确打开并且 QueueAudio 返回 0 表示成功。
这是课
Speaker::Speaker()
{
SDL_AudioSpec ds;
ds.freq = Speaker::SPEAKER_FREQUENCY;
ds.format = AUDIO_F32;
ds.channels = 1;
ds.samples = 4096;
ds.callback = NULL;
ds.userdata = this;
SDL_AudioSpec os;
this->dev = SDL_OpenAudioDevice(NULL, 0, &ds, &os, NULL);
std::cout << "DEVICE: " << this->dev << std::endl;
SDL_PauseAudioDevice(this->dev, 0);
}
Speaker::~Speaker()
{
SDL_CloseAudioDevice(this->dev);
}
void Speaker::pushBeep(double freq, int duration) {
int nSamples = duration * Speaker::SPEAKER_FREQUENCY / 1000;
float* samples = new float[nSamples];
double v = 0.0;
for (int idx = 0; idx < nSamples; idx++) {
//float value = (float)Speaker::SPEAKER_AMPLITUDE * std::sin(v * 2 * M_PI / Speaker::SPEAKER_FREQUENCY);
float value = 440.0;
samples[idx] = value;
v += freq;
}
int a = SDL_QueueAudio(this->dev, (void*)samples, nSamples * sizeof(float));
std::cout << a << std::endl;
delete[] samples;
samples = NULL;
}
这就是我的称呼
Speaker s;
s.pushBeep(440.0, 1000);
当我尝试使用正弦波生成代码(已注释)时,它给了我一个“双精度浮点损失”错误。当我使用固定值(未注释)时,它不会给出错误,但它仍然不起作用。
我希望程序能够输出声音。
【问题讨论】:
-
sin的注释行是怎么回事?应该没问题(取决于“幅度”值),常数不是。设置常数值是......好吧,我们说不是很听得见,只是一声响亮的咔嗒声,然后什么也没有。浮动应该在 1.0 达到峰值,440 太多了,很可能会被削减。 -
@keltar 正如我在 OP 上解释的那样,我也尝试了评论行,但没有效果,我什么也听不到。但是,如果浮点数需要介于 0 和 1 之间,那么该行也是错误的,因为它创建的值超出了限制……成千上万。我会试试这个并报告。关于声音的长度,我相信这取决于您在队列中放置的样本数量。
-
@dagilpe 这就是我所说的,“取决于幅度值”。幅度 1 在这里很好。长度从来都不是问题,我是说恒定值甚至不是波浪(但我们正在进入波浪定义的迂腐基础 - 我们不应该),理论上它只能在值跳跃时在第一个样本中被听到从 0 到你的常数,当它最后回落到 0 时。
-
它不是 [0;1] 而是 [-1;1] (在这里并不重要,只是为了清楚起见,正弦波完美地包裹到负数)。