文档章节

波形文件数据的表示

如比如比
 如比如比
发布于 2017/01/23 21:00
字数 926
阅读 260
收藏 0

从wav文件读取数据并用波的形式表示。

 

对于模拟信号不能直接数字化,根据采样定律通过模拟-数字转换才行。

采样定律

对于频率为fi的输入模拟信号,模数转换时的采样率为fs,要保证模数转换后的数字信号能够完全恢复到输入前的模拟信号,则必须满足:

fs≥2fimax

式中  fs为采样频率;fimax为模拟信号的最高频分量的频率。上式称为采样定律(或称奈魁斯特定律)。

 

采样后,接下来是量化。量化指将信号的连续取值(或者大量可能的离散取值)近似为有限多个(或较少的)离散值的过程。量化主要应用于从连续信号到数字信号的转换中。连续信号经过采样成为离散信号,离散信号经过量化即成为数字信号。注意离散信号并不需要经过量化的过程。例如CD音频信号就是按照44110Hz的频率采样,按16位元量化为有着65536(= 2^16)个可能取值的数字信号。

量化就是将模拟声音的波形转换为数字,表示采样值的二进制位数决定了量化的精度。量化的过程是先将整个幅度划分成有限个小幅度(量化阶距)的集合,把落入某个阶距内的样值归为一类,并赋予相同的量化值。

 

编码

 对量化结果进行大端字节序、小端字节序、混合序编码。

 

代码

以无损的wav(PCM) 为例。

 

package javay.test;



import java.io.File;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;



import javax.sound.sampled.AudioFormat;

import javax.sound.sampled.AudioInputStream;

import javax.sound.sampled.AudioSystem;

import javax.sound.sampled.UnsupportedAudioFileException;



import javafx.application.Application;

import javafx.scene.Node;

import javafx.scene.Scene;

import javafx.scene.chart.LineChart;

import javafx.scene.chart.NumberAxis;

import javafx.scene.chart.XYChart;

import javafx.scene.chart.XYChart.Series;

import javafx.scene.layout.HBox;

import javafx.stage.Stage;



/**

 * 波形文件数据的表示

 * 只表示声道1的信息

 */

public class TestWaveDraw extends Application {

    // 常量

    private final String fileName = "music/dog01.wav"; // 要表示的声音文件

    private final double sec = 0.15; // 要表示的时长(s)



    // 获取声音信息用的变量

    private AudioFormat format = null;

    private int[] values = null;



    public static void main(String[] args) {

        launch(args);

    }



    @Override

    public void start(Stage primaryStage) throws Exception {

        // 字色的设置

        System.setProperty("prism.lcdtext" , "false" );



        // 场景图

        HBox root = new HBox();



        // 图

        init(); // 读取声音文件的信息到values

        root.getChildren().add(createLineChart()); // 折线



        // 现场

        Scene scene = new Scene(root, 900, 300);



        // 窗口

        primaryStage.setScene(scene);

        primaryStage.show();

    }



    /**

     * 读取声音文件的信息到values

     * @throws IOException

     * @throws UnsupportedAudioFileException

     */

    public void init() throws Exception {

        // 获取AudioInputStream

        File file = new File(fileName);

        AudioInputStream is = AudioSystem.getAudioInputStream(file);



        // 获取Format信息

        format = is.getFormat();

        System.out.println(format.toString());

        System.out.println("采样率:" + format.getSampleRate());

        System.out.println("帧大小:" + format.getFrameSize());

        System.out.println("样本大小:" + format.getSampleSizeInBits());



        // 计算获取的样本数

        // 指定时间的样本数

        int mount = (int) (format.getSampleRate() * sec);



        // 读取声音数据

        values  = new int[mount];

        for(int i = 0; i < mount; i ++) {

            // 1帧的大小

            int size = format.getFrameSize();

            byte[] data = new byte[size];

            int readedSize = is.read(data);



            // 读取失败时

            if( readedSize == -1 ){

                break;

            }



            // SampleSizeInBits

            switch( format.getSampleSizeInBits() ) {

                case 8:

                    values[i] = (int) data[0];

                    break;

                case 16:

                    values[i] = (int) ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getShort();

                    break;

                default:

                    break;

            }

        }



        // 关闭AudioInputStream

        is.close();

    }



    /**

     * 用折线图表示

     * @return Node

     */

    @SuppressWarnings("unchecked")

