c - 从 SDL2 音频回调函数调用 Chicken Scheme 函数挂起
问题描述
我正在尝试将 Chicken Scheme 嵌入到 C 程序中,以生成要使用 SDL2 的音频系统播放的声音。我本来想使用sdl2 egg,但它似乎还不支持音频(尽管文档中提到了'audio
该函数的标志init!
)。
起初,我使用C 中的SDL_QueueAudio,将我在 C 中分配的缓冲区传递给它,然后填充到 Scheme。这很好用,将 a 传递给Scheme,Sint16 *
然后size_t
使用pointer-s16-set!
from Scheme 填充它并返回 asize_t
以记录填充了多少单元格。
然后,当我意识到使用回调 api生成音频更适合于此时,我尝试切换到它(之前已经在 C 中使用过它),只是为了永远不会输入 Scheme 函数。在调用 Scheme 之前在回调函数中记录某些内容,但直接在 Scheme 函数中或在 Scheme 调用之后记录,从未发生过。
我只能想象这是由于 SDL2 的音频回调在单独的线程上运行,并且以某种方式调用 Scheme 搞砸了。考虑到这一点,我尝试CHICKEN_run(C_toplevel);
在第一次调用回调函数时从回调函数中调用,但这只会导致总线错误。
所以我的问题是:有没有办法从 SDL2 的音频回调中调用嵌入式鸡方案?
我在 macOS 10.13.6 High Sierra 上,安装了 SDL2 和 chicken,并通过 Homebrew 更新。
我编译(正如我所说,这在使用队列音频 api 时工作正常):
csc code.c codescm.scm -embedded -o code -L -lSDL2
我的简化代码如下:
#include <chicken.h>
#include "SDL2/SDL.h"
extern size_t fill_sound_buffer(Sint16 *buffer, size_t buffer_length);
void fill_sound_callback(void *user_data, Uint8 *stream, int stream_length)
{
// Logging here prints to the console
fill_sound_buffer((Sint16 *)stream, stream_length / 2);
// Logging here does not print to the console
}
void play(void)
{
SDL_AudioSpec audio_want;
SDL_zero(audio_want);
audio_want.freq = 44100;
audio_want.format = AUDIO_S16SYS;
audio_want.channels = 1;
audio_want.samples = 2048;
audio_want.callback = fill_sound_callback;
SDL_AudioSpec audio_have;
SDL_AudioDeviceID audio_device = SDL_OpenAudioDevice(NULL, 0, &audio_want, &audio_have, 0);
SDL_PauseAudioDevice(audio_device, 0);
SDL_Delay(5000);
// Logging here shows up after 5 seconds, but the program then continues to wait
SDL_CloseAudioDevice(audio_device);
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_AUDIO);
CHICKEN_run(C_toplevel);
play();
SDL_Quit();
return 0;
}
(import (chicken format)
(chicken foreign)
(chicken memory)
(chicken platform))
(define-external (fill_sound_buffer ((c-pointer short) buffer) (size_t buffer_length)) size_t
; This never prints when using the callback api
(printf "In Scheme~%")
; Removed the code that calculates a sine wave and fills the buffer with it, which works
0)
(return-to-host)
解决方案
推荐阅读
- python - 计算列表 2 中列表 1 中的项目的次数
- angular - 如何使用angularFire从firebase数据库中检索用户列表并且没有“密钥”?
- java - ConstraintLayout 以编程方式设置 constraintHeight_default
- file - 读取 Haskell 中的值和列表列表
- c# - If (Integer Console.Readline "" or null) 不起作用
- upgrade - 升级到 SugarCRM ver 8.0.0 Pro 后无法登录
- html - Angular Sticky Header 重叠内容
- python - 嵌入pytorch
- angular - 仅清除单个输入字段 angular6 模板驱动表单
- excel - Excel - 在 sumif 中用间接代替动态列名