转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-extract-amplitude-array-from.html

Extract amplitude array from recorded/saved wav : From File , AudioInputStream , ByteArray of File or ByteArrayInputStream - working java source code example

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
/**
* saving and extracting amplitude data from wavefile byteArray
*
* @author Ganesh Tiwari
*/
public class WaveData {
private byte[] arrFile;
private byte[] audioBytes;
private int[] audioData;
private ByteArrayInputStream bis;
private AudioInputStream audioInputStream;
private AudioFormat format;
private double durationSec;
private double durationMSec;
public WaveData() {
}
public int[] extractAmplitudeFromFile(File wavFile) {
try {
// create file input stream
FileInputStream fis = new FileInputStream(wavFile);
// create bytearray from file
arrFile = new byte[(int) wavFile.length()];
fis.read(arrFile);
} catch (Exception e) {
System.out.println("SomeException : " + e.toString());
}
return extractAmplitudeFromFileByteArray(arrFile);
}
public int[] extractAmplitudeFromFileByteArray(byte[] arrFile) {
// System.out.println("File : "+wavFile+""+arrFile.length);
bis = new ByteArrayInputStream(arrFile);
return extractAmplitudeFromFileByteArrayInputStream(bis);
}
/**
* for extracting amplitude array the format we are using :16bit, 22khz, 1
* channel, littleEndian,
*
* @return PCM audioData
* @throws Exception
*/
public int[] extractAmplitudeFromFileByteArrayInputStream(ByteArrayInputStream bis) {
try {
audioInputStream = AudioSystem.getAudioInputStream(bis);
} catch (UnsupportedAudioFileException e) {
System.out.println("unsupported file type, during extract amplitude");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOException during extracting amplitude");
e.printStackTrace();
}
// float milliseconds = (long) ((audioInputStream.getFrameLength() *
// 1000) / audioInputStream.getFormat().getFrameRate());
// durationSec = milliseconds / 1000.0;
return extractAmplitudeDataFromAudioInputStream(audioInputStream);
}
public int[] extractAmplitudeDataFromAudioInputStream(AudioInputStream audioInputStream) {
format = audioInputStream.getFormat();
audioBytes = new byte[(int) (audioInputStream.getFrameLength() * format.getFrameSize())];
// calculate durations
durationMSec = (long) ((audioInputStream.getFrameLength() * 1000) / audioInputStream.getFormat().getFrameRate());
durationSec = durationMSec / 1000.0;
// System.out.println("The current signal has duration "+durationSec+" Sec");
try {
audioInputStream.read(audioBytes);
} catch (IOException e) {
System.out.println("IOException during reading audioBytes");
e.printStackTrace();
}
return extractAmplitudeDataFromAmplitudeByteArray(format, audioBytes);
}
public int[] extractAmplitudeDataFromAmplitudeByteArray(AudioFormat format, byte[] audioBytes) {
// convert
// TODO: calculate duration here
audioData = null;
if (format.getSampleSizeInBits() == 16) {
int nlengthInSamples = audioBytes.length / 2;
audioData = new int[nlengthInSamples];
if (format.isBigEndian()) {
for (int i = 0; i < nlengthInSamples; i++) {
/* First byte is MSB (high order) */
int MSB = audioBytes[2 * i];
/* Second byte is LSB (low order) */
int LSB = audioBytes[2 * i + 1];
audioData[i] = MSB << 8 | (255 & LSB);
}
} else {
for (int i = 0; i < nlengthInSamples; i++) {
/* First byte is LSB (low order) */
int LSB = audioBytes[2 * i];
/* Second byte is MSB (high order) */
int MSB = audioBytes[2 * i + 1];
audioData[i] = MSB << 8 | (255 & LSB);
}
}
} else if (format.getSampleSizeInBits() == 8) {
int nlengthInSamples = audioBytes.length;
audioData = new int[nlengthInSamples];
if (format.getEncoding().toString().startsWith("PCM_SIGN")) {
// PCM_SIGNED
for (int i = 0; i < audioBytes.length; i++) {
audioData[i] = audioBytes[i];
}
} else {
// PCM_UNSIGNED
for (int i = 0; i < audioBytes.length; i++) {
audioData[i] = audioBytes[i] - 128;
}
}
}// end of if..else
// System.out.println("PCM Returned===============" +
// audioData.length);
return audioData;
}
public byte[] getAudioBytes() {
return audioBytes;
}
public double getDurationSec() {
return durationSec;
}
public double getDurationMiliSec() {
return durationMSec;
}
public int[] getAudioData() {
return audioData;
}
public AudioFormat getFormat() {
return format;
}
}

留言:

Think I found a bug for 8 bit unsigned samples in the code above.

Java regards a byte-variable as a signed variable, so we can't just subtract 128 for all sample-values. For "negative" values we must instead add 128, I think.

