HTML5 WebAudioAPI(三)--绘制频谱图

HTML

<style>
    #canvas {
        background: black;
    }
</style>
<div class="container">
    <button class="btn btn-primary" id="playBtn">
        <i class="glyphicon glyphicon-pause"></i>
    </button>
</div>
<canvas id="canvas" width="800" height="300"></canvas>

实例1,绘制频谱图:

var url=‘../content/audio/海阔天空.mp3‘;
if (!window.AudioContext) {
    alert(‘您的浏览器不支持AudioContext‘);
} else {
    //创建上下文
    var ctx = new AudioContext();
    var source = null;
    //使用Ajax获取音频文件

    var request = new XMLHttpRequest();
    request.open(‘GET‘, url, true);
    request.responseType = ‘arraybuffer‘;//配置数据的返回类型
    //加载完成
    request.onload = function () {
        var arraybuffer = request.response;
        ctx.decodeAudioData(arraybuffer, function (buffer) {
            //创建分析器
            var analyser = ctx.createAnalyser();
            source = ctx.createBufferSource();
            //将source与分析器链接
            source.connect(analyser);
            //将分析器与destination链接,这样才能形成到达扬声器的通路
            analyser.connect(ctx.destination);
            //将解码后的buffer数据复制给source
            source.buffer = buffer;
            //播放
            source.start(0);

            //开始绘制频谱图
            function drawSpectrum() {
                var canvas = document.getElementById(‘canvas‘),
                    cwidth = canvas.width,
                    cheight = canvas.height - 2,
                    meterWidth = 10,//能量条的宽度
                    gap = 2,//能量条的间距
                    meterNum = 800 / (10 + 2),//计算当前画布上能画多少条
                    ctx = canvas.getContext(‘2d‘);
                var capHeight = 2;//
                var array = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(array);
                console.info(array.length);
                var step = Math.round(array.length / meterNum);//计算从analyser中的采样步长

                //清理画布
                ctx.clearRect(0, 0, cwidth, cheight);
                //定义一个渐变样式用于画图
                var gradient = ctx.createLinearGradient(0, 0, 0, 300);
                gradient.addColorStop(1, ‘#0f0‘);
                gradient.addColorStop(0.5, ‘#ff0‘);
                gradient.addColorStop(0, ‘#f00‘);
                ctx.fillStyle = gradient;
                //对信源数组进行抽样遍历,画出每个频谱条
                for (var i = 0; i < meterNum; i++) {
                    var value = array[i * step];
                    ctx.fillRect(i * 12/*频谱条的宽度+条间距*/, cheight - value + capHeight,
                        meterWidth, cheight);
                }
                requestAnimationFrame(drawSpectrum)
            }
            requestAnimationFrame(drawSpectrum)
        }, function (e) {
            console.info(‘处理出错‘);
        });
    }
    request.send();

    //绑定播放按钮
    $(‘#playBtn‘).click(function () {
        var icon = $(this).find(‘i‘);;
        icon.toggleClass(‘glyphicon-play‘).toggleClass(‘glyphicon-pause‘);
        //停止播放
        source.stop();
    });
}

实例2,绘制缓慢下落的帽头

var url=‘../content/audio/海阔天空.mp3‘;
if (!window.AudioContext) {
    alert(‘您的浏览器不支持AudioContext‘);
} else {
    //创建上下文
    var atx = new AudioContext();
    var source = null;
    //使用Ajax获取音频文件
    var request = new XMLHttpRequest();
    request.open(‘GET‘, url, true);
    request.responseType = ‘arraybuffer‘;//配置数据的返回类型
    //加载完成
    request.onload = function () {
        var arraybuffer = request.response;
        atx.decodeAudioData(arraybuffer, function (buffer) {
            //创建分析器
            var analyser = atx.createAnalyser();
            source = atx.createBufferSource();
            //将source与分析器链接
            source.connect(analyser);
            //将分析器与destination链接,这样才能形成到达扬声器的通路
            analyser.connect(atx.destination);
            //将解码后的buffer数据复制给source
            source.buffer = buffer;
            //播放
            source.start(0);

            //开始绘制频谱图
            var canvas = document.getElementById(‘canvas‘),
                cwidth = canvas.width,
                cheight = canvas.height - 2,
                meterWidth = 10,//能量条的宽度
                gap = 2,//能量条的间距
                meterNum = 800 / (10 + 2);//计算当前画布上能画多少条
            var ctx = canvas.getContext(‘2d‘);
            var capHeight = 2,//冒头的高度
                capStyle = ‘#fff‘,//冒头的颜色
                capYPositionArray = [];//将上一面各个冒头的位置保存到这个数组
            //定义一个渐变样式用于画图
            var gradient = ctx.createLinearGradient(0, 0, 0, 300);
            gradient.addColorStop(1, ‘#0f0‘);
            gradient.addColorStop(0.5, ‘#ff0‘);
            gradient.addColorStop(0, ‘#f00‘);
            //绘制频谱图
            function drawSpectrum() {
                var array = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(array);
                var step = Math.round(array.length / meterNum);//计算从analyser中的采样步长
                //清理画布
                ctx.clearRect(0, 0, cwidth, cheight);
                //对信源数组进行抽样遍历,画出每个频谱条
                for (var i = 0; i < meterNum; i++) {
                    var value = array[i * step]; //取样作为y轴的值
                    //绘制缓慢降落的冒头
                    if (capYPositionArray.length < Math.round(meterNum)) {
                        capYPositionArray.push(value);//初始化保存冒头位置的数组,将第一个画面位置保存
                    }
                    ctx.fillStyle = capStyle;
                    //1.开始绘制冒头
                    if (value < capYPositionArray[i]) {
                        //使用前一次数据
                        ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight);
                    } else {
                        //否则,直接使用当前数据并记录
                        ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight);
                        capYPositionArray[i] = value;
                    }
                    //2.开始绘制频谱条
                    ctx.fillStyle = gradient;
                    ctx.fillRect(i * 12/*频谱条的宽度+条间距*/, cheight - value + capHeight,
                        meterWidth, cheight);
                }
                requestAnimationFrame(drawSpectrum);
            }
            requestAnimationFrame(drawSpectrum);
        }, function (e) {
            console.info(‘处理出错‘);
        });

    }
    request.send();
    //绑定播放按钮
    $(‘#playBtn‘).click(function () {
        var icon = $(this).find(‘i‘);;
        icon.toggleClass(‘glyphicon-play‘).toggleClass(‘glyphicon-pause‘);
        //停止播放
        source.stop();
    });
}

内容来源:http://www.cnblogs.com/Wayou/p/3543577.html

更多参考:

HTML5 WebAudioAPI简介(一)

HTML5 WebAudioAPI-实例(二)

时间: 2024-10-24 12:27:02

HTML5 WebAudioAPI(三)--绘制频谱图的相关文章

HTML5 WebAudioAPI(四)--绘制频谱图2

绘制分析器数组所有数据.本文内容,承接上文 1.800宽度绘制 var url='../content/audio/海阔天空.mp3'; if (!window.AudioContext) { alert('您的浏览器不支持AudioContext'); } else { //创建上下文 var atx = new AudioContext(); var source = null; //使用Ajax获取音频文件 var request = new XMLHttpRequest(); reque

HTML5 随音乐节奏变化的频谱图动画

这里将要介绍的HTML5 音频处理接口与Audio标签是不一样的.页面上的Audio标签只是HTML5更语义化的一个表现,而HTML5提供给JavaScript编程用的Audio API则让我们有能力在代码中直接操作原始的音频流数据,对其进行任意加工再造. 展示HTML5 Audio API 最典型直观的一个例子就是跟随音乐节奏变化的频谱图,也称之为可视化效果.本文便是以此为例子展示JavaScript中操作音频数据的. 文中代码仅供参考,实际代码以下载的源码为准. 了解Audio API   

用Html5制作的一款数学教学程序Function Graphics(绘制函数图的程序)

最近我不仅对游戏开发感兴趣,还对函数图感兴趣,特此我开发了这个程序.以下是一些介绍和下载演示地址,喜欢的朋友可以看看: 一,产品名片 产品名:Function Graphics 版本: 0.1 开发者:Yorhom Wang 首次发行时间:2013年 4月4日 分类:教学程序 功能:画出一,二,三次函数图象 开发语言:JavaScript&HTML5 二,怎么使用 下载地址(含有源码): http://files.cnblogs.com/ducle/function_graphs.rar 在线使

[HTML5 Canvas学习]绘制矩形

1.使用strokeRect和fillRect方法绘制矩形 a.strokeRect是绘制一个不填充的矩形 b.fillRect是绘制一个填充的矩形 代码: <script> var canvas = document.getElementById('canvas'), context = canvas.getContext('2d'); context.lineJoin = 'round'; context.lineWidth = 20; context.strokeRect(10, 10,

Morris.js和flot绘制折线图的比较

[文章摘要] 最近用开源的AdminLTE做框架感觉效果特别好,其针对图表库Morris.js和flot都提供了不错的支持,也都提供了这两者的例子.不过Morris.js是基于Raphael.js来的,也就是其使用SVG和VML来绘制图形,而flot则是使用Canvas进行绘制,在绘制效率和浏览器兼容性等方面会有出入,同时两者需要的数据格式也不相同.本文中对两者的使用和性能进行了比较. [文章索引] Morris.js的使用 flot的使用 性能比较 [一.Morris.js的使用] Morri

nagios二次开发之“依据分组绘制服务图”

背景:       在nagios3.2.0版本,曾将nagios.saltstack.Thinkphp进行整合.在整合的基础之上,进行了二次开发,新增分组出图.资产管理.服务器批量管理等功能.资产的增删改查借助的是Thinkphp框架:分组出图单独写分组页面,调用pnp的接口:服务器的批量管理,依靠的是saltstack的强大的API,如下图: 图1  按业务分组出图 图2  资产管理和服务器批量管理 上述系统已应用到线上环境.接下来我们要讲述的"依据分组绘制服务图"是在nagios

【python】pandas &amp; matplotlib 数据处理 绘制曲面图

Python matplotlib模块,是扩展的MATLAB的一个绘图工具库,它可以绘制各种图形 建议安装 Anaconda后使用 ,集成了很多第三库,基本满足大家的需求,下载地址,对应选择python 2.7 或是 3.5 的就可以了: https://www.continuum.io/downloads#windows 脚本默认执行方式:              1.获取当前文件夹下的1.log文件              2.将数据格式化为矩阵              3.以矩阵的列

图像的二维频谱图的理解 20170622

# 1 图像二维频谱长什么样子(左图是原图,右图是对应的频谱图) (图片来源:第一组是来自matlab自带的图片 "cameraman.tif":第二组是用 excel 画的,然后截图) # 2 怎么获得(matlab和C++调用) matlaba代码,保存为 spectrum2D.m function [Result] = spectrum2D(I) % I is a gray image % 'Input Image should be gray!' A = rgb2gray(I)

Excel应该这么玩——7、我是预言家:绘制趋势图

让我们先看一个场景:你是公司销售部的员工,你手里有公司最近几年的销售额相关的数据,经理希望你预测下个月的销售额.盯着一堆数据,你或许会想到画一张XY坐标图,然后将每个月份的销售额标定为一个坐标.但是下个月的趋势是上升还是下降,值是多少,估计你只能凭感觉在坐标图上打一个点. 读完本文,你就有了很严谨的预测未来趋势的能力,不只是凭感觉哦. 假设存在下面一系列数据,第一行是区间值(例如第几个月),第二行的随着区间变化的值(例如销售额). 选中数据,菜单:插入->图表->散点图->带平滑线和数据