zhaomingwork
2023-11-14 8ceb2662f95d6e9185a00b7ccbff3ee596d46342
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
pcm编码器+编码引擎
https://github.com/xiangyuecn/Recorder
 
编码原理:本编码器输出的pcm格式数据其实就是Recorder中的buffers原始数据(经过了重新采样),16位时为LE小端模式(Little Endian),并未经过任何编码处理
 
编码的代码和wav.js区别不大,pcm加上一个44字节wav头即成wav文件;所以要播放pcm就很简单了,直接转成wav文件来播放,已提供转换函数 Recorder.pcm2wav
*/
(function(){
"use strict";
 
Recorder.prototype.enc_pcm={
    stable:true
    ,testmsg:"pcm为未封装的原始音频数据,pcm数据文件无法直接播放;支持位数8位、16位(填在比特率里面),采样率取值无限制"
};
Recorder.prototype.pcm=function(res,True,False){
        var This=this,set=This.set
            ,size=res.length
            ,bitRate=set.bitRate==8?8:16;
        
        var buffer=new ArrayBuffer(size*(bitRate/8));
        var data=new DataView(buffer);
        var offset=0;
        
        // 写入采样数据
        if(bitRate==8) {
            for(var i=0;i<size;i++,offset++) {
                //16转8据说是雷霄骅的 https://blog.csdn.net/sevennight1989/article/details/85376149 细节比blqw的按比例的算法清晰点,虽然都有明显杂音
                var val=(res[i]>>8)+128;
                data.setInt8(offset,val,true);
            };
        }else{
            for (var i=0;i<size;i++,offset+=2){
                data.setInt16(offset,res[i],true);
            };
        };
        
        
        True(new Blob([data.buffer],{type:"audio/pcm"}));
    };
 
 
 
 
 
/**pcm直接转码成wav,可以直接用来播放;需同时引入wav.js
data: {
        sampleRate:16000 pcm的采样率
        bitRate:16 pcm的位数 取值:8 或 16
        blob:blob对象
    }
    data如果直接提供的blob将默认使用16位16khz的配置,仅用于测试
True(wavBlob,duration)
False(msg)
**/
Recorder.pcm2wav=function(data,True,False){
    if(data.slice && data.type!=null){//Blob 测试用
        data={blob:data};
    };
    var sampleRate=data.sampleRate||16000,bitRate=data.bitRate||16;
    if(!data.sampleRate || !data.bitRate){
        console.warn("pcm2wav必须提供sampleRate和bitRate");
    };
    if(!Recorder.prototype.wav){
        False("pcm2wav必须先加载wav编码器wav.js");
        return;
    };
    
    var reader=new FileReader();
    reader.onloadend=function(){
        var pcm;
        if(bitRate==8){
            //8位转成16位
            var u8arr=new Uint8Array(reader.result);
            pcm=new Int16Array(u8arr.length);
            for(var j=0;j<u8arr.length;j++){
                pcm[j]=(u8arr[j]-128)<<8;
            };
        }else{
            pcm=new Int16Array(reader.result);
        };
        
        Recorder({
            type:"wav"
            ,sampleRate:sampleRate
            ,bitRate:bitRate
        }).mock(pcm,sampleRate).stop(function(wavBlob,duration){
            True(wavBlob,duration);
        },False);
    };
    reader.readAsArrayBuffer(data.blob);
};
 
 
 
})();