Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

channel_extraction

by kle15 (Initiate)
on Jul 19, 2005 at 21:56 UTC ( #476283=sourcecode: print w/replies, xml ) Need Help??
Category: data extraction
Author/Contact Info Kevin Epson (kle15@psu.edu) originally written by martial michel
Description: Im hoping for someone to optimize this code in PDL plz!!!! ## Simple program to extract raw simple channel data from ## a multiple channel raw file
#!/usr/bin/env perl

use Getopt::Long;
$Getopt::Long::autoabbrev = 1;
$Getopt::Long::ignorecase = 0;

use File::Basename;

use strict;

# Defaults + Variables
my $dmaxchannel = 64 
my $maxchannel  = -1;
my $dbytes      = 3;
my $bytes       = -1;
my $dreadinc    = 500;
my $readinc     = -1;
my $channel     = -1;
my $infile      = "";
my $outfile     = "";
my $force       = 0;
my $quiet       = 0;
my $use1of      = 0;

# Usage
my $usage =<< "END";
Usage: $0 [--outfile F] [--channels C] [--bytes B] [--readinc R] [--fo
+rce] [--quiet] channelnumber inputfile [inputfile inputfile ...]
  channelnumber   channel to extract
  inputfile       file to open (raw data)
  --outfile F     file to write the extracted channel to (default is "
+channelnumber-inputfile"). Only one file can be specified, all data f
+rom input files will be concatenated to this file.
  --channels C    number of channels in the input file (default: $dmax
+channel)
  --bytes B       number of bytes per channel in the input file (defau
+lt: $dbytes)
  --readinc R     Number of chunks of data to process at a time (for s
+peedup vs memory use) (default: $dreadinc)
  --force         Forces the use of input file if its size does not ma
+tch the 'channels*bytes' requirements
  --quiet         Run in quiet mode
END

# Option processing + use of default values
GetOptions
  (
   'outfile=s'     => \$outfile,
   'channels=i'    => \$maxchannel,
   'bytes=i'       => \$bytes,
   'readinc=i'     => \$readinc,
   'force'         => sub {$force = 1;},
   'quiet'         => sub {$quiet = 1;}
  ) || usage();
$maxchannel = $dmaxchannel if ($maxchannel == -1);
$bytes = $dbytes if ($bytes == -1);
$readinc = $dreadinc if ($readinc == -1);
my $verb = ($quiet == 1) ? 0 : 1;
$use1of = ($outfile ne "") ? 1 : 0;

$| = 1 if ($verb);

# Channel number
$channel = shift @ARGV;
die "Error: Channel ($channel) must be between 1 and $maxchannel\n\n$u
+sage"
  if (($channel < 1) || ($channel > $maxchannel));

####################
# Opening/Checking Input file
my @tinfiles = @ARGV;
my @infiles;
my $tfs = 0;
my %fs;
print "\nChecking input file(s)..." if ($verb);
foreach $infile (@tinfiles) {
  die "Error: Invalid file name ($infile)\n"
    if ($infile eq "");
  $infile =~ s{^~([^/]*)}{$1?(getpwnam($1))[7]:($ENV{HOME} || $ENV{LOG
+DIR})}ex;
  push @infiles, $infile;
  if (exists $fs{$infile}) {
    print "Warning: file ($infile) seems to be listed more than once\n
+";
    next;
  }
  die "Error: Input file ($infile) does not exist, aborting !\n"
    if (! -e $infile);
  $fs{$infile} = (stat($infile))[7];
  $tfs += $fs{$infile};
  die "Error: Input file size (" . $fs{$infile} . ") is not a multiple
+ of $maxchannel channels by $bytes bytes (maybe not a \"real\" raw fi
+le); use \'--force\' to process this file\n"
    if ((! $force) && ($fs{$infile} % ($maxchannel * $bytes)));
  open INFILE, "<$infile"
    or die "Error: Could not open input file ($infile): $!\n\n$usage";
  close INFILE;
}
print " done\n" if ($verb);

####################
# Processing each input files
my $totalread;
my $percent;
my ($tottofs, $totwofs);
while ($infile = shift @infiles) { # "foreach" does not seem to set $i
+nfile
  ### Creating outputfile
  # Multiple output files
  if ($use1of == 0) {
    if ($outfile eq "") {
      $outfile = $infile;
      $outfile =~ /^(.*?)([^\/]+)$/;
      my $infile_dir = $1;
      my $infile_file = $2 ;

      $outfile = $infile_dir . sprintf("%02d", $channel) . "-$infile_f
+ile";
    }
  }
  # Multiple and single output file
  if (($use1of - 1) <= 0) {
    $outfile =~ s{^~([^/]*)}{$1?(getpwnam($1))[7]:($ENV{HOME} || $ENV{
+LOGDIR})}ex;
    my $as = checkspaceleft($outfile);
    my $sr = (($use1of == 1) ? $tfs : $fs{$infile}) / $maxchannel;
    my $ksr = $sr / 1024; # kb value (for 'df -k')
    die "Error: Not enough space left on device for writting output fi
+le ($outfile), estimated size of $ksr KB is more than available ($as 
+KB), aborting\n" if ($as < $ksr);
    open OUTFILE, ">$outfile"
      or die "Error: Could not open output file ($outfile): $!\n\n$usa
+ge";
    binmode OUTFILE;
  }
  # One output file ... stay with only one
  $use1of++ if ($use1of == 1);

  ### Opening inputfile
  open INFILE, "<$infile"
    or die "Error: Could not open input file ($infile): $!\n\n$usage";
  binmode INFILE;

  if ($verb) {
    print "\n";
    print << "END";
Will extract:
 - Channel $channel (out of $maxchannel) with $bytes byte(s) per chann
+el
 - Input file : $infile
 - Output file: $outfile
 - will read/write a group of $readinc such elements at a time (for sp
+eedup)
END
    print "\n";
  }

  my $toread = $readinc*$maxchannel*$bytes;
  my $toskip_pre = $bytes*($channel - 1);
  my $toskip_post = ($maxchannel - $channel)*$bytes;
  my $running = 1;
  my $read = 0;
  my $outsize = 0;
  my $buffer;
  $percent = -1; # Set the variable even if we do not use it
  $totalread = 0;
  while ($running) {
    $read = read(INFILE, $buffer, $toread);
    $totalread += $read;

    $running = 0 if ($read < $toread);

    my $outbuffer = "";
    for (my $i = 0; $i < $read; $i += $maxchannel*$bytes) {
      my $done = ($buffer =~ s/^.{$toskip_pre}(.{$bytes}).{$toskip_pos
+t}//s);
      if ($done) {
    $outbuffer .= $1;
    $outsize += $bytes;
    }
    }
    print OUTFILE $outbuffer;
    pprint();
  }

  if (! $quiet) {
    print "\rProgress ... done     \n\n";

    print "Read from input file     : ", $totalread, " bytes\n";
    print "Supposed output file size: ", $totalread / $maxchannel, " b
+ytes\n";
    print "Written to output file   : ", $outsize, " bytes\n";
  }
  if ($use1of == 2) {
    $tottofs += $totalread / $maxchannel;
    $totwofs += $outsize;
  }

  close INFILE;
  close OUTFILE if ($use1of == 0);
}
if ($use1of == 2) {
  close OUTFILE;
  if ($verb) {
    print "\n";
    print "Total supposed output file size : ", $tottofs, " bytes\n";
    print "Total written output file size  : ", $totwofs, " bytes\n";
    print "Real output file size           : ", (stat($outfile))[7], "
+ bytes\n";
  }
}

sub checkspaceleft {
  my $file = shift @ARGV;
  my $return = 10000;
  my $match = "";

  my $base = dirname($file);
  $base = $ENV{PWD} if ($base eq ".");

  my @tmp = 'df -k';
  chomp(@tmp);
  shift(@tmp);

  foreach my $line (@tmp) {
    my ($dev, $blocks, $used, $avail, $cap, $mount) = split(/\s+/, $li
+ne);
    next if ($base !~ /^$mount/);
    if (length($match) < length($mount)) {
      $match  = $mount;
      $return = $blocks;
    }
  }

  return $return;
}

sub pprint {
  return if ($quiet);

  my $t = int (100 * $totalread / $fs{$infile});
  if ($t > $percent) {
    printf("\rProgress: %03d %%", $t);
    $percent = $t;
  }
}
Replies are listed 'Best First'.
Re: channel_extraction
by Jaap (Curate) on Jul 20, 2005 at 08:13 UTC
    Please forgive my ignorance but... what does this do?
      Sorry for the vague explanation of this code. it is part of a data extraction project that i (kle15) am working on. without going into the technics of it, i will say that following the 'usage' instructions (around line 28), one should be able to extract/read sound data from an arbitrary file type (please email me kle15@psu.edu for this file or more info).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://476283]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2021-10-23 20:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (88 votes). Check out past polls.

    Notices?