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

Hi, Im looking to understand and create a program that can read the specific input from a mic, or a song - then be able to manipulate that data. I realy have no idea where to begin ( I am only 4 months studying perl ) Any wisdom would be greatly appreciated, thank you.

Replies are listed 'Best First'.
Re: reading sound input
by thunders (Priest) on Jan 21, 2010 at 04:26 UTC

    Which operating system are you on? For *NIX there is a device handle called /dev/dsp that you can read data from, the module Audio::DSP allows an easier interface to setting that up, on windows there's something called Win32::SoundRec. Once you have the data there is another module called PDL::Audio that should allow for manipulation and writing of the file.

    What do you want to do with the sound? For real time recording/manipulation/output perl may not be the best tool for the job, especially if you don't have much experience with perl. Do you have experience with manipulation of sound files?

      AFAIK, the available options are all lousy, and I wouldn't suggest starting any new project in perl using sound input until the situation improves.

      Audio::DSP leaks memory, and the bug report on the memory-leak bug has been open since 2003.

      Audio::OSS depends on OSS, but OSS emulation on Linux has been deteriorating rapidly in quality. It was removed by default in ubuntu 10.10, and you have to jump through extra hoops to get it to work (e.g., installing the also-oss package and invoking your program foo as "aoss foo"). I have experienced a lot of problems with bugs and poor performance, and these can be difficult to test for, since they depend, e.g., on what version of ubuntu you're running.

      What is really missing right now is any kind of ALSA interface for linux. Either that or you could wait five years and hope that the quality of OSS emulation becomes acceptable.

Re: reading sound input
by zentara (Cardinal) on Jan 21, 2010 at 12:44 UTC
    Here's a start on how it's done
    #!/usr/bin/perl use Audio::DSP; #alsamixer must be setup right, just turn everything up :-) $|++; ($buf, $chan, $fmt, $rate) = (4096, 1, 16, 22050); #($buf, $chan, $fmt, $rate) = (4096, 1, AFMT_U16_LE, 44100); #use the formats from soundcard.h, plain 16 wont work with sblive $dsp = new Audio::DSP(buffer => $buf, channels => $chan, format => $fmt, rate => $rate); $dsp->init() || die $dsp->errstr(); # this buffers print to file so that you need ~ 10 secs of audio or t +he file is 0 # like when you hit control-c after a couple of seconds # open(OUT, "| speexenc -n --rate 22050 - test.spx "); ##this works for small low Q ogg open(OUT, "| oggenc -r -R 8000 -B 8 -C 1 -q 0 - | cat > zztest.ogg ") + or warn "No oggenc $!\n"; while ( $buffer = $dsp->dread(4096) ) { syswrite( OUT, $buffer, length($buffer) ); } $dsp->close(); # If you don't set the output of the dsp with arecord, or this # module, the dsp will go to it's lowest setting # speexenc --rate 8000 --le --8bit /dev/dsp - | cat > 1.spx # it works but it sounds lousy. # to convert to wave # sox -r 44100 -u -w -c 1 out1.raw out1.wav # arecord -f S16_LE -c1 -r 22050 -t wav -d 3600 -D hw:0,0 # | speexenc -n --rate 22.05 - - > /home/zentara/`date +%d%b%y%H +%M%S`.spx

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku