Audio-DSP
view release on metacpan or search on metacpan
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 */
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;
}
/**** 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);
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)
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) {
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);
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) {
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 */
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);
} 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 )