pcm 文件存储的是 原始的声音波型二进制流,没有文件头。

(1)首先要确认 pcm文件的每个采样数据 采样位数,一般为8bit或16bit。

(2)然后确定是双声道还是单声道,双声道是两个声道的数据交互排列,需要单独提取出每个声道的数据。

(3)然后确定有没有符号位,如采样点位16bit有符号位的的范围为-32768~32767

(4)确定当前操作系统的内存方式是大端,还是小端存储。具体看http://blog.csdn.net/u013378306/article/details/78904238

(5)根据以上四条对pcm文件进行解析,转化为10进制文件

注意:对于1-3可以在windows使用cooledit 工具设置参数播放pcm文件来确定具体参数,也可以使用以下java代码进行测试:

本例子的语音为: 静默1秒,然后说 “你好”,然后静默两秒。pcm文件下载路径:http://download.csdn.net/download/u013378306/10175068

packagetest;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.io.InputStream;importjavax.sound.sampled.AudioFormat;importjavax.sound.sampled.AudioSystem;importjavax.sound.sampled.DataLine;importjavax.sound.sampled.LineUnavailableException;importjavax.sound.sampled.SourceDataLine;public classtest {/***@paramargs

*@throwsException*/

public static void main(String[] args) throwsException {//TODO Auto-generated method stub

File file= new File("3.pcm");

System.out.println(file.length());int offset = 0;int bufferSize =Integer.valueOf(String.valueOf(file.length())) ;byte[] audioData = new byte[bufferSize];

InputStream in= newFileInputStream(file);

in.read(audioData);float sampleRate = 20000;int sampleSizeInBits = 16;int channels = 1;boolean signed = true;boolean bigEndian = false;//sampleRate - 每秒的样本数//sampleSizeInBits - 每个样本中的位数//channels - 声道数(单声道 1 个,立体声 2 个)//signed - 指示数据是有符号的,还是无符号的//bigEndian -是否为大端存储, 指示是否以 big-endian 字节顺序存储单个样本中的数据(false 意味着//little-endian)。

AudioFormat af = newAudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);

SourceDataLine.Info info= new DataLine.Info(SourceDataLine.class, af, bufferSize);

SourceDataLine sdl=(SourceDataLine) AudioSystem.getLine(info);

sdl.open(af);

sdl.start();for(int i=0;i

audioData[i]*=1;while (offset

offset+=sdl.write(audioData, offset, bufferSize);

}

}

}

如果测试通过确定了参数就可以对pcm文件进行解析,如下java代码对每个采样数据为16bits,单声道的pcm,在操作系统内存为小端存储下解析为10进制文件。

packagetest;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileWriter;importjava.io.InputStream;importjava.math.BigInteger;public classffff {/*** 采样位为16bits,小端存储,单声道解析为10进制文件

*@paramargs*/

public static voidmain(String[] args) {try{

File file= new File("3.pcm");

System.out.println(file.length());

System.out.println(file.length());int bufferSize =Integer.valueOf(String.valueOf(file.length()));byte[] buffers = new byte[bufferSize];

InputStream in= newFileInputStream(file);

in.read(buffers);

String rs= "";for (int i = 0; i < buffers.length; i++) {byte[] bs = new byte[2];

bs[0]=buffers[i+1];//小端存储,

bs[1]=buffers[i];int s = Integer.valueOf(binary(bs, 10));

i= i + 1;

rs+= " " +s;

}

writeFile(rs);

in.close();

}catch(Exception e) {

e.printStackTrace();

}

}public static voidwriteFile(String s) {try{

FileWriter fw= new FileWriter("hello3.txt");

fw.write(s,0, s.length());

fw.flush();

fw.close();

}catch(Exception e) {

e.printStackTrace();

}

}public static String binary(byte[] bytes, intradix) {return new BigInteger(bytes).toString(radix);//这里的1代表正数

}

}

