Node.js 从缓冲区节点分离4个通道
我正在尝试分离从4麦克风阵列应答器接收到的缓冲区中的4个通道。我使用的是nodejs,目前使用的是spawn命令,如:Node.js 从缓冲区节点分离4个通道,node.js,audio,buffer,channels,Node.js,Audio,Buffer,Channels,我正在尝试分离从4麦克风阵列应答器接收到的缓冲区中的4个通道。我使用的是nodejs,目前使用的是spawn命令,如: spawn('arecord-r16000-fS16_LE-traw-c4-Dac108') 然后将输出传输到一个转换器中,我将缓冲区分成4个通道,并将它们保存到单独的文件中以检查结果 const stream = require("stream"); const fs = require('fs'); class ChannelTransformer extends stre
spawn('arecord-r16000-fS16_LE-traw-c4-Dac108')
然后将输出传输到一个转换器中,我将缓冲区分成4个通道,并将它们保存到单独的文件中以检查结果
const stream = require("stream");
const fs = require('fs');
class ChannelTransformer extends stream.Transform {
constructor(options) {
var write_1 = fs.createWriteStream('ch1', {encoding: 'binary'});
var write_2 = fs.createWriteStream('ch2', {encoding: 'binary'});
var write_3 = fs.createWriteStream('ch3', {encoding: 'binary'});
var write_4 = fs.createWriteStream('ch4', {encoding: 'binary'});
options.readableObjectMode = true;
options.writableObjectMode = true;
options.highWaterMark = 20000;
options.transform = (chunk, encoding, callback) => {
let channels = [[],[],[],[]];
for(let i=0; i<source.length;i++ ){
channels[i%4].push(chunk[i])
}
write_1.write(new Uint8Array(channels[0]));
write_2.write(new Uint8Array(channels[1]));
write_3.write(new Uint8Array(channels[2]));
write_4.write(new Uint8Array(channels[3]));
callback();
};
super(options);
}
}
我也不明白为什么,如果我遵循的模式不正确,两个通道成功分离。
我还试着将这部分内容转换为其他内容,如:
let source = new Int8Array(chunk);
然后在循环的中:
channels[i%4].push(source[i])
使用不同的类型,如Float32Array
,Uint8Array
,Uint16Array
,Int16Array
但结果是一样的。
我已经使用以下命令测试了4mic是否正常工作:
arecord -r16000 -fS16_LE -traw -c4 -Dac108 -I ch1 ch2 ch3 ch4
按预期生成包含每个通道的4个文件
在每次测试中,我在说话时每隔几秒钟用mi手指挡住麦克风,这样我就可以分辨出每个通道之间的差异
有人能帮我吗?还是有一些提示?
谢谢 好的,我知道问题出在哪里了。
基本上我是用bitWidth=16
录制的,节点中的Buffer
对象是Uint8Array
的一个实例,因此我遵循的模式确实是正确的,但由于8bit数组,我不得不为每个通道分配2个元素。原因8位阵列的格式为:
[[ch1],[ch1],[ch2],[ch2],[ch3],[ch3],[ch4],[ch4],...]
此外,强制转换数组也没有用,因为生成的16位数组
没有合并28bit
元素以创建16位
元素,而是每个8bit
元素创建16位
元素的最后一个8bit
,其中第一个8bit是0
,如下所示:
8bitArray=[[11111111],[11111111],[2222222],[22222222],...]
16bitArray Casted= [[0000000011111111],[0000000011111111],[0000000022222222],...]
因此,我创建了一种方法,该方法将8bitArray
合并到正确的数组中,以便根据您正在录制的位宽度
正确处理:
var bitMultipler = bitWidth/8; //so i can handle any bitWidth with the same code
let channelsMap = new Map<number, Array<any>>();
for (let channel: number = 0; channel < totalChannels; channel++) {
channelsMap.set(channel, new Array())
}
/**
For each channel i push as many element as needed based on the bitMultipler
*/
let i = 0
while (i < chunk.length) {
for (let channel = 0; channel < totalChannels; channel++) {
for (let indexMultipler = 0; indexMultipler < bitMultipler; indexMultipler++) {
channelsMap.get(channel).push(chunk[i]);
i++;
}
}
}
var bitMultipler=bitWidth/8//因此,我可以用相同的代码处理任何位宽度
让channelsMap=newmap();
对于(让通道:编号=0;通道<总通道;通道++){
channelsMap.set(通道,新数组())
}
/**
对于每个通道,我根据位乘法器的需要推送尽可能多的元素
*/
设i=0
while(i
var bitMultipler = bitWidth/8; //so i can handle any bitWidth with the same code
let channelsMap = new Map<number, Array<any>>();
for (let channel: number = 0; channel < totalChannels; channel++) {
channelsMap.set(channel, new Array())
}
/**
For each channel i push as many element as needed based on the bitMultipler
*/
let i = 0
while (i < chunk.length) {
for (let channel = 0; channel < totalChannels; channel++) {
for (let indexMultipler = 0; indexMultipler < bitMultipler; indexMultipler++) {
channelsMap.get(channel).push(chunk[i]);
i++;
}
}
}