转载自: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. 判断 List map set 是否为空

    //如果object为null,则设置为defaultValue ObjectUtils.defaultIfNull(object, defaultValue); //判断集合是否为null List ...

  2. vue引入js文件时报This dependency was not found:错误

    vue引入js文件时报This dependency was not found:错误 使用了很多方法,原来是这么小的问题,特此记录 解决办法 添加 ./

  3. IDEA设置提示生成序列化ID

    背景: 实现Serializable接口的类,没有提示生成序列化ID 解决问题: 1.FIle->Settings->Editor->inspections 2.点击java-> ...

  4. BZOJ 2159: Crash 的文明世界 第二类斯特林数+树形dp

    这个题非常巧妙啊~ #include <bits/stdc++.h> #define M 170 #define N 50003 #define mod 10007 #define LL ...

  5. bzoj 5299: [Cqoi2018]解锁屏幕 状压dp+二进制

    比较简单的状压 dp,令 $f[S][i]$ 表示已经经过的点集为 $S$,且最后一个访问的位置为 $i$ 的方案数. 然后随便转移一下就可以了,可以用 $lowbit$ 来优化一下枚举. code: ...

  6. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/mysql.sock' (2)

    这种情况一般是mysql被杀掉了. 要重新启动. ps -A | grep -i mysql kill 列出来的进程 service mysql start 我的问题就解决了    

  7. cf 1051F 树+图

    $des$给定一张 $n$ 个点 $m$ 条边的带权无向联通图,$q$ 次询问,每次询问 $u_i$ 到 $v_i$ 的最短路长度.$n,q <= 10^5, m - n <= 20$ $ ...

  8. subcode

    在思考.查阅subcode时,我发现Magma,Sage Math软件都提供了具体的命令和例子,对subcode的认识比较具象. 例如:Sage Math中有如下命令: C1 = codes.Hamm ...

  9. WSL2(Ubuntu)安装Docker

    原文链接:https://www.cnblogs.com/blog5277/p/12071400.html 原文作者:博客园--曲高终和寡 *******************如果你看到这一行,说明 ...

  10. GO语言Error处理

    Go语言没有提供像Java.C#.Python语言中的try...catch异常处理方式,而是通过函数返回值逐层往上抛.好处就是避免漏掉本应处理的错误.坏处是代码啰嗦. 错误与异常区别 错误指的是可能 ...