首先,我是音频处理和合成方面的新手,如果我做出一些愚蠢的假设或对核心概念的误解,请纠正我。
我正在尝试使用SoX将数字数据数组转换为单个音频文件。到目前为止,我有两种“有效”的方法会产生一些非常可怕的结果,并且都具有严重的局限性。
我在64位WIN 8.1机器上通过PHP使用SoX。
方法1 输出单个音,然后进行串联
$toneLinks=array();
for($i=0;$i<count($sourceData);$i++){
$filename='tones\\'.$dataTitle.'_'.$i.'.au';
$soxCommand=$soxFolder.'sox -n '.$filename.' synth .5 sin '.($sourceData[$i]).' vol 0.5 ';
shell_exec($soxCommand);
$toneLinks[]=$filename;
}
$chunks=array_chunk($toneLinks,100);
$chunkFiles=array();
for($ch=0;$ch<count($chunks);$ch++){
$name='tones\\'.$dataTitle.'_chunk_'.$ch.'.au';
$soxCommand=$soxFolder.'sox ';
for($i=0;$i<count($chunks[$ch]);$i++){
$soxCommand.=' '.$chunks[$ch][$i];
}
$soxCommand.=' '.$name;
$result=shell_exec($soxCommand);
$chunkFiles[]=$name;
}
$soxCommand=$soxFolder.'sox ';
for($i=0;$i<count($chunkFiles);$i++){
$soxCommand.=' '.$chunkFiles[$i];
}
$soxCommand.=' '.$dataTitle.'.au';
shell_exec($soxCommand);
局限性:
方法2 在单个命令中生成“和弦”
$soxCommand=$soxFolder.'sox -n '.$dataTitle.'.au synth ';
for($i=1;$i<count($sourceData);$i++){
$soxCommand.='.25 sin '.($sourceData[$i]).' ';
}
$soxCommand.='delay ';
for($i=1;$i<count($sourceData);$i++){
$soxCommand.=($i*.2).' ';
}
$soxCommand.='remix - fade 0 '.(count($sourceData)*.2+.5).' .1 norm -1';
shell_exec($soxCommand);
局限性:
与最后一种方法类似的问题,但是级联较小
使用此方法的文件听起来很奇怪,因为
连接处有声音中断的组件。一个可以重叠文件,但是仍然不理想。
它还可能由于两个层次而引入了裁剪
音量为1的音调。我无法确定如何按照方法1
理想的答案将解决以下问题:
一块“音乐”
最佳答案
经过更多的实验,我确定了可以满足我的要求的方法。我敢肯定,可以利用管道来提高过程效率,但是这种方法在一分钟内就可以在所需大小(〜2,000)左右的数据集上产生所需的结果。
//Generate individual tones
$tones=array();
for($i=0;$i<count($sourceData)-1;$i++){
$name='tones\\'.$dataTitle.'_'.$i.'.au';
$soxCommand=$soxFolder.'sox -n '.$name.' synth 0.2 sin '.($sourceData[$i]).' fade q 0.05 0 ';
shell_exec($soxCommand);
$tones[]=$name;
}
//Break into manageable chunks to avoid exec character limit
$chunks=array_chunk($tones,100);
$chunkFiles=array();
for($ch=0;$ch<count($chunks);$ch++){
$name='tones\\'.$dataTitle.'_chunk_'.$ch.'.au';
$soxCommand=$soxFolder.'sox ';
for($i=0;$i<count($chunks[$ch]);$i++){
$soxCommand.=' '.$chunks[$ch][$i];
}
$soxCommand.=' '.$name.' splice 0.2';
shell_exec($soxCommand);
$chunkFiles[]=$name;
}
//Render chunks into final track
$soxCommand=$soxFolder.'sox ';
for($i=0;$i<count($chunkFiles);$i++){
$soxCommand.=' '.$chunkFiles[$i];
}
$soxCommand.=' '.$dataTitle.'.au splice 20';
shell_exec($soxCommand);
//Clean component files
for($i=0;$i<count($tones);$i++){
unlink($tones[$i]);
}
for($i=0;$i<count($chunkFiles);$i++){
unlink($chunkFiles[$i]);
}
SoX命令的歧义消除
生成音调:“sox -n [输出文件]合成器0.2 [频率]淡入q 0.05 0”
此命令会在音轨自然结束之前生成0.2秒的音调,并带有0.05秒的四分之一正弦渐弱和0.05秒的四分之一正弦渐弱。
组合音调/块:“sox [tone1] [tone2] [tone ...] [outfile]拼接0.2”
其中的秘诀在于接头,它将自动尝试消除由哑级联所引起的咔嗒声。最后的命令只是将音调infile替换为块infile,并将接合点从0.2sec增加到20sec。