Audio-Wav

 view release on metacpan or  search on metacpan

Wav/Read.pm  view on Meta::CPAN

    my $length = shift;
    my $data = $self -> _read_raw( $length );
    my $types = $self -> {tools} -> get_wav_pack();
    my $pack_str = '';
    my $fields = $types -> {order};
    foreach my $type ( @{$fields} ) {
        $pack_str .= $types -> {types} -> {$type};
    }
    my @data = unpack $pack_str, $data;
    my %record;
    for my $id ( 0 .. $#{$fields} ) {
        $record{ $fields -> [$id] } = $data[$id];
    }
    return { %record };
}

sub _read_long {
    my $self = shift;
    my $data = $self -> _read_raw( 4 );
    return unpack 'V', $data; 
}

sub _error {
    my ($self, @args) = @_;
    return $self -> {tools} -> error( $self -> {file}, @args );
}

=head1 AUTHORS

    Nick Peskett (see http://www.peskett.co.uk/ for contact details).
    Brian Szymanski <ski-cpan@allafrica.com> (0.07-0.14)
    Wolfram humann (pureperl 24 and 32 bit read support in 0.09)
    Kurt George Gjerde <kurt.gjerde@media.uib.no>. (0.02-0.03)

=cut

1;

__DATA__

#ifdef WIN32
  // Note: if it becomes a problem that Visual Studio 6 and
  // Embedded Visual C++ 4 dont realize that char has the same
  // size as int8_t, check for #if (_MSC_VER < 1300) and use
  // signed __int8, unsigned __int16, etc. as in:
  // http://msinttypes.googlecode.com/svn/trunk/stdint.h
  typedef signed char       int8_t;
  typedef signed short      int16_t;
  typedef signed int        int32_t;
  typedef unsigned char     uint8_t;
  typedef unsigned short    uint16_t;
  typedef unsigned int      uint32_t;
#endif

//NOTE: 16, 32 bit audio do *NOT* work on big-endian platforms yet!
//verified formats (output is identical output to pureperl):
// 1 channel signed   16 little endian
// 2 channel signed   16 little endian
// 1 channel unsigned  8 little endian
// 2 channel unsigned  8 little endian
//verified "looks right" on these formats:
// 1 channel signed   32 little endian
// 2 channel signed   32 little endian
// 1 channel signed   24 little endian
// 2 channel signed   24 little endian

//maximum number of channels per audio stream
#define MAX_CHANNELS 10
//maximum number of bytes per sample (in one channel)
#define MAX_SAMPLE 4

FILE *handle;
int sample_size;
int channels;
int big_end;
int is_signed;
char buf[MAX_SAMPLE];
SV* retvals[MAX_CHANNELS];

void init(FILE *fh, int ss, int ch, int be) {
    int i;
    handle = fh;
    sample_size = ss;
    channels = ch;
    big_end = be;
    is_signed = (ss != 1); //TODO: is this really right?
    for(i=0; i<MAX_CHANNELS; i++) {
        retvals[i] = newSV(0);
    }
}

void read_c(void *self) {
    int samples[MAX_CHANNELS];
    int nread;
    int i, s;

    Inline_Stack_Vars;
    Inline_Stack_Reset;

    for(i=0; i<channels; i++) {
        // having fread in the loop is probably slightly less efficient,
        // but it avoids byte alignment problems and fread is buffered,
        // so it "shouldn't be a problem" (tm). more info:
        // http://www.eventhelix.com/RealtimeMantra/ByteAlignmentAndOrdering.htm
        nread = fread( buf, sample_size, 1, handle );
        if( !nread ) {
            if( feof( handle ) && i ) {
                perror("got EOF mid-sample!");
            } else if( ferror( handle ) ) {
                perror("io error");
            }
            break;
        }
        switch(sample_size) {
            case 4:
                if(big_end) {
                    s = buf[0]; buf[0] = buf[3]; buf[3] = s;
                    s = buf[1]; buf[1] = buf[2]; buf[2] = s;
                }
                s = is_signed ?
                    *((int32_t *)buf) :



( run in 2.346 seconds using v1.01-cache-2.11-cpan-d8267643d1d )