/* hey emacs, this is a -*- C -*- file
*
* Audio::SndFile - perl glue to libsndfile
*
* Copyright (C) 2006 by Joost Diepenmaat, Zeekat Softwareontwikkeling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <sndfile.h>
#include <stdio.h>
typedef SF_INFO* Audio_SndFile_Info;
typedef struct {
SNDFILE* sndfile;
SF_INFO* info;
double* datas;
} Audio_SndFile_t;
typedef Audio_SndFile_t* Audio_SndFile;
SV* to_obj(const char* package, void* p) {
SV* ref;
SV* iv;
iv = newSViv(PTR2IV(p));
ref = sv_bless(newRV_noinc(iv),gv_stashpv(package,0));
SvREADONLY_on(iv);
return ref;
}
MODULE = Audio::SndFile::Info PACKAGE = Audio::SndFile::Info
PROTOTYPES: DISABLE
SV*
new(package)
const char* package
PREINIT:
SF_INFO* info;
CODE:
Newz(0,info, 1, SF_INFO);
if (!info) croak("Error allocating SF_INFO struct.");
RETVAL = to_obj("Audio::SndFile::Info",info);
OUTPUT:
RETVAL
sf_count_t
frames(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->frames;
OUTPUT:
RETVAL
int
get_samplerate(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->samplerate;
OUTPUT:
RETVAL
void
set_samplerate(self, samplerate)
Audio_SndFile_Info self
int samplerate
CODE:
self->samplerate = samplerate;
int
get_channels(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->channels;
OUTPUT:
RETVAL
void
set_channels(self, channels)
Audio_SndFile_Info self
int channels
CODE:
self->channels = channels;
int
get_format(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->format;
OUTPUT:
RETVAL
void
set_format(self, format)
Audio_SndFile_Info self
int format
CODE:
self->format = format;
int
sections(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->sections;
OUTPUT:
RETVAL
int
seekable(self)
Audio_SndFile_Info self
CODE:
RETVAL = self->seekable;
OUTPUT:
RETVAL
int
format_check(self)
Audio_SndFile_Info self
CODE:
RETVAL = sf_format_check(self);
OUTPUT:
RETVAL
MODULE = Audio::SndFile::Constants PACKAGE = Audio::SndFile::Constants
PROTOTYPES: ENABLE
INCLUDE: constants.xs
MODULE = Audio::SndFile PACKAGE = Audio::SndFile PREFIX=sf_
PROTOTYPES: DISABLE
SV*
open_fd(package, fd, mode, info,close)
const char* package
int fd
int mode
Audio_SndFile_Info info;
int close
PREINIT:
Audio_SndFile self;
CODE:
if (mode == SFM_WRITE && !sf_format_check(info)) croak("invalid format for writing");
Newz(0,self, 1, Audio_SndFile_t);
if(!self) croak("Error allocating Audio_SndFile struct");
self->info = info;
self->sndfile = sf_open_fd(fd,mode,info,close);
if(!self->sndfile) croak("Error opening filehandle: %s",sf_strerror(NULL));
RETVAL = to_obj(package,self);
OUTPUT:
RETVAL
SV*
info(self)
Audio_SndFile self
CODE:
RETVAL = to_obj("Audio::SndFile::Info",self->info);
OUTPUT:
RETVAL
void
sf_close( self )
SNDFILE* self
sf_count_t
sf_seek(self, frames, whence)
SNDFILE* self
sf_count_t frames
int whence
int
sf_command(self, cmd, data, datasize)
SNDFILE* self
int cmd
void* data
int datasize
int
sf_error(self)
SNDFILE* self
const char*
sf_strerror(self)
SNDFILE* self
#ifdef sf_write_sync
void
sf_write_sync(self)
SNDFILE* self
#endif
sf_count_t
read_raw(self, buff, bytes)
SNDFILE* self
SV* buff
sf_count_t bytes
CODE:
RETVAL = sf_read_raw(self, (void*) SvGROW(buff, bytes+1),bytes);
SvCUR_set(buff,RETVAL);
OUTPUT:
RETVAL
sf_count_t
write_raw(self, buff)
SNDFILE* self
SV* buff
CODE:
RETVAL = sf_write_raw(self, (void*) SvPV_nolen(buff), SvCUR(buff));
OUTPUT:
RETVAL
INCLUDE: functions.xs
SV*
lib_version()
PREINIT:
char buff[2048];
CODE:
sf_command(NULL, SFC_GET_LIB_VERSION, buff, sizeof(buff));
RETVAL = newSVpv(buff,0);
OUTPUT:
RETVAL
#ifdef SFC_GET_LOG_INFO
SV*
log_info(self)
SNDFILE* self
PREINIT:
SV* log;
int len;
CODE:
log = newSV( 4096 );
len = sf_command(self, SFC_GET_LOG_INFO, SvPVX(log) , SvLEN(log));
while ( len == SvLEN(log) ) {
SvGROW(log,SvLEN(log) + 4096);
len = sf_command(NULL, SFC_GET_LOG_INFO, SvPVX(log) , SvLEN(log));
}
SvLEN_set(log, len);
SvPOK_on(log);
RETVAL = log;
OUTPUT:
RETVAL
#endif
#ifdef SFC_FILE_TRUNCATE
int
truncate(self, frames)
SNDFILE* self
sf_count_t frames
CODE:
RETVAL = sf_command(self, SFC_FILE_TRUNCATE, &frames, sizeof(sf_count_t));
#endif
#ifdef SFC_SET_RAW_START_OFFSET
int
set_raw_start_offset(self, offset)
SNDFILE* self
sf_count_t offset
CODE:
RETVAL = sf_command(self, SFC_SET_RAW_START_OFFSET, &offset, sizeof(sf_count_t));
#endif
#ifdef SFC_SET_CLIPPING
int
set_clipping(self, boolean)
SNDFILE* self
int boolean
CODE:
RETVAL = sf_command(self, SFC_SET_CLIPPING, NULL, boolean ? SF_TRUE : SF_FALSE );
#endif
#ifdef SFC_GET_CLIPPING
int
get_clipping(self)
SNDFILE* self
CODE:
RETVAL = sf_command(self, SFC_GET_CLIPPING, NULL, 0 );
#endif