zoukankan      html  css  js  c++  java
  • 摇滚吧HTML5!Jsonic超声波前端交互!

      前些年吹过一阵canvas制作html5游戏的东风,相信不少同学重温了一把高中物理课本上的牛顿定律。时光如梭,你是否还记得牛顿定律后面一章的各种机械波的物理定律?环视四周,光纤、wifi、蓝牙、广播都有波的身影,可以说机械波桥接了信息时代。Jsonic作为前端的音频交互框架,也有利用声波进行数据传输的接口,在介绍API之前,先分享一些web audio原生编码的干货。

      读了这系列前两篇博文摇滚吧HTML5!有声前端交互!(一)摇滚吧HTML5!有声前端交互!(Hello, Jsonic!)的同学,应该已经能够使用web audio产生一个特定频率的声波了。所谓的超声波,就是频率超过20000hz的声波,正常成人人耳能接收的声波范围是20-20000hz。20hz以下的次声波因为频率和人体一些器官相近,可能对人体造成损伤,所以不建议使用。这么一看,发出超声波就很简单了,代码如下,使用oscillaor节点。

    var context = new webkitAudioContext(),
        osc  = context.createOscillator();
    osc.frequency.value = 20000;
    osc.connect(context.destination);
    osc.start(0);

      这里有一点值得注意,oscillator节点的start方法只能调用一次。一旦调用了oscillator的stop方法,想要再发出这个频率的声音,就只能再创建一个新的对象了。在web audio中,我们还可以使用gain节点配合oscillator的方法,定期发出指定的声波。你可以把gain节点理解为一个信号强度调节器,通过设置gain.gain.value的值,可以控制信号的强弱。这个值取值范围是0~1。玩过音箱,效果器这些东西的同学应该就比较好理解了,其实web audio可以串联各种效果的节点。(下图仅供参考)

       

      回到代码的世界:

    var context = new webkitAudioContext(),
        gain = _ctx.createGain(),
        osc  = context.createOscillator();
    osc.frequency.value =20000; 
    gain.gain.value=0;
    osc.connect(gain); 
    gain.connect(context .destination); 
    osc.start(0);
    gain.gain.setValueAtTime(1,1);
    gain.gain.setValueAtTime(0,2);

      通过以上代码,可以在1-2秒这个时间区间内发出一个20000hz的超声波信号。这里调用setValueAtTime方法改变gain节点的值,波形变化过程如下图所示。gain节点有各种不同的方法,这些方法使信号强度到达预设值有不同的变化过程,读者可自行查阅web audio的API。

      通过gain节点控制信号和直接使用oscillator的start和stop方法控制信号各有利弊,具体使用大家可自行考虑。有了信号源,接下来就是接收的问题了。很多文章都介绍过html5的音频可视化,其核心就是通过analyser节点获取数据。这里简单罗列下analyser节点获取数据的几种方法。

    //通过浮点数组获取时域数据
    var data = new Float32Array(analyser.fftSize);
    analyser.getFloatTimeDomainData(data);
    
    //通过浮点数组获取频域数据
    var data = new Float32Array(analyser.fftSize);
    analyser.getFloatFrequencyData(data);
    
    //通过 Uint8数组获取时域数据
    var data = new Uint8Array(analyser.fftSize);
    analyser.getByteTimeDomainData(data);
    
    //通过 Uint8数组获取频域数据
    var data = new Uint8Array(analyser.fftSize);
    analyser.getByteFrequencyData(data);

      时域信号和频域信号可以通过傅里叶变化互相转换,Jsonic选择的是unit8数组获取频域信号,以下是获取频域数据的代码。

    var ctx = new webkitAudioContext();
    navigator.webkitGetUserMedia({
        audio:{optional:[{echoCancellation:false}]}
    },function(stream){
        var analyser = ctx.createAnalyser(),
            _input = ctx.createMediaStreamSource(stream),
            data = new Float32Array(analyser.fftSize);
        _input.connect(analyser);
        analyser.getFloatFrequencyData(data);
    },function(e){});

      这里的data数组获取的是所有频率的数据,那么怎么找到对应的频率数据呢?又要上物理课了。。。。。。这里要用到 奈奎斯特定理,不懂的同学可以直接看公式B=2W。通过audioContext节点sampleRate属性,我们可以获取在当前web audio上下文的采样率(一般是192000),那么通过奈奎斯特定理,这个采样率/2就是我们能采集到的信号频率的范围了。上面我们采集到的data数组长度默认是1024。以192000的采样率为例,data数组就是把0-96000hz的声波数据均分成1024个频率存储。到这里我们就能获取到频率数据了。虽然采样范围很广,但是不同设备通过oscillator节点能产生的声波的频率极限不同,我之前用iphone5测试的时候在22500hz左右。

    下面简单介绍下怎么用Jsonic收发超声波数据,更多信息可以自行捣鼓jsonic.net

      在jsonic之前的版本中,使用的是峰值分析法解码数据。最近发布了新的版本,使用的是波形分析法,使用了新的Band对象。无论接收还是发送端,在Jsonic中都要创建一个band实例。

    var band = new Jsonic.Band();
    band.initDefaultChannel();

    接收端 demo (点击start按钮后,需要授权浏览器使用麦克风)

    navigator.webkitGetUserMedia({
        audio:{optional:[{echoCancellation:false}]}
        },function(stream){
            _input = band.AudioContext.createMediaStreamSource(stream);
            band.listenSource(_input);
            band.scanEnvironment();
    },function(e){});

    发射端 demo (功放,发射输入框中的文字)

    band.send('Hello Jsonic',function(){
        //call back
    });

    最后附上github地址 https://github.com/ArthusLiang/jsonic 走过路过,给个star :),同时也期待前端大神加盟。

    转发请注明出处http://www.cnblogs.com/Arthus/p/4281442.html

  • 相关阅读:
    2016huasacm暑假集训训练四 递推_A
    2016huasacm暑假集训训练三 G
    2016huasacm暑假集训训练三 F
    今年暑假不AC
    Who's in the Middle
    The Suspects
    食物链
    抓牛问题
    士兵队列训练问题
    H
  • 原文地址:https://www.cnblogs.com/Arthus/p/4281442.html
Copyright © 2011-2022 走看看