执行完可以查看hello.txt ,可以看到一开始振幅很小,如下,基本不超过100:

-15 -12 -18 -24 -17 -8 -8 -17 -22 -14 -5 -18 -47 -67 -60 -41 -28 -28 -23 -12 -6 -9 -13 -8 0 6 21 49 68 48 -2 -43 -47 -32 -22 -10 22 56

但说你好的时候,振幅变得很大:

-2507 -2585 -2600 -2596 -2620 -2670 -2703 -2674 -2581 -2468 -2378 -2305 -2200 -2018 -1774 -1523 -1307 -1127 -962 -806 -652 -505 -384 -313 -281 -241 -163

然后静默两秒,振幅又变的很小:

5 3 0 -4 -5 -6 -6 -7 -7 -8 -9 -8 -10 -10 -11 -10 -11 -11 -11 -11 -11 -11 -10 -9 -7 -6 -3 -2 -2 -3 -3 -3 -1 2 4 4

具体波形图可以使用python代码显示:

importnumpy as npimportpylab as plimportmathimportcodecs

file=codecs.open("hello3.txt","r") //原文代码file=codecs.open("hello3.txt","rb"),b是binary,以二进制方式读取,是错误的。

lines=" "

for line infile.readlines():

lines=lines+line

ys=lines.split(" ")

yss=[]

ays=list()

axs=list()

i=0

max1=pow(2,16)-1

for y inys:if y.strip()=="":continueyss.append(y)for index inrange(len(yss)):

y1=yss[index]

i+=1;

y=int(y1)

ays.append(y)

axs.append(i)#print i

file.close()

pl.plot(axs, ays,"ro")#use pylab to plot x and y

pl.show()#show the plot on the screen

得到波形图

这里音频振幅与audacity中呈现的结果吻合,只是这里把振幅放大以便用肉眼去观察。

2019-11-20 更新:

经过实践发展,可以使用时间单位来检测该时间内的数据是否检测振幅。

(数学不太好,随便用一个字符代替说明一下)

设时间单位为t,音频采样率为S,如果连续的时间单位t时间内振幅很小(也可以计算分贝数),可以认为是静音(没有声音录入) 。

待检验数据长度L=S*t,则检测目标是长度为L的数组,如果这个时间类振幅(分贝)数据小于阈值(threshold),则认为近似静音。

例:采样率16000,2秒以外则认为没有声音输入。即 2*16000长度的数组内,所有数组低于一个阈值。

stackoverflow答案:

How can I detect silence when recording operation is started in Java?

Calculate the dB or RMS value for a group of sound frames and decide at what level it is considered to be 'silence'.

What is PCM data?

Data that is in Pulse-code modulation format.

How can I calculate PCM data in Java?

I do not understand that question. But guessing it has something to do with the speech-recognition tag, I have some bad news.

This might theoretically be done using the Java Speech API. But there are apparently no 'speech to text' implementations available for the API (only 'text to speech').

I have to calculate rms for speech-recognition project. But I do not know how can I calculate in Java.

For a single channel that is represented by signal sizes in a double ranging from -1 to 1, you might use this method.

/**Computes the RMS volume of a group of signal sizes ranging from -1 to 1.*/

public double volumeRMS(double[] raw) {double sum =0d;if (raw.length==0) {returnsum;

}else{for (int ii=0; ii

sum+=raw[ii];

}

}double average = sum/raw.length;double sumMeanSquare =0d;for (int ii=0; ii

sumMeanSquare+= Math.pow(raw[ii]-average,2d);

}double averageMeanSquare = sumMeanSquare/raw.length;double rootMeanSquare =Math.sqrt(averageMeanSquare);returnrootMeanSquare;

}

There is a byte buffer to save input values from the line, and what I should have to do with this buffer?

If using the volumeRMS(double[]) method, convert the byte values to an array of double values ranging from -1 to 1. ;)

笔者的思路是计算音频分贝值,可以参考通过pcm音频数据计算分贝

