作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我无法理解 sdl 库的音频部分是如何工作的现在,我知道当你初始化它时,你必须指定频率和一个 >>callback<< 函数,我认为它会以给定的频率自动调用。使用 sdl 库的任何人都可以编写一个简单的示例,使用 sdl_audio 以 44000 赫兹的采样频率生成 440 赫兹的方波(因为它是最简单的波形)吗?
最佳答案
Introduction to SDL (2011 缓存版本:2)有一个使用 SDL 声音库的简洁示例,应该可以帮助您入门:http://www.libsdl.org/intro.en/usingsound.html
编辑:这是一个可以执行您要求的工作程序。我修改了这里的代码:http://www.dgames.org/beep-sound-with-sdl/
#include <SDL/SDL.h>
#include <SDL/SDL_audio.h>
#include <queue>
#include <cmath>
const int AMPLITUDE = 28000;
const int FREQUENCY = 44100;
struct BeepObject
{
double freq;
int samplesLeft;
};
class Beeper
{
private:
double v;
std::queue<BeepObject> beeps;
public:
Beeper();
~Beeper();
void beep(double freq, int duration);
void generateSamples(Sint16 *stream, int length);
void wait();
};
void audio_callback(void*, Uint8*, int);
Beeper::Beeper()
{
SDL_AudioSpec desiredSpec;
desiredSpec.freq = FREQUENCY;
desiredSpec.format = AUDIO_S16SYS;
desiredSpec.channels = 1;
desiredSpec.samples = 2048;
desiredSpec.callback = audio_callback;
desiredSpec.userdata = this;
SDL_AudioSpec obtainedSpec;
// you might want to look for errors here
SDL_OpenAudio(&desiredSpec, &obtainedSpec);
// start play audio
SDL_PauseAudio(0);
}
Beeper::~Beeper()
{
SDL_CloseAudio();
}
void Beeper::generateSamples(Sint16 *stream, int length)
{
int i = 0;
while (i < length) {
if (beeps.empty()) {
while (i < length) {
stream[i] = 0;
i++;
}
return;
}
BeepObject& bo = beeps.front();
int samplesToDo = std::min(i + bo.samplesLeft, length);
bo.samplesLeft -= samplesToDo - i;
while (i < samplesToDo) {
stream[i] = AMPLITUDE * std::sin(v * 2 * M_PI / FREQUENCY);
i++;
v += bo.freq;
}
if (bo.samplesLeft == 0) {
beeps.pop();
}
}
}
void Beeper::beep(double freq, int duration)
{
BeepObject bo;
bo.freq = freq;
bo.samplesLeft = duration * FREQUENCY / 1000;
SDL_LockAudio();
beeps.push(bo);
SDL_UnlockAudio();
}
void Beeper::wait()
{
int size;
do {
SDL_Delay(20);
SDL_LockAudio();
size = beeps.size();
SDL_UnlockAudio();
} while (size > 0);
}
void audio_callback(void *_beeper, Uint8 *_stream, int _length)
{
Sint16 *stream = (Sint16*) _stream;
int length = _length / 2;
Beeper* beeper = (Beeper*) _beeper;
beeper->generateSamples(stream, length);
}
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_AUDIO);
int duration = 1000;
double Hz = 440;
Beeper b;
b.beep(Hz, duration);
b.wait();
return 0;
}
祝你好运。
关于c++ - 在 C++ 中使用 SDL 的简单声波发生器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10110905/
我是一名优秀的程序员,十分优秀!