E.g. the sampled unsigned value 10000000 (128 unsigned) should mean that we are in the middle of the value-range. It should actually mean 0, but java sees it as -128, and if we subtract 128 we'll get -256, which isn't what we want at all.

And the "highest" sample-value possible with 8 bits, 11111111, means -1 to java if it's in a byte-variable. We'd get the value -129 here with the old method, but we would expect 127.

For all "positive" values 00000000 - 01111111 it works fine to subtract 128 as before, so something like this would work better:

// PCM_UNSIGNED
for (int i = 0; i < audioBytes.length; i++)
{
if (audioBytes[i] >= 0)
_audioData[i] = audioBytes[i] - 128;
else
_audioData[i] = audioBytes[i] + 128;
}

(Or e.g. you could "shift" the byte-value into an int-variable before subtracting 128.)

Java extract amplitude array from recorded wave的更多相关文章

  1. Java Sound : audio inputstream from pcm amplitude array

    转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-sound-making-audio-input-stream.html In ...

  2. Java之数组array和集合list、set、map

    之前一直分不清楚java中的array,list.同时对set,map,list的用法彻底迷糊,直到看到了这篇文章,讲解的很清楚. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 ...

  3. Java – Check if Array contains a certain value?

    Java – Check if Array contains a certain value?1. String Arrays1.1 Check if a String Array contains ...

  4. java 编程基础 Class对象 反射 :数组操作java.lang.reflect.Array类

    java.lang.reflect包下还提供了Array类 java.lang.reflect包下还提供了Array类,Array对象可以代表所有的数组.程序可以通过使 Array 来动态地创建数组, ...

  5. Java Audio : Playing PCM amplitude Array

    转载自:http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-audio-playing-pcm-amplitude-array.html ...

  6. java中List Array相互转换

    List to Array List 提供了toArray的接口,所以可以直接调用,转为object型数组 List<String> list = new ArrayList<Str ...

  7. Java中对Array数组的常用操作

    目录: 声明数组: 初始化数组: 查看数组长度: 遍历数组: int数组转成string数组: 从array中创建arraylist: 数组中是否包含某一个值: 将数组转成set集合: 将数组转成li ...

  8. JAVA中数组Array与List互转

    List<String> list = new ArrayList<String>();String[] array = new String[10]; 1.数组转成Listl ...

  9. Java List 和 Array 转化

    List to Array List 提供了toArray的接口,所以可以直接调用转为object型数组 List<String> list = new ArrayList<Stri ...

随机推荐

  1. 倒水问题UVA 10603——隐式图&&Dijkstra

    题目 给你三个容量分别为 $a,b,c$ 的杯子,最初只有第3个杯子装满了水,其他两个杯子为空.最少需要到多少水才能让一个某个杯子中的水有 $d$ 升呢?如果无法做到恰好 $d$ 升,就让某个杯子里的 ...

  2. Linux secureCRT 介绍和安装和优化

    修改背景颜色

  3. Codeforces Round #604 (Div. 2) A. Beautiful String

    链接: https://codeforces.com/contest/1265/problem/A 题意: A string is called beautiful if no two consecu ...

  4. 既然 transform 不适用于某些内联元素,那咱们就把这些元素变成 inline-block 或 block 就行了。

    既然 transform 不适用于某些内联元素,那咱们就把这些元素变成 inline-block 或 block 就行了.

  5. identifier of an instance of com.xxx.model.system.xxxObject was altered from 1765 to 1766

    Caused by: org.hibernate.HibernateException: identifier of an instance of com.xxx.model.system.xxxOb ...

  6. PDB符号文件浏览工具介绍

    一.SymView SymView工具用来显示符号文件中包含的符号表和符号数据.目前支持微软的Visual C/C++和C#编译器产生的DBG格式的符号文件和PDB格式的符号文件. SymView提供 ...

  7. nginx+uwsgi+python3+pipenv+mysql+redis部署django程序

    1.下载项目 git clone https://github.com/wangyitao/MyBlogs.git 2.进入Myblogs目录 cd MyBlogs 3.创建虚拟环境并且安装依赖 pi ...

  8. Linux 系统安装下安装 mysql5.7(glibc版)

    转自:https://www.cnblogs.com/mujingyu/p/7689116.html 前言:经过一天半的折腾,终于把 mysql 5.7.17 版本安装上了 centos 7 系统上, ...

  9. Java ArrayList几种遍历方法

    import java.util.ArrayList; import java.util.Iterator; public class StringSampleDemo { public static ...

  10. 在应用中显示的图片很多情况不满足业务需求,我们需要动态根据图片的宽高进行缩放或加载中显示的缺省图片,这是我没就需要监听图片加载完成回调,来看看微信小程序怎么实现图片加载完成回调。

    <swiper-item> <image src="{{item.image}}" class="slide-image" mode=&quo ...