Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
There's more than one way to do things.
 
PerlMonks

Manipulating Audio Data in Perl

by lofichurch (Beadle)
 | Log in | Create a new user | The Monastery Gates | Super Search | 
 | Seekers of Perl Wisdom | Meditations | PerlMonks Discussion | 
 | Obfuscation | Reviews | Cool Uses For Perl | Perl News | Q&A | Tutorials | 
 | Poetry | Recent Threads | Newest Nodes | Donate | What's New | 

on Jun 13, 2002 at 20:13 UTC ( #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!

Comment on Manipulating Audio Data in Perl
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

[reply]
[d/l]

      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
[reply]
[d/l]
Re: Manipulating Audio Data in Perl
by cjf (Vicar) 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 :).

[reply]
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

[reply]
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

[reply]

Back to Seekers of Perl Wisdom


Login:
Password
remember me
What's my password?
Create A New User

Node Status
node history
Node Type: perlquestion [id://174329]
Approved by dws
Front-paged by grep
help
Community Ads
Chatterbox
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users
Others avoiding work at the Monastery: (6)
GrandFather
wfsp
atcroft
herveus
Eyck
gnosti
As of 2009-11-21 09:33 GMT
Sections
The Monastery Gates
Seekers of Perl Wisdom
Meditations
PerlMonks Discussion
Categorized Q&A
Tutorials
Obfuscated Code
Perl Poetry
Cool Uses for Perl
Perl News
Information
PerlMonks FAQ
Guide to the Monastery
What's New at PerlMonks
Voting/Experience System
Tutorials
Reviews
Library
Perl FAQs
Other Info Sources
Find Nodes
Nodes You Wrote
Super Search
List Nodes By Users
Newest Nodes
Recently Active Threads
Selected Best Nodes
Best Nodes
Worst Nodes
Saints in our Book
Leftovers
The St. Larry Wall Shrine
Offering Plate
Awards
Craft
Snippets Section
Code Catacombs
Quests
Editor Requests
Buy PerlMonks Gear
PerlMonks Merchandise
Planet Perl
Perlsphere
Use Perl
Perl.com
Perl 5 Wiki
Perl Jobs
Perl Mongers
Perl Directory
Perl documentation
CPAN
Random Node
Voting Booth

Future historians will find that the material characteristic of the current era is...

Aluminium
Plastic
Oil
Water
Carbon dioxide
Copper
Iron
Silicon
Salt
Uranium
Hydrogen
Other

Results (729 votes), past polls