学做网页Applet录音机

2016-02-19 16:27 1 1 收藏

今天图老师小编给大家精心推荐个学做网页Applet录音机教程,一起来看看过程究竟如何进行吧!喜欢还请点个赞哦~

【 tulaoshi.com - 编程语言 】

  网络多媒体是目前Web应用的一个发展方向。在网页上录音,并发给朋友,相信他们收到你的声音一定非常高兴。如今这已经是一项很普通的多媒体应用技术,笔者使用Java语言开发出了能够嵌入Web页面上的Applet录音机(界面外观如下图所示)。如果你有编程的兴趣,不妨试试。在此,我将这种技术介绍给各位编程爱好者。

  多媒体基本概念及常识

  开发多媒体音频软件,必须了解一些多媒体基本概念,诸如采样、量化、量化位、采样频率、单双声道、音频编解码、音频压缩格式等概念。采样是把时间上连续的模拟信号变成时间上离散的、有限个样值的信号。量化是在幅度上把连续值的模拟信号变为离散值的数字信号。在时间轴上已变为离散的样值脉冲,在幅度轴上仍会在动态范围内有连续值,可能出现任意幅值,即在幅度轴上仍是模拟信号的性质,因此必须用有限个电平等级来代表实际量值。量化位是每个采样点能够表示的数据范围,经常采用的有8、12和16位。采样频率是将模拟声音波形转换为数字时,每秒钟所抽取声波幅度样本的次数,采样频率的计算单位是Hz(赫兹)。根据采样理论,为了保证声音不失真,采样频率应为声音频率的两倍左右。记录声音时,如果每次生成一个声波数据,称为单声道;每次生成二个声波数据,成为立体声(双声道)。量化位和采样频率越高,音质就越好。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  正常人耳听觉的声音频率范围大约在20Hz至20KHz之间,人的语音频率大概在300Hz至3.4KHz之间。对于语音来说,采用8KHz的采样频率已经足够了。所以我们采用8KHz采样频率、16位量化位、单声道来记录和播放语音,就可以满足网页上的语音需求了。

  网页录音机的制作过程

  了解了以上常识,下面来看看录音机的制作过程。

  首先要碰到的是音频采集。音频采集有很多种,JDK 1.3中构建TargetDataLine类实例来实现声音数据采集。在此例中,我采用Visual J++的J/Direct调用Windows API函数来实现声音的采集。

  声音俘获主要由AudioCapture、AudioDataEvent、AudioDataListener三个类组成。我们依次按照0.1秒时间采样数据块的大小(即1600字节)作为所送出到系统的录音数据缓冲区大小,这样也就相当于每隔0.1秒声卡提交给我们一次声音数据。另外,使用Windows API方式声音采集有一个好处,录音过程不需要建立单独的线程。这是因为有回调函数的巨大作用,这样节省了系统资源,提高了程序的稳定性。

  

