Audio-DSP

 view release on metacpan or  search on metacpan

DSP.xs  view on Meta::CPAN

double
constant(name,arg)
        char *          name
        int             arg

#############################################
################ Constructor ################

void
new (...)
    PPCODE:
    {
        HV* construct      = newHV();
        HV* thistash       = newHV();

        SV* buff           = newSViv(4096);    /* read/write buffer size */
        SV* chan           = newSViv(1);       /* mono(1) or stereo(2) */
        SV* data           = newSVpv("",0);    /* stored audio data */
        SV* device         = newSVpv("/dev/dsp",8);
        SV* errstr         = newSVpvf("",0);
        SV* file_indicator = newSViv(0);       /* file descriptor */

DSP.xs  view on Meta::CPAN

        thistash = gv_stashpv("Audio::DSP", 0);
        sv_bless(self, thistash);         /* bless it */
        XPUSHs(self);                     /* push it */
    }

#################################################################
############## Methods for opening / closing device #############

void
init (...)
    PPCODE:
    {
        SV* format;
        HV* caller = (HV*)SvRV(ST(0));
        char* dev;
        char* key;
        char* val;
        int arg;
        int fd;
        int mode = O_RDWR;  /* device open mode */
        int status;

DSP.xs  view on Meta::CPAN

        }
         
        /**** store file descriptor in Audio::DSP object ****/
        hv_store(caller, "file_indicator", 14, newSViv(fd), 0);

        XSRETURN_YES;
    }

void
open (...)
    PPCODE:
    {
        /* open without sending any ioctl messages */
        HV* caller = (HV*)SvRV(ST(0));
        SV* flag;
        int fd;
        int mode   = O_RDWR;
        char* dev  = SvPVX(*hv_fetch(caller, "device", 6, 0));

        if (items > 1) {
            flag = ST(1);

DSP.xs  view on Meta::CPAN

            hv_store(caller, "errstr", 6,
                     newSVpvf("failed to open audio device file"), 0);
            XSRETURN_NO;
        }
        hv_store(caller, "file_indicator", 14, newSViv(fd), 0);
        XSRETURN_YES;
    }

void
close (...)
    PPCODE:
    {
        /* fetch file descriptor and close... nothing fancy */
        int fd = SvIV(*hv_fetch((HV*)SvRV(ST(0)), "file_indicator", 14, 0));

        if (close(fd) < 0)
            XSRETURN_NO;
        else
            XSRETURN_YES;
    }

#################################################################
####################### I/O control methods #####################

void
channels (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int chan, arg;
        chan = arg = SvIV(ST(1));

        if (ioctl(fd, SNDCTL_DSP_CHANNELS, &arg) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_CHANNELS ioctl failed"), 0);
            XSRETURN_NO;
        }
        XPUSHs(newSViv(arg));
    }

void
getfmts (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int mask;

        if (ioctl(fd, SNDCTL_DSP_GETFMTS, &mask) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_GETFMTS ioctl failed"), 0);
            XSRETURN_NO;
        }
        XPUSHs(newSViv(mask));
    }

