构建具有多个频率的wav文件



我们想要构建一个wav文件,其中包含多个频率,每个频率指定持续时间。

我将试着解释用例

假设我们需要在前5秒内建立一个频率范围从150MHz到200MHz的wav文件(从频率150MHz, 150.1MHz, 150.2MHz等到200MHz的整个波文件应该在5秒内结束)接下来的10秒应该是从200MHz到300MHz接下来的15秒应该从300MHz到400MHz一旦所有3个wav文件生成,我们需要将这3个文件合并/连接成一个30秒(5+10+15)的wav文件

谁能告诉我们如何才能做到这一点?

My Code:

//https://www.npmjs.com/package/tonegenerator
var tone = require('tonegenerator');
var header = require('waveheader');
var fs = require('fs');
var file = fs.createWriteStream('16bit_400_600.wav')
var t =[];
var first = tone({ freq: 4000000, lengthInSecs: 0.01, volume: tone.MAX_16,  rate: 44100000,  shape: 'sine' })
for(var i = 4000000.1; i <6000000.1; i+=0.1) {

var j = tone({ freq: i.toFixed(1), lengthInSecs: 0.01, volume: tone.MAX_16,  rate: 44100000,  shape: 'sine' })
//var j = tone({ freq: 428, lengthInSecs: 5, volume: tone.MAX_16,  rate: 44100,  shape: 'sine' })
// res = res.concat(j);
//first.concat(j);

t.push(j)
//console.info(i.toFixed(1));
}
res = first.concat(...t);

file.write(header(res.length * 2, {
bitDepth: 16
}))

var data = Int16Array.from(res)

var size = data.length * 2 // 2 bytes per sample
if (Buffer.allocUnsafe) { 
buffer = Buffer.allocUnsafe(size)
} else {
buffer = new Buffer(size)
}

data.forEach(function (value, index) {
buffer.writeInt16LE(value, index * 2)
})

file.write(buffer)
file.end()

问题是发送给tone函数的速率值,在tonegenerator index.js文件中,我们可以看到

var cycle = Math.floor(rate/freq);
var samplesLeft = lengthInSecs * rate;
var cycles = samplesLeft/cycle;

由于与频率相比,速率较低,因此当调用Math.floor()函数时,周期变为零。周期无法计算,因此程序挂起。

根据频率调整速率,使周期变量不为零或某个正值。

编辑

我不确定音调逻辑,但这就是我如何清理你的代码。

const tone = require('tonegenerator');
const header = require('waveheader');
const {createWriteStream} = require('fs');
let samples = [];
const makeChannel = (freq, lengthInSecs) => {
let channel = tone({ freq: freq, lengthInSecs: lengthInSecs, volume: tone.MAX_16, rate: 44100,  shape: 'sine' });
for (var i = 0; i < channel.length; i++) {
samples.push(channel[i])
}
};
let start = 150;
let end = 200;
const increment = 0.1;
for (let index = parseFloat(start); index <= parseFloat(end); index = parseFloat((index + increment).toFixed(1))) {
makeChannel(index, 0.01);
}
start = 200;
end = 300;
for (let index = parseFloat(start); index <= parseFloat(end); index = parseFloat((index + increment).toFixed(1))) {
makeChannel(index, 0.01);
}
start = 300;
end = 400;
for (let index = parseFloat(start); index <= parseFloat(end); index = parseFloat((index + increment).toFixed(1))) {
makeChannel(index, 0.015);
}
let file = createWriteStream('16bit-stereo_01.wav');
file.write(header(samples.length * 2, {
channels: 2,
bitDepth: 16
}));
const data = Int16Array.from(samples);
const size = data.length * 2;
const buffer = new Buffer.alloc(size);
data.forEach((value, index) => {
buffer.writeInt16LE(value, index * 2)
});
file.write(buffer);
file.end();

最新更新