//声音俘获类:
...
public class AudioCapture{
...
public AudioCapture(){
...
waveincaps=new WAVEINCAPS();
wavehdr=new WAVEHDR[bufferlen];
}
public void addAudioDataListener(AudioDataListener lter){
listeners.addElement(lter);
}
void applyBuffer(){
for(int i=0;ibufferlen;i++){
wavehdr[i]=new WAVEHDR();
int
adr=dlllib.addrOfPinnedObject(dlllib.getPinnedHandle(data[i]));
wavehdr[i].lpData=adr;
...
}
}
int chkData(byte[] a){//将整型低16位高低位交叉并转为字节
...
}
public void close(){
if(!useful)return;
isclose=true;
waveInStop(deviceid[0]);
...
}
...
synchronized void notifyListener(int minValue,byte[] audioData){
AudioDataEvent evt=new AudioDataEvent(this,minValue,audioData);
For(Enumeration enu=listeners.elements();enu.hasMoreElements();)
((AudioDataListener)enu.nextElement()).onAudioDataArrived(evt);
}
...
public void setMuteValue(int muteValue){
this.muteValue=muteValue;
}
/**@dll.import("WINMM",auto)*/
...
public static native int waveInReset(int hwi);
private class c extends Callback{
AudioCapture record;
c(AudioCapture tt){
record=tt;
}
...
}
}
//缓冲数据提交事件类:
import java.util.EventObject;
public class AudioDataEvent extends EventObject{
...
}
//事件侦听接口
import java.util.EventListener;
public interface AudioDataListener extends EventListener{
public abstract void onAudioDataArrived(AudioDataEvent evt);
}

  第二步,数据的编码压缩存储。由声卡采集的数据是一连串16位脉冲编码调制(PCM格式)的数据,数据量很大,如果不采取压缩处理,不利于文件的存储和传输。所以要进行数据的压缩编码,这就是我们会碰到的声音编码数据格式。压缩编码方法有很多种,有GSM、IAM4、AU格式编码等,这些压缩算法比较简单,可以在很多网站上获得压缩和解压缩的源代码。笔者对这几种压缩格式进行了测试,其主要参数及品质对比见上表。

  压缩格式主要参数及品质对比

  压缩格式 GSM IMA4 AU

  压缩比 10:1 4:1 2:1

  文件大小 很小 小 中

  声音质量 一般 好 好

  编解码速度 慢 快 很快

  数据量(byte/s) 165 400 800

  一般来说,人说话时并不是非常连续的,哪怕是你有意发连续的声音,其实有很多时间段是处在静音状态(没有声音或声音很小,量化数据值很小),只要记录它的一个状态就可以了。所以声音数据区的数据格式就是(数据头+数据体)的方式。对于静音数据,数据头为0,数据体为空。

  在声音回放时,先读数据头,如果数据头不为0,则解压数据体播放;如果数据头为0,则暂停一定时间或者写入一定长度的静音数据即可。采用这种方式可以大大减小记录语音文件,并且不影响声音的还原回放。

  

//处理录音数据到达事件
public void onAudioDataArrived(AudioDataEvent evt){
...
int min=evt.getAudioMinValue();
fileWriter.write((min==0?0:1));
if(min!=0){
Convert.BytesToInts(evt.getAudioData(),audiodata);
fileWriter.write(Codec.encode(evt.getAudioData()));
}
...
}

  第三步,声音采集编码保存结束后,就可以回放我们录制的声音。

  接下来我们要在网页上来播放它。Java Applet支持AU格式声音的回放,使用非常简单。所以我们把录制并压缩的声音数据解码为AU格式,就可以很方便地进行声音回放了。在sun.audio包中提供的au流数据播放sun.audio.AudioPlayer.start(InputStream),实际上是虚拟机的au播放类每隔50毫秒依次调用InputStream的read(byte[],abyte0,int i,int j)方法,每次读取长度为400字节的AU格式数据用来播放。我们知道,输入流的read方法是阻塞方式的,而解压缩声音数据是要费时的,如果在其请求数据时再解压数据并写入缓冲区,则播放声音时听起来会断断续续的,那是不可行的。所以需要单独建立解压缩数据的线程,也就是说从虚拟机的au播放类读取数据的线程中独立出来,用缓冲区做为两个线程的管道连接,解压缩线程不停地写入缓冲区中,播放线程不断地从缓冲区中读取并播放。这样一来,对于播放声音的暂停、停止等功能就很容易实现。所以我们需要重载read(byte[],abyte0,int I,int j)方法。

  