    public Node createLineChart() {

        // 折线图

        NumberAxis xAxis = new NumberAxis();

        NumberAxis yAxis = new NumberAxis();

        LineChart<Number, Number> chart = new LineChart<Number, Number>(xAxis, yAxis);

        chart.setMinWidth(900);



        //生成数据

        Series<Number, Number> series1 = new Series<Number, Number>();

        series1.setName("声道1");

        for(int i = 0; i < values.length; i ++) {

            series1.getData().add(new XYChart.Data<Number, Number>(i, values[i]));

        }



        // 登录数据

        chart.getData().addAll(series1);

        // 设置标题

        String title = String.format("『%s』的波形数据(采样率:%.1fHz)", fileName, format.getSampleRate());

        chart.setTitle(title);



        // 调整外观

        chart.setCreateSymbols(false); // 去掉符号

        series1.getNode().lookup(".chart-series-line").setStyle("-fx-stroke-width: 1px;"); // 细线



        return chart;

    }

}

 

执行结果

PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian

采样率:44100.0

帧大小:4

样本大小:16

PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian

采样率:44100.0

帧大小:4

样本大小:16


wav文件结构

 

© 著作权归作者所有

共有 人打赏支持
上一篇: 朗读
下一篇: URL编码
如比如比
粉丝 125
博文 178
码字总数 286951
作品 0
日本
程序员
私信 提问
python数据建模分析 - 语音识别

语音识别: Getting Started!首先,我们要知道语音的产生过程 voice.png 状态:由肺产生向外的气流,完全放松时声带张开,就是平时的呼吸。如果声带一张一合(振动)形成周期性的脉冲气流。这个...

语落心生
2017/08/07
0
0
SerialTool

SerialTool是一个实用的串口调试工具,这款工具支持串口调试助手、波形显示和文件传输等功能。该工具软件使用GPL许可证发布。用户可以将波形文件保存为文本文件,然后使用Matlab等工具进行数...

过招铁是傻
12/07
0
0
【高速接口-RapidIO】6、RapidIO核仿真与包时序分析

  一、软件平台与硬件平台      软件平台:        操作系统:Windows 8.1 64-bit        开发套件:Vivado2015.4.2      硬件平台:        评估板:ZYNQ-7 ZC...

SEOwhywhy
昨天
0
0
Android系统音频开发遇到的几个问题,求指点

最近在Android系统上做一款APP,需要和硬件外设(基于HiJack)做数据交互,外设采集到业务数据并通过音频口将数据传给APP,同时App通过音频口输出符合硬件要求的波形来给外设供电。 外设向手...

andywster
2013/09/17
406
3
android获取和展示音乐的频谱

还有一些帖子: https://blog.csdn.net/Qzhongwenze/article/details/52851297 http://blog.sina.com.cn/s/blog_67d95f40010113ec.html https://blog.csdn.net/caryee89/article/details/693......

whoisliang
11/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

docker快速搭建几个常用的第三方服务

本次和大家分享的内容是使用docker快速搭建工作中常用的第三方的服务,对于有一些互联网背景的公司来说,以下几个服务都是很需要的:redis,rabbit,elasticsearch; 如果想学习Java工程化、...

编程SHA
28分钟前
3
0
我的Linux系统九阴真经

在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行业,共享经济等概念的公...

linuxprobe16
37分钟前
12
0
Dubbo标签解析详解

在Spring继承dubbo时,会使用dubbo自定义的标签来定义相关的属性,常见的标签有<dubbo:application/>,<dubbo:registry/>,<dubbo:service/>等。对于这些标签的解析,dubbo都是使用的统一的方...

爱宝贝丶
42分钟前
5
0
网站彩蛋

图形类彩蛋 知乎 https://www.zhihu.com/ 想来知乎工作?请发送邮件到 jobs@zhihu.com 天猫 https://www.tmall.com/ 喵~ 加入我们吧 http://tb.cn/iS8NBOy 超级课程表 http://www.super.cn/...

临江仙卜算子
49分钟前
10
0
ThreadLocal父子线程之间的数据传递问题

一、问题的提出 在系统开发过程中常使用ThreadLocal进行传递日志的RequestId,由此来获取整条请求链路。然而当线程中开启了其他的线程,此时ThreadLocal里面的数据将会出现无法获取/读取错乱...

nonnetta
58分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部