Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:从Int16转换为Float32_Javascript_Html5 Audio_Audiobuffer - Fatal编程技术网

Javascript:从Int16转换为Float32

Javascript:从Int16转换为Float32,javascript,html5-audio,audiobuffer,Javascript,Html5 Audio,Audiobuffer,我想把一个WAV文件放在一个音频缓冲区里,这样我就可以操纵它了。我以前从AudioBuffer创建过WAV文件,这需要将Float32Array转换为包含Int16值的DataView。我使用了我学到的这个方便的功能: function floatTo16BitPCM(output, offset, input){ for (var i = 0; i < input.length; i++, offset+=2){ var s = Math.max(-1, Math

我想把一个WAV文件放在一个音频缓冲区里,这样我就可以操纵它了。我以前从AudioBuffer创建过WAV文件,这需要将Float32Array转换为包含Int16值的DataView。我使用了我学到的这个方便的功能:

function floatTo16BitPCM(output, offset, input){
    for (var i = 0; i < input.length; i++, offset+=2){
        var s = Math.max(-1, Math.min(1, input[i]));
        output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
    }
}
函数浮动到16bit PCM(输出、偏移、输入){
对于(变量i=0;i

好的,我现在需要做的就是反转这个(WAV文件是从服务器加载的,所以我不再有原始数据)。我不知道该函数中实际发生了什么,也不知道数据是如何转换的。

数组输入的每个实际数据都被缩减为间隔[-1,1]

  • 如果x=-1,则Math.min(1,x)给出x,否则给出-1
然后将-1和1之间的实数转换为有符号16位整数

无论它是正的还是负的乘以32767或-32768,它都只保留整数部分。这相当于在二进制表示法中,小数点后仅保留16个有效位

16位整数一个接一个地存储在缓冲区中两个字节的little Endian中(根据将二推进为二的偏移量)


对于反向操作,只需在int16中放置两个连续字节。将其转换为实数,区分符号后面的两个格,并除以32768或32767。但是操作将在数据丢失的情况下完成。

阵列输入的每个实际数据都将减少到间隔[-1,1]

  • 如果x=-1,则Math.min(1,x)给出x,否则给出-1
然后将-1和1之间的实数转换为有符号16位整数

无论它是正的还是负的乘以32767或-32768,它都只保留整数部分。这相当于在二进制表示法中,小数点后仅保留16个有效位

16位整数一个接一个地存储在缓冲区中两个字节的little Endian中(根据将二推进为二的偏移量)


对于反向操作,只需在int16中放置两个连续字节。将其转换为实数,区分符号后面的两个格,并除以32768或32767。但是操作将在数据丢失的情况下完成。

下面是一些似乎有效的方法。我在一个响应类型为“arraybuffer”的ajax调用中加载数据。否则,响应将变成一个字符串,处理起来会很混乱。然后我转换成一个16位数组。然后我用WAV编码的方式将其转换为Float32数组。我还需要扔掉WAV的标题,以及结尾的一些元数据

// These are ready to be copied into an AudioBufferSourceNode's channel data.
var theWavDataInFloat32;

function floatTo16Bit(inputArray, startIndex){
    var output = new Uint16Array(inputArray.length-startIndex);
    for (var i = 0; i < inputArray.length; i++){
        var s = Math.max(-1, Math.min(1, inputArray[i]));
        output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
    }
    return output;
}

// This is passed in an unsigned 16-bit integer array. It is converted to a 32-bit float array.
// The first startIndex items are skipped, and only 'length' number of items is converted.
function int16ToFloat32(inputArray, startIndex, length) {
    var output = new Float32Array(inputArray.length-startIndex);
    for (var i = startIndex; i < length; i++) {
        var int = inputArray[i];
        // If the high bit is on, then it is a negative number, and actually counts backwards.
        var float = (int >= 0x8000) ? -(0x10000 - int) / 0x8000 : int / 0x7FFF;
        output[i] = float;
    }
    return output;
}

// TEST
var data = [ 65424, 18, 0, 32700, 33000, 1000, 50000 ];
var testDataInt = new Uint16Array(data);
var testDataFloat = int16ToFloat32(testDataInt, 0, data.length);
var testDataInt2 = floatTo16Bit(testDataFloat, 0);
// At this point testDataInt2 should be pretty close to the original data array (there is a little rounding.)

var xhr = new XMLHttpRequest();
xhr.open('GET', '/my-sound.wav', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
    if (this.status === 200) {
        // This retrieves the entire wav file. We're only interested in the data portion.
        // At the beginning is 44 bytes (22 words) of header, and at the end is some metadata about the file.
        // The actual data length is held in bytes 40 - 44.
        var data = new Uint16Array(this.response);
        var length = (data[20] + data[21] * 0x10000) / 2; // The length is in bytes, but the array is 16 bits, so divide by 2.
        theWavDataInFloat32 = int16ToFloat32(data, 22, length);
    }
};

xhr.send();
//这些已准备好复制到AudioBufferSourceNode的频道数据中。
var theWavDataInFloat32;
函数floatTo16位(inputArray,startIndex){
var输出=新的UINT16阵列(inputArray.length startIndex);
for(变量i=0;i=0x8000)?-(0x10000-int)/0x8000:int/0x7FFF;
输出[i]=浮点数;
}
返回输出;
}
//试验
var数据=[65424,18,032700,33000,1000,50000];
var testDataInt=新的UINT16阵列(数据);
var testDataFloat=int16ToFloat32(testDataInt,0,data.length);
var testDataInt2=floatTo16Bit(testDataFloat,0);
//此时,testDataInt2应该非常接近原始数据数组(有一点舍入)
var xhr=new XMLHttpRequest();
xhr.open('GET','/my-sound.wav',true);
xhr.responseType='arraybuffer';
xhr.onload=函数(e){
如果(this.status==200){
//这将检索整个wav文件。我们只对数据部分感兴趣。
//开头是44字节(22个字)的头,结尾是一些关于文件的元数据。
//实际数据长度以字节40-44为单位。
var数据=新的UINT16阵列(此.response);
var length=(data[20]+data[21]*0x10000)/2;//长度以字节为单位,但数组为16位,因此除以2。
wavdatainfloat32=int16ToFloat32(数据,22,长度);
}
};
xhr.send();

以下是似乎有效的方法。我在一个响应类型为“arraybuffer”的ajax调用中加载数据。否则,响应将变成一个字符串,处理起来会很混乱。然后我转换成一个16位数组。然后我用WAV编码的方式将其转换为Float32数组。我还需要扔掉WAV的标题,以及结尾的一些元数据

// These are ready to be copied into an AudioBufferSourceNode's channel data.
var theWavDataInFloat32;

function floatTo16Bit(inputArray, startIndex){
    var output = new Uint16Array(inputArray.length-startIndex);
    for (var i = 0; i < inputArray.length; i++){
        var s = Math.max(-1, Math.min(1, inputArray[i]));
        output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
    }
    return output;
}

// This is passed in an unsigned 16-bit integer array. It is converted to a 32-bit float array.
// The first startIndex items are skipped, and only 'length' number of items is converted.
function int16ToFloat32(inputArray, startIndex, length) {
    var output = new Float32Array(inputArray.length-startIndex);
    for (var i = startIndex; i < length; i++) {
        var int = inputArray[i];
        // If the high bit is on, then it is a negative number, and actually counts backwards.
        var float = (int >= 0x8000) ? -(0x10000 - int) / 0x8000 : int / 0x7FFF;
        output[i] = float;
    }
    return output;
}

// TEST
var data = [ 65424, 18, 0, 32700, 33000, 1000, 50000 ];
var testDataInt = new Uint16Array(data);
var testDataFloat = int16ToFloat32(testDataInt, 0, data.length);
var testDataInt2 = floatTo16Bit(testDataFloat, 0);
// At this point testDataInt2 should be pretty close to the original data array (there is a little rounding.)

var xhr = new XMLHttpRequest();
xhr.open('GET', '/my-sound.wav', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
    if (this.status === 200) {
        // This retrieves the entire wav file. We're only interested in the data portion.
        // At the beginning is 44 bytes (22 words) of header, and at the end is some metadata about the file.
        // The actual data length is held in bytes 40 - 44.
        var data = new Uint16Array(this.response);
        var length = (data[20] + data[21] * 0x10000) / 2; // The length is in bytes, but the array is 16 bits, so divide by 2.
        theWavDataInFloat32 = int16ToFloat32(data, 22, length);
    }
};

xhr.send();
//这些已准备好复制到AudioBufferSourceNode的频道数据中。
var theWavDataInFloat32;
函数floatTo16位(inputArray,startIndex){
var输出=新的UINT16阵列(inputArray.length startIndex);
for(变量i=0;i