//音频缓冲区类
import java.io.*;
public class AudioBuffer extends InputStream{
int capacity=4096;
...
public AudioBuffer(AudioPlayer ap){
player=ap;
clearData();
}
public void close(){
isclose=true;
synchronized(putManager){
if(waitingPut0)putManager.notify();
}
synchronized(getManager){
if(waitingGet0)getManager.notify();
}
}
public void clearData(){
...
}
public void suspend(){ispause=true;}
public void resume(){ispause=false;}
public void write(int i){
synchronized(putManager){
while(emptyBytes1){
waitingPut++;
try{
putManager.wait();
}catch(InterruptedException _ex){}
waitingPut--;
}
...
}
synchronized(getManager){
usedBytes++;
if(waitingGet0)getManager.notify();
}
}
public void write(byte[] d){
write(d,0,d.length);
}
public void write(byte[] d,int i,int j){
...
synchronized(getManager){
usedBytes+=j;
if(waitingGet0)getManager.notify();
}
}
public int read(){
...
}
public int read(byte[] d){
return read(d,0,d.length);
}
public int read(byte[] d,int i,int j){
if(isclose)return -1;
if(ispause){
d[i]=127;
return 1;
}
synchronized(getManager){
...
}
System.arraycopy(data,readPtr,d,i,k);
ReadPtr+=k;
readPtr%=capacity;
usedBytes-=j;
}
synchronized(putManager){
emptyBytes+=j;
if(waitingPut0)putManager.notify();
}
try{
player.notifyListener(AudioPlayEvent.PLAY_DATA,d);
}catch(Exception e){}
return j;
}
}
//音频播放器类
public class AudioPlayer implements Runnable{
...
AudioBuffer buffer=new AudioBuffer(this);
sun.audio.AudioPlayer.start(buffer);
...
byte[] auData=new byte[400];
//存放解压后的au数据
int compressLength=165;
//GSM格式为165;IMA格式为400;AU格式为800
byte[] compressData=new byte[compressLength];
//存储从文件流中读取的压缩格式数据
...
public void run(){
...
fileInputStream.read(compressData);//从音频文件读取压缩格式数据,此输入流要处理静音
Codec.decode(abyte0,auData); //解压缩数据到auData
Buffer.write(auData,0,400);//写入到缓冲区
...
}
...
}

  最后,将上述各个模块拼接起来,并把GUI做好就可以使用了。如果在GUI上加入声音显示效果,你的录音机就更酷了。

  总结

  这里介绍的声音处理的主要技术,可以组合或衍生使用。例如,可以在网页上方便地实现声音回放;可以加入调节播放起点(跳跃播放)功能,而不使用其它播放器;还可以做语音留言系统。如果数据通过流格式以组播方式实时传出,另一端接收下来然后播放出来,又可非常简单地实现实时语音系统,即语音聊天。另外,有了自己的语音库,还可以实现简单的语音合成技术,让计算机读出文本内容

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

来源:https://www.tulaoshi.com/n/20160219/1612151.html

延伸阅读
标签: windows系统
Windows8中打开系统自带录音机程序的操作办法   方法一:在正常桌面中,按键盘的 F3 按键,键入录音机并回车搜索,然后点击选择录音机。 方法二:使用组合热键Win+R调出运行对话框,输入soundrecorder,确定后打开录音机程序。 方法三:在 Metro 界面,然后单击鼠标右键,点击屏幕下方出现的所有程序,在所有程序界面...
标签: PS PS教程
编者按:今天这个教程适合有基础的同学进阶练习,原作者是追波大神,效果逼真到翻天,这篇临摹教程也特别用心,光截图打字就花了三个多小时,强烈推荐同学们马起来练习 昨天在某个网站看到一位高手临摹国外大师的一张ICON,效果逼真。一整夜我都手痒痒得无法入睡,早上起来也打算来一个,不过这样那样的琐事之后又是午后,估...
标签: 软件教程
龙卷风网络收音机是现在非常流行的一款收音机软件,这个软件有一个很好的录音功能,那怎么样更好的使用龙卷风网络收音机的录音功能呢?小编给大家分享下龙卷风网络收音机怎么录音,具体告诉大家用龙卷风网络收音机内置录音,一起来看看具体操作吧 第一步:我们要先确定我们的电脑是否装了声卡哦,打开设备管理器...
龙卷风收音机怎么录音   第一步:我们要先确定我们的电脑是否装了声卡哦,打开设备管理器,看到下图,如果没装声卡的话会有个感叹号的图标,这些很多人应该都明白(小编提醒:声卡驱动的话最好还是选些稳定点的,不要盲目地追求最新) 第二步:确定自己启用了声卡来录音,进入控制面板硬件和声音声音管理音频设备 第三...
Application和Applet是利用JAVA语言生成的可运行代码中最常用的两种,两者都必须在JAVA虚拟机上运行。简单来讲,Application更象我们平常用VB,VC等编写的桌面程序,多以控制台(CONSOLE)方式运行,当然也很容易实现窗口应用.Applet可以嵌入Web页面中,在支持JAVA虚拟机的浏览器上运行。在使用时应该区应用。

经验教程

825

收藏

24
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部