您的位置:首页 > 编程语言 > Java开发

波形文件数据的表示

2017-01-23 00:00 369 查看
摘要: JavaFX

从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文件结构



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  wav JavaFX 声音 表示
相关文章推荐