#include /* -*- c -*- */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include "ppport.h" #include typedef struct { SV *isv; SV *cbfn; PerlInterpreter *pi; } mybundle; static PortAudioStream *pa_stream; static mybundle bundle; static int pa_callback (void *in, void *out, unsigned long nsamps, PaTimestamp outTime, void *user) { unsigned char *fromperl; mybundle *intbundle = (mybundle *) user; PERL_SET_CONTEXT (intbundle->pi); if (intbundle->cbfn == NULL) croak ("Soundzero: PA callback called, but not set to point to " "any perl function.\n"); { dSP; int count; ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs (sv_2mortal(newSVpvn((unsigned char *) in, nsamps))); PUTBACK; count = perl_call_sv (intbundle->cbfn, G_SCALAR); SPAGAIN; if (count != 1) croak ("Soundzero: PA callback function did not return a scalar.\n"); fromperl = (unsigned char *) POPp; memcpy (out, fromperl, nsamps); PUTBACK; FREETMPS; LEAVE; } return 0; } MODULE = Soundzero PACKAGE = Soundzero void pa_init (samplerate, buflen) double samplerate int buflen CODE: bundle.isv = newSVpvn (NULL, buflen); bundle.pi = Perl_get_context (); bundle.cbfn = (SV *) NULL; Pa_Initialize (); Pa_OpenDefaultStream (&pa_stream, 1, 1, paUInt8, samplerate, buflen, 0, pa_callback, &bundle); void pa_sleep (mili) int mili CODE: Pa_Sleep (mili); void pa_stop () CODE: Pa_StopStream (pa_stream); void pa_start () CODE: Pa_StartStream (pa_stream); void pa_close () CODE: Pa_CloseStream (pa_stream); Pa_Terminate (); void registercb (cbname) SV * cbname CODE: if (bundle.cbfn == (SV *) NULL) { bundle.cbfn = newSVsv (cbname); } else { SvSetSV (bundle.cbfn, cbname); }