void
post (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        if (ioctl(fd, SNDCTL_DSP_POST, 0) == -1) {
            hv_store(caller, "errstr", 6, 
                     newSVpvf("SNDCTL_DSP_POST ioctl failed"), 0);
            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

void
reset (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        if (ioctl(fd, SNDCTL_DSP_RESET, 0) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_RESET ioctl failed"), 0);
            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

void
setduplex (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        if (ioctl(fd, SNDCTL_DSP_SETDUPLEX) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_SETDUPLEX ioctl failed"), 0);
            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

void
setfmt (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        /* SV* format = ST(1); */
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int fmt, arg;
        /* fmt = arg = _audioformat(format); */
        fmt = arg = SvIV(ST(1));

        if (ioctl(fd, SNDCTL_DSP_SETFMT, &arg) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_SETFMT ioctl failed"), 0);
            XSRETURN_NO;
        }
        XPUSHs(newSViv(arg));
    }

void
speed (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int rate, arg;
        rate = arg = SvIV(ST(1));

        if (ioctl(fd, SNDCTL_DSP_SPEED, &arg) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_SPEED ioctl failed"), 0);
            XSRETURN_NO;
        }
        XPUSHs(newSViv(arg));
    }

void
sync (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        if (ioctl(fd, SNDCTL_DSP_SYNC, 0) == -1) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("SNDCTL_DSP_SYNC ioctl failed"), 0);
            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

#################################################################
##################### Direct device I/O #########################

void
dread (...)
    PPCODE:
    {
        /* read data and return it */
        HV* caller = (HV*)SvRV(ST(0));
        int fd = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        int count;
        int status;
        char *buf;

        if (items > 1)

DSP.xs  view on Meta::CPAN

            hv_store(caller, "errstr", 6,
                     newSVpvf("failed to read correct number of bytes"), 0);
            XSRETURN_NO;
        }
        XPUSHs(newSVpvn(buf, status));
        free(buf);
    }

void
dwrite (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));

        int status;
        int count      = SvCUR(ST(1));
        char* diy_data = SvPVX(ST(1));

        status = write(fd, diy_data, count);
        if (status != count) {

DSP.xs  view on Meta::CPAN

            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

#################################################################
##################### "data-in-memory" methods ##################

void
audiofile (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        char audio_buff[AUDIO_FILE_BUFFER_SIZE];
        char* audio_file;
        int audio_fd;
        int status;

        audio_file = SvPVX(ST(1));
        audio_fd   = open(audio_file, O_RDONLY);

DSP.xs  view on Meta::CPAN

        if (close(audio_fd) < 0) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("problem closing audio file '%s'", audio_file), 0);
            XSRETURN_NO;
        }
        XSRETURN_YES;
    }

void
clear (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        hv_store(caller, "data", 4, newSVpv("",0), 0);
        hv_store(caller, "mark", 4, newSViv(0), 0);
    }

void
data (...)
    PPCODE:
    {
        XPUSHs(*hv_fetch((HV*)SvRV(ST(0)), "data", 4, 0));
    }

void
datacat (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int len    = SvCUR(ST(1));

        sv_catpvn(*hv_fetch(caller, "data", 4, 0), SvPVX(ST(1)), len);
        XPUSHs(sv_2mortal(newSViv(SvCUR(*hv_fetch(caller, "data", 4, 0)))));
    }

void
datalen (...)
    PPCODE:
    {
        XPUSHs(sv_2mortal(newSViv(SvCUR(*hv_fetch((HV*)SvRV(ST(0)), "data", 4, 0)))));
    }

void
read (...)
    PPCODE:
    {
        /* read one buffer length of data */
        HV* caller = (HV*)SvRV(ST(0));
        int count  = SvIV(*hv_fetch(caller, "buffer", 6, 0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int status;
        char buf[count];

        status = read(fd, buf, count); /* record some sound */
        if (status != count) {

DSP.xs  view on Meta::CPAN

                     newSVpvf("failed to read correct number of bytes"), 0);
            XSRETURN_NO;
        }

        sv_catpvn(*hv_fetch(caller, "data", 4, 0), buf, status);
        XSRETURN_YES;
    }

void
setmark (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "mark", 4, ST(1), 0);
        }
        XPUSHs(*hv_fetch(caller, "mark", 4, 0));
    }

void
write (...)
    PPCODE:
    {
        HV* caller  = (HV*)SvRV(ST(0));
        int count   = SvIV(*hv_fetch(caller, "buffer", 6, 0));
        int dlength = SvCUR(*hv_fetch(caller, "data", 4, 0));
        int fd      = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int mark    = SvIV(*hv_fetch(caller, "mark", 4, 0));
        int status;
        char* data;

        if (mark >= dlength) /* end of data */

DSP.xs  view on Meta::CPAN


        hv_store(caller, "mark", 4, newSViv(mark + count), 0);
        XSRETURN_YES;
    }

####################################################################
######################### misc. methods ############################

void
errstr (...)
    PPCODE:
    {
        XPUSHs(*hv_fetch((HV*)SvRV(ST(0)), "errstr", 6, 0));
    }

####################################################################
################## Deprecated methods from v.0.01 ##################

void
getformat (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        SV* format = ST(1);
        int arg    = _audioformat(format);
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int mask;

        if (arg < 0) {
            hv_store(caller, "errstr", 6,
                     newSVpvf("error determining audio format"), 0);

DSP.xs  view on Meta::CPAN

        } else if (mask & arg) /* the format is supported */
            XSRETURN_YES;
        else
            hv_store(caller, "errstr", 6,
                     newSVpvf("format not supported"), 0);
            XSRETURN_NO;
    }

void
queryformat (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        int fd     = SvIV(*hv_fetch(caller, "file_indicator", 14, 0));
        int status = ioctl(fd, SNDCTL_DSP_SETFMT, AFMT_QUERY);
        XPUSHs(newSViv(status));
    }

void
setbuffer (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "buffer", 6, ST(1), 0);
        }
        XPUSHs(*hv_fetch(caller, "buffer", 6, 0));
    }

void
setchannels (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "channels", 8, ST(1), 0);
        }
        XPUSHs(*hv_fetch(caller, "channels", 8, 0));
    }

void
setdevice (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "device", 6, ST(1), 0);
        }
        XPUSHs(*hv_fetch(caller, "device", 6, 0));
    }

void
setformat (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));

        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "format", 6, newSViv(_audioformat(ST(1))), 0);
            if (SvIV(*hv_fetch(caller, "format", 6, 0)) < 0) {
                hv_store(caller, "errstr", 6,
                         newSVpvf("error determining audio format"), 0);
                XSRETURN_NO;
            }
        }

        XPUSHs(*hv_fetch(caller, "format", 6, 0));
    }

void
setrate (...)
    PPCODE:
    {
        HV* caller = (HV*)SvRV(ST(0));
        if (items >= 2) {
            SvREFCNT_inc(ST(1));
            hv_store(caller, "rate", 4, ST(1), 0);
        }
        XPUSHs(*hv_fetch(caller, "rate", 4, 0));
    }



( run in 0.835 second using v1.01-cache-2.11-cpan-71847e10f99 )