使用SDL_audio生成正弦音调无正常输出及流大小异常问题咨询
无正常音调仅存在咔哒声的故障原因
核心错误点:
- 音频格式适配错误:调用
SDL_OpenAudioDevice时你传入了SDL_AUDIO_ALLOW_FORMAT_CHANGE标记,允许SDL修改你申请的音频格式参数(声道数、采样位深、采样率等),但你生成音频数据的逻辑是硬编码匹配16位单声道格式的,一旦SDL返回的实际运行格式和你申请的不一致,写入音频流的数据就会完全错乱,自然无法输出正常音调。 - 方波采样函数逻辑错误:
sampleSquare函数中你直接将sin()返回的[-1, 1]区间浮点数强转为int类型,除极少数边界场景外转换结果均为0,导致该函数几乎永远返回1,输出直流信号,仅在采样点跳变时会产生你听到的咔哒声。 - 音频设备ID丢失:
SDL_AudioDeviceID devID是initializeAudio函数内的局部变量,函数执行结束后就会被销毁,你后续无法对该音频设备做任何控制,极端情况下会导致音频流意外终止。 - 缺少错误校验逻辑:未检查
SDL_OpenAudioDevice的返回值,如果设备打开失败后续所有操作都会无效,也无法定位故障原因。
流大小为设置值两倍的原因
你设置的bufferSize = 1024是单通道的采样点数量,每个采样点为16位(即2字节),SDL音频回调的len参数单位是字节,所以1024个采样点对应的总字节数为1024 * 2 = 2048,刚好是你设置的bufferSize的两倍,属于正常现象。
修复方案
- 修复方波采样函数逻辑:
float Beeper::sampleSquare(float index) { float sinVal = sin(index); return sinVal >= 0 ? 1.0f : -1.0f; }
- 调整音频设备打开逻辑,禁止格式变更,增加错误校验,使用默认音频设备,同时将设备ID改为类成员变量:
// Beeper类的private成员增加一行 SDL_AudioDeviceID devID; // 修改initializeAudio函数中的打开设备逻辑 devID = SDL_OpenAudioDevice(NULL, 0, &desired, &returned, 0); if (devID == 0) { // 此处输出SDL_GetError()的错误信息即可定位设备打开失败问题 return; }
内容的提问来源于stack exchange,提问作者Thomas Cummings
相关产品推荐
相关产品推荐

