Node.js 从缓冲区节点分离4个通道

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

我正在尝试分离从4麦克风阵列应答器接收到的缓冲区中的4个通道。我使用的是nodejs,目前使用的是spawn命令,如:

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位数组
没有合并2
8bit
元素以创建
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++;
        }
    }
}