AW: Problem with C callback (PortAudio)
Hi Chris,
this is just a rough guess. Did you compile the callback function?
Interpreted code is slow in Lispworks AFAIK. This might be a problem in
audio processing.
Andreas
> -----Ursprüngliche Nachricht-----
> Von: owner-lisp-hug@lispworks.com [mailto:owner-lisp-hug@lispworks.com]
> Im Auftrag von Chris Melen
> Gesendet: Montag, 6. April 2009 00:54
> An: lisp-hug@lispworks.com
> Betreff: Problem with C callback (PortAudio)
>
>
> I have written some bindings for PortAudio, a widely-used cross-
> platform C
> audio API. It requires a callback, which is called continuously while
> audio is
> required. It works, but I often encounter the following error -
>
> Error: Exception C0000005 [flags 0] at 218313C
> eax 40200 ebx 262FA60 ecx 19CEF0 edx A5BFE8
> esp 262FA14 ebp 0 esi 0 edi FFFFFFFF
> 1 (abort) Return to event loop.
>
> Type :b for backtrace, :c <option number> to proceed, or :? for other
> options
>
> PORTAUDIO-TEST 1 : 1 > :b
> Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION
> SYSTEM::|%FOREIGN-CALLABLE/fault_handler_on_c_stack|
> (FLI:DEFINE-FOREIGN-CALLABLE "fault_handler_on_c_stack"))
> Call to FLI::FOREIGN-CALLABLE-ENTRY-POINT-AUX-NESTED
> Call to |%cffi-foreign-function/PA-OPEN-STREAM|
> Interpreted call to PA-OPEN-STREAM
> Interpreted call to PLAY-SAMPLES
> Call to CAPI::EXECUTE-CALLBACK
> Call to CAPI:EXECUTE-WITH-INTERFACE
> Call to CAPI-WIN32-LIB::PERFORM-WM-COMMAND-FOR-R-PCL-WINDOW
> Call to WIN32::WND-PROC
> Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION
> WIN32::|%FOREIGN-CALLABLE/wnd_proc_callback| (FLI:DEFINE-FOREIGN-
> CALLABLE
> "wnd_proc_callback"))
> Call to FLI::FOREIGN-CALLABLE-ENTRY-POINT-AUX-NESTED
> Call to WIN32:IS-DIALOG-MESSAGE
> Call to WIN32::PROCESS-MESSAGES
> Call to MP::WIN32-PROCESS-WAIT-FOR-EVENT
> Call to MP:PROCESS-READ-EVENT
> Call to CAPI-INTERNALS:LOOP-PROCESS-EVENTS
> Call to CAPI::INTERFACE-EVENT-LOOP
> Call to CAPI::INITIALIZE-AND-PROCESS-EVENTS
> Call to (HARLEQUIN-COMMON-LISP:SUBFUNCTION MP::PROCESS-SG-FUNCTION
> MP::INITIALIZE-PROCESS-STACK)
>
> On my Mac I simply get this -
>
> Bus error(10) [code F068C678] at C
>
> The callback itself takes the following form (I'm using CFFI) -
>
> (defcallback process-samples :int ((input :pointer)
> (output :pointer)
> (frames-per-buffer :ulong)
> (time-info pa-stream-callback-time-
> info)
> (status-flags pa-stream-callback-
> flags)
> (user-data :pointer))
> (declare (ignore input time-info status-flags user-data))
> (loop with n-samps = (length *samples*)
> for i from 0 below frames-per-buffer
> for j = (+ *counter* i)
> if (< j n-samps)
> do (setf (mem-aref output :float i) (aref *samples* j))
> else do
> (setf *counter* 0)
> (return 1)
> finally
> (setf *counter* (+ *counter* frames-per-buffer))
> (return 0)))
>
> This simply writes samples from the Lisp array *samples* to the output
> audio
> buffer in blocks of size frames-per-buffer (in this case 2048). While
> the
> callback returns 0 it continues to be called, returning 1 stops it. The
> variable *counter* stores the current position within the sample
> buffer.
>
> I suspect the error I'm getting may be due to GC occurring during the
> callback
> process, thus moving objects which the foreign code is still pointing
> to. I've
> declared my samples buffer static to hopefully account for this, but
> the error
> remains. The callback lives in its own thread, so possibly it's a
> multi-threading problem... Plus I'm calling PortAudio from a menu in my
> main
> interface, which adds possibly another level of complication...
>
> PortAudio also has a non-callback interface, which causes no problems,
> but the
> advantage of the callback approach is that it allows me to update
> various
> variables on a 'per sample' basis. More info on this can be found at
> http://www.portaudio.com/trac/wiki/TutorialDir/WritingACallback.
>
> Any help/suggestions greatly appreciated.
>
> Chris