我正在嘗試爲PortAudio寫一個球拍接口。每個音頻流都有一個關聯的回放函數用於回放; FFI文件說我應該能夠通過一個球拍程序沒有問題。但是,註冊回調函數似乎會導致分段錯誤,我認爲這是因爲我做錯了什麼。從庫頭:使用球拍在PortAudio註冊回調FFI導致段錯誤
// 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);
我用球拍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
事情我已經嘗試過(單獨或組合):
- 在
Pa_OpenDefaultStream
定義更改_PaStreamCallback
到_pointer
。 - 將
_PaStreamCallback
更改爲(_ptr i _PaStreamCallback)
在相同的定義。 - 通過
(function-ptr stream-callback _PaStreamCallback)
到Pa_OpenDefaultStream
而不是僅僅stream-callback
。
有什麼建議嗎?
我看不出任何明顯的東西。也許@約翰克萊門斯有一個想法?也許你可以在這裏找到解決方案。 https://github.com/jbclements/portaudio/blob/74dfaf1d6317a9f5479ae5492e874e9e73888a46/portaudio/portaudio.rkt#L1383 – soegaard 2014-08-27 18:56:37
謝謝 - 我可能只是使用這個預製解決方案。由於GC的延遲問題,看起來作者選擇不在Racket中編寫回調函數。 – Skatche 2014-08-27 19:35:02