Складывал wav файлы на PHP. Просто брал точки-значения амплитуды и складывал их. После сложения лимитировал до max/min значения. На слух в итоге всё выходило нормально, хотя в теории лимитирование при некоторых условиях должно резать слух, как мне кажется. Распаковывал и запаковывал сами сырые данные при помощи функций:
<?php
// ****************************************************
function readSample($handler,$bitsPerSample){
$sample=0;
for($b=0;$b<$bitsPerSample;$b+=8){
$sample|=ord(fread($handler,1))<<$b;
}
if($sample>0x7fff) $sample-=0x10000;
return $sample;
}
// ****************************************************
function writeSample($handler,$sample,$bitsPerSample){
$data='';
for($b=0;$b<$bitsPerSample;$b+=8){
$data.=chr($sample>>$b&0xff);
}
return fwrite($handler,$data);
}
// ****************************************************
?>
Возможно не оптимально, делал временно костыльно для наглядности и экспериментов. Функция возвращает число - значение амплитуды у очередной точки (семпла). Чтение заголовков сделано ещё более костыльно, поэтому не привожу его тут. Потому что мне нужно работать только с файлами 44100 гц 16 бит и я заведомо знаю, что никаких левых заголовков и комментариев в контейнере нет. При наложении двух семплов делал так:
<?php
$sample = $sample1 + $sample2;
if($sample < -32768) $sample = -32768; // лимитирование до минимума при 16 бит
if($sample > 32767) $sample = 32767; // лимитирование до максимума при 16 бит
?>
Кто знает способ правильнее и оптимальнее, высказывайтесь.