很多场合我们需要动态显示实时声音分贝,下面列举三种计算分贝的算法。(以双声道为例,也就是一个short类型,最大能量值为32767)

1:计算分贝 音频数据与大小

首先我们分别累加每个采样点的数值,除以采样个数,得到声音平均能量值。

然后再将其做100与32767之间的等比量化。得到1-100的量化值。

通常情况下,人声分布在较低的能量范围,这样就会使量化后的数据大致分布在1-20的较小区间,不能够很敏感的感知变化。

所以我们将其做了5倍的放大,当然计算后大于100的值,我们将其赋值100.

//参数为数据,采样个数//返回值为分贝

#define VOLUMEMAX 32767

int SimpleCalculate_DB(short* pcmData, intsample)

{

signedshort ret = 0;if (sample > 0){int sum = 0;

signedshort* pos = (signed short *)pcmData;for (int i = 0; i < sample; i++){

sum+= abs(*pos);

pos++;

}

ret= sum * 500.0 / (sample *VOLUMEMAX);if (ret >= 100){

ret= 100;

}

}returnret;

}

2:计算均方根(RMS) 即能量值

static const float kMaxSquaredLevel = 32768 * 32768;

constexprfloat kMinLevel = 30.f;void Process(const int16_t*data, size_t length)

{float sum_square_ = 0;

size_t sample_count_= 0;for (size_t i = 0; i < length; ++i) {

sum_square_+= data[i] *data[i];

}

sample_count_+=length;.float rms = sum_square_ / (sample_count_ *kMaxSquaredLevel);//20log_10(x^0.5) = 10log_10(x)

rms = 10 *log10(rms);if (rms < -kMinLevel)

rms= -kMinLevel;

rms= -rms;return static_cast(rms + 0.5);

}

3:获取音频数据最大的振幅(即绝对值最大)(0-32767),除以1000,得到(0-32)。从数组中获取相应索引所对应的分贝值。(提取自webrtc)

const int8_t permutation[33] ={0,1,2,3,4,4,5,5,5,5,6,6,6,6,6,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,9,9};

int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t*vector, size_t length)

{

size_t i= 0;int absolute = 0, maximum = 0;for (i = 0; i < length; i++) {

absolute= abs((int)vector[i]);if (absolute >maximum) {

maximum=absolute;

}

}if (maximum > 32767) {

maximum= 32767;

}return(int16_t)maximum;

}void ComputeLevel(const int16_t*data, size_t length)

{

int16_t _absMax= 0;

int16_t _count= 0;

int8_t _currentLevel= 0;

int16_t absValue(0);

absValue=WebRtcSpl_MaxAbsValueW16(data,length);if (absValue >_absMax)

_absMax=absValue;if (_count++ == 10) {

_count= 0;

int32_t position= _absMax/1000;if ((position == 0) && (_absMax > 250)){

position= 1;

}

_currentLevel=permutation[position];

_absMax>>= 2;

}

}

