Editing wav or mp3 using php

I’m looking to be able to edit wav (or mp3) files using PHP. I want to overlay one sound over another.

I can join to files together into one file, but I’m not sure how to get them to play over top of one another. Anyone have experience or know of a class?

I’m using wavedit class.

I would be looking for audio editing program that accepts command line arguments, so you can easily execute it with php.

I guess I’ll have to install something on my server then. I was hoping to avoid that. But I guess there’s no work-around. I was hoping there might be, but joining wav files is a much easier process than overlaying them.

You can use ffmpeg and/or mencoder for that.

If you really need it to be in pure php, you could merge raw wav-files, as long as they are unencoded and has the same bit-rate and sample-rate. It’s bound to be horribly slow and memory-expensive though.

If you have to work with MP3 files as well, then you don’t have a choice except to use an external command line program.

I don’t have to use .mp3… .wav is fine.

Is there a way to do it with PHP? The script wouldn’t even run daily – like once/twice per week.

Just to reiterate:
I need to be able to overlay one .wav file over another and save it (e.g. voice over music)

ffmpeg doesn’t seem capable of doing this? I couldn’t find any support for it - but I did find a couple of posts around the net saying it wouldn’t be possible. I’d prefer to use straight PHP at this time, but if there is a command line program that’d be okay too.

sox is what you want to achieve this, not ffmpeg.

@kyberfabrikken
is it possible to overlay two wav files to create one file (like spoken word over music) using pure PHP? And can you point me in the right direction?

You can check PHPClasses to see if there is anything available:
http://www.phpclasses.org/browse/class/34/page/3.html

If you want to mix together two tracks that are of the same sample rate, it’s pretty easy. You simply add the two tracks together, sample by sample. However, you need to be aware of clipping, but you can “solve” that by reducing the sample values so that they will not overflow (or underflow) the integer size.

I can’t say that anything you implement in pure PHP will be very fast though.

One of us can explain in more detail what you need to do, but you need to be familiar with how audio is recorded digitally first (samples, sample rate, bit depth, linear quantization, etc.).

How do I open a sample and add them together?

I’m guessing this information could be extracted into an array. I’ve taken a look at the wavedit class – I looked at it earlier today as well – I just can’t seem to get the information I want out of the file.

Well, each sample is the smallest possible packet of sound. Samples are stored as your regular binary integers (not ASCII integers), and they can be stored in 8 bits, or 16 bits, etc. To read a WAV file, after you have parsed the WAV header and figured out the bit depth (8, 16, 24, etc.), you proceed to read the data block and start consuming integers. You can use unpack() to convert a binary integer into a PHP nubmer. In a standard stereo WAV file, you will have a sample for each channel, so for each small moment of time, there will be two samples.

After you have extracted the samples, you can simply add them together. However, you can’t just add the samples from two different files together because they can overflow or underflow the size of the integer, so you need to do something about that.

And by the way, as for what each sample means, it represents the amplitude of the sound wave at that precise moment in time. In your PCM wave files, linear quantization is used to store the samples. This means that the non-discrete range of wave amplitudes is all fit into your 8-bit/16-bit/etc. integer in a linear fashion. 50% amplitude is highest value of the signed integer divided in half.

To help you understand, you can check out the wave synthesis code I wrote a few years ago:

That function just generates a regular sine wave. encodeSample() takes the place of pack(). There you can see linear quantization in use (see $volume) and how a sample is generated for each channel.

alright, I took all of your advice and decided to use a command line program. and you’re right - it’s a lot faster.
so I’m using sox. now I’m just going through it all.
I’ve installed it - is it possible to add a codec now? Or did I need to do that first?
e.g. I’d like to work with mp3 files now that I can

All digital audio processing calculations take place using uncompressed raw samples format whether the source file is mp3 or not (mp3 doesn’t store discrete sample values as such). If you start with an mp3, then perform the mix process (the mp3 has to be converted first to raw pcm samples) then output (reconverted) to mp3 you have an extra generation of lossy compression (and quality degradation) than if you start with wavs->mix->output to mp3.

the problem is, the default installation doesn’t have a codec for creating or uncompressing mp3s

Install the right libraries and their headers for MP3 (liblame), and then recompile sox with MP3 support.

I’m new to shell and putty. how do I recompile? I’ve installed lame - but how do I recompile something? Do I just redo the configure, make and make install?

If you don’t want to recompile, just pipe the output of sox (as wav) directly into ffmpeg which will do the wav to mp3 conversion.

Just re-do the ./configure, make, and make install.