Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Manipulating Audio Data in Perl

by lofichurch (Beadle)
on Jun 13, 2002 at 20:13 UTC ( [id://174329]=perlquestion: print w/replies, xml ) Need Help??

lofichurch has asked for the wisdom of the Perl Monks concerning the following question:

I'm wondering whether or not anyone out there is currently working to utilize Perl for audio manipulation, in a (mostly) pure-perl implementation? By pure-perl, I mean the code written by the developer, not necessarily any modules being used.

What I'm really wondering is what is the best approach to working with the actual waveform data? Just using perl arrays seems easy enough, where each sample is expressed as an array element, but really bogs down in memory and CPU time when the number of samples exceeds a second's worth at 44,100Hz. I've been using a substr()-based solution, but this has a tendancy to be a big hassle when working with bitrates higher than 8 (and if you don't use pack/unpack, you can end up with garbled data). I've heard of using PDL for this, but can't find a reference to clear examples.

Some examples of using susbtr() to manipulate wave data can be found at http://www.digitalkoma.com/church/projects/perl-dsp.html.

Is anyone out there also wrestling with wave data, and have some suggestions?

Thanks!

Replies are listed 'Best First'.
Re: Manipulating Audio Data in Perl
by Zaxo (Archbishop) on Jun 13, 2002 at 20:52 UTC

    Consider pack/unpack in a pure perl implementation. It may be helpful to set the record delimiter $/ to a reference to a constant integer. That triggers magic which will let you read a file in fixed length chunks.

    There is a PDL::Audio module, but I had difficulty with it, seemed to be version problems. PDL in general is a good way to improve the performance of numerical array operations. I'm currently using it to do FFT of data.

    Update: Have you looked at Mmap for working on these files? Here's a PDL FFT example with a small enough data set to show results explicitly:

    #!/usr/bin/perl -w use strict; use PDL; use PDL::IO::Misc; use PDL::FFT qw(:Func); use constant TWOPI=>8*atan2 1,1; my $data = PDL->new([ map { exp(-$_/10) * cos(TWOPI*3*$_/16) } 0..15 ] +); # this is a print routine print 'Original Data:',$/; PDL::IO::Misc::wcols($data); # works in place, modifies $data realfft($data); print 'Transformed Data:',$/; PDL::IO::Misc::wcols($data); realifft($data); print 'Restored Data:',$/; PDL::IO::Misc::wcols($data);
    Which produces:

    After Compline,
    Zaxo

      Oops, guess I should've specified the ability to look backwards / forwards in the data, hence the substr(). I use the pack/unpack when I don't need to know anything other than a current sample value.

      For example, without using arrays or hashes, be able to look forward in the data while processing an waveform:

      assuming 16bit/mono:
      my $cur_smp = 0; my $len = length($input_data) / 2; foreach (unpack("s*",$input_data)) { # take the value and add to it the sample value # five samples ahead if($len < $cur_smp + 5) { # if we don't have enough samples left to look ahead, # just go with what we've got $output .= pack("s",$_); $cur_smp++; next; } my $five_ahead = unpack("s",substr($input_data,($cur_smp + 5) * 2,2) +); $output .= pack("s",$_ + $five_ahead); $cur_smp++; next; }

      That substr() is a big hit on large amounts of data, but some sort of look-ahead/back is necessary on things like multi-tap delays and variable delays, and a perl array is out of the question. I'm balking at the math knowledge necessary for PDL, since DSP is a pretty new subject for me, on the low-level aspects of the algorithms.

      Would you mind sharing an example of doing the FFT with PDL?

      Thanks!
      !c
Re: Manipulating Audio Data in Perl
by cjf (Parson) on Jun 14, 2002 at 08:55 UTC
    By pure-perl, I mean the code written by the developer, not necessarily any modules being used.

    There's a whole bunch of audio related modules on CPAN. Even if you don't want to use any modules for some strange reason(?) they are worth taking a look at to see how other's have approached the task.

    In particular, the docs for Audio::Wav state that the module is written entirely in Perl. I don't have much experience manipulating audio data though, so I could be completely off the mark here :).

Re: Manipulating Audio Data in Perl
by PetaMem (Priest) on Jun 14, 2002 at 09:49 UTC
    Please have a look at this node. I started years ago with a Perl Virtual Sound Generator, but stopped that project "years ago". Presumably the URL won't work anymore. If you want the sources, I could mail them to you.

    Bye
     PetaMem

Re: Manipulating Audio Data in Perl
by toma (Vicar) on Jun 16, 2002 at 16:30 UTC
    There is an example at Analyzing WAV Files with Perl. In this example, I needed to track the frequency of a tone versus time. I used Audio::Wav, PDL, and PDL::FFT.

    This code includes various algorithms to track the frequency of a tone. The example graphs are for the algorithm that worked best for my application.

    I have written some other audio analysis modules, also, so please let me know if you would like more examples.

    It should work perfectly the first time! - toma

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://174329]
Approved by dws
Front-paged by grep
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-03-19 11:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found