python pcm 分贝_语音文件 pcm 静默(静音)判断相关推荐

  1. python 跳过_如果文件已经存在,Python将跳过一个函数

    我需要在python中创建一个skip函数,如果文件已经存在,它将跳过我的下载代码.在 该功能应如何工作: (如果文件存在,则无需运行此代码,只需跳到下一个代码. 如果不存在,则运行此代码,然后运行下 ...

  2. python rm 条件_删除文件 (rm)

    # 附录A-练习14:删除文件 (rm) 这节练习中,你将学会如何使用`rm`命令删除一个文件. ### 做到这些 ### Linux ~~~ $ cd temp $ ls uncool.txt ia ...

  3. python读取日期_从文件中读取日期和数据(Python)

    我想从文件中读取时间字符串和数据,但是当我使用loadtxt时,我不能同时读取字符串和数字,因为字符串不是浮点型的.所以我尝试使用genfromtxt并使用delimiter=[]+[]+[]作为我所 ...

  4. python另存为对话框_“另存为文件”对话框如何不允许覆盖

    我正在尝试在tkinter中创建一个保存文件对话框.我需要保存文件名以便以后使用.但是,我不希望filedialog接受选择已存在的文件名.在 到目前为止我只有这个:from tkinter impo ...

  5. java录制pcm文件_AudioRecord录制PCM格式的语音示例

    AudioRecord可以将手机或麦克风的声音录制成pcm格式的语音文件,本案例将再service中实现pcm声音的录制,并提供将pcm格式语音转化为mp3格式的方法,先来看看AudioRecord如 ...

  6. python 将多个wav语音文件合到一起

    (本文已经同步到公众号) ******######******上期关于pcm语音格式文件合成文章:python把千万个语音文件合成一个 pcm格式的音频文件与wav格式还是有很大差别的. wav格式: ...

  7. python语音合成并播放_使用Python实现文字转语音并生成wav文件的例子

    目前手边的一些工作,需要实现声音播放功能,而且仅支持wav声音格式. 现在,一些网站上支持文字转语音功能,但是生成的都是MP3文件,这样还需要额外的软件来转成wav文件,十分麻烦. 后来,研究Pyth ...

  8. python 语音特征提取_使用python实现语音文件的特征提取方法

    概述 语音识别是当前人工智能的比较热门的方向,技术也比较成熟,各大公司也相继推出了各自的语音助手机器人,如百度的小度机器人.阿里的天猫精灵等.语音识别算法当前主要是由rnn.lstm.dnn-hmm等 ...

  9. python对语音文件加入高斯白噪声(含公式推导)

    python对语音文件加入高斯白噪声(带公式推导) 1. 信噪比概念及计算公式 2.已知信噪比,如何去产生固定功率的噪声 3.完整代码 1. 信噪比概念及计算公式 信噪比(Signal-to-nois ...

最新文章

  1. Redis基础、应用、第三方支持组件总结
  2. SQL SERVER 数据库 怎么从一个服务器一个表中把数据插入到另一个服务器中的一个表内(纯复制)...
  3. opcua 入门简介 java_大二的学生自学Java有出路吗?
  4. 雷军微博念了几句诗 评论区疯狂猜谜
  5. 查找一:C++静态查找
  6. 电脑屏幕卡住了按什么都没反应_刚买2个月,联想电脑屏幕出现坏点,售后回复:坏点不够3个不能保修...
  7. 【python】if判断、for循环、while循环练习题
  8. “/应用程序中的服务器错误
  9. Mybatis_day4_Mybatis的缓存
  10. 穿越沙漠问题c语言算法,沙漠穿越问题_c语言课程设计.doc
  11. 2022-2027年中国环锻件行业市场全景评估及发展战略规划报告
  12. Unity 3D模型展示之UI布局
  13. outlook规则导出_如何在Outlook和Gmail之间导入和导出联系人
  14. 狗年最后一文[2007-02-16]
  15. 计算机主机放到什么位置最好,电脑桌放在哪个位置好 这些建议你一定要看
  16. 柔性显示实现的关键技术
  17. IDEA版最新SMM整合,根据手机号实现登录/注册/修改密码
  18. 天哪,我只是想吃顿红烧肉啊
  19. 常用估值方法的编程实现(1):自由现金流折现
  20. [Unity]ShaderGraph问题所有材质丢失Maximum number (256) of shader keywords exceeded

热门文章

  1. Spring什么是复杂对象
  2. SpringBoot 路径处理
  3. java 手写缓存,java手写多级缓存
  4. oracle数据结构是什么意思,Oracle数据结构知多少(一)
  5. Protobuf之proto文件编写规则
  6. 面试篇---1 如何区分深拷贝与浅拷贝
  7. Left 4 Dead升级补丁总汇(3663-3986)
  8. Git + Maven + Jenkins 实现自动化部署
  9. Java EE之旅02 CSS基础
  10. Anconda安装教程