使用Racket FFI在PortAudio中注册回调会导致段错误

时间:2014-08-27 18:33:13

标签: racket ffi portaudio

我正试图为PortAudio编写一个Racket接口。每个音频流都有一个相关的回调函数用于播放; FFI文档说我应该能够毫无问题地通过一个Racket程序。但是,注册回调的函数似乎会导致分段错误,我认为这是因为我做错了。从图书馆标题:

// portaudio.h
// ...

typedef int PaStreamCallback(
    const void *input, void *output,
    unsigned long frameCount,
    const PaStreamCallbackTimeInfo* timeInfo,
    PaStreamCallbackFlags statusFlags,
    void *userData );
// ...

PaError Pa_OpenDefaultStream( PaStream** stream,
                          int numInputChannels,
                          int numOutputChannels,
                          PaSampleFormat sampleFormat,
                          double sampleRate,
                          unsigned long framesPerBuffer,
                          PaStreamCallback *streamCallback, // <-----
                          void *userData );

我使用了Racket FFI进行导入,没有任何抱怨:

; portaudio.rkt
; ...

(define _PaStreamCallback
  (_fun #:atomic? #t
        _pointer _pointer
        _ulong
        _PaStreamCallbackTimeInfo-pointer
        _PaStreamCallbackFlags
        (_or-null _pointer)
        -> _PaStreamCallbackResult))

; ...

(define-portaudio Pa_OpenDefaultStream
  (_fun (s : (_ptr o _PaStream-pointer))
        _int _int
        _PaSampleFormat
        _double
        _ulong
        _PaStreamCallback ; <-----
        (_or-null _pointer)
        -> (r : _PaError)
        -> (begin (check r 'Pa_OpenDefaultStream) s))
  #:wrap (allocator Pa_CloseStream))

但是以下现在给出了一个分段错误:

(require "portaudio.rkt")

; ...

(define (stream-callback _1 output-buffer frame-count _2 _3 data)
    ... )

; ...

(define stream (Pa_OpenDefaultStream 0 (output-channel-count)
                                       (format-symbol->format (sample-format))
                                       (sample-rate)
                                       (frames-per-buffer)
                                       stream-callback
                                       #f))

结果是:

SIGSEGV MAPERR si_code 1 fault on addr (nil)
Aborted

我尝试过的事情(单独和组合):

  • _PaStreamCallback
  • 的定义中将_pointer更改为Pa_OpenDefaultStream
  • 在同一定义中将_PaStreamCallback更改为(_ptr i _PaStreamCallback)
  • (function-ptr stream-callback _PaStreamCallback)传递给Pa_OpenDefaultStream而不只是stream-callback

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

这是John Clements - 如果您对我的portaudio Racket界面有任何问题,请告诉我们!你可以用

安装它

raco pkg install portaudio

...假设你正在使用6号或更高的球拍。