学做网页Applet录音机

四大名砚之洮砚

四大名砚之洮砚

2016-02-19 16:27

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

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

  多媒体基本概念及常识

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

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

  网页录音机的制作过程

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

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

  首先要碰到的是音频采集。音频采集有很多种,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格式编码等,这些压缩算法比较简单,可以在很多网站上获得压缩和解压缩的源代码。笔者对这几种压缩格式进行了测试,其主要参数及品质对比见上表。

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

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

  压缩格式 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上加入声音显示效果,你的录音机就更酷了。

  总结

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

展开更多 50%)
分享

猜你喜欢

学做网页Applet录音机

编程语言 网络编程
学做网页Applet录音机

MFC Activex 录音机控件

编程语言 网络编程
MFC Activex 录音机控件

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

win7录音机在哪

电脑网络
win7录音机在哪

win8录音机在哪里

windows系统
win8录音机在哪里

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

用Windows自带录音机录制音乐

windows 操作系统
用Windows自带录音机录制音乐

Photoshop临摹超逼真的录音机图标教程

PS PS基础
Photoshop临摹超逼真的录音机图标教程

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

MAC全屏模式下如何打开Dock

MAC全屏模式下如何打开Dock

可以获得键值的Applet

可以获得键值的Applet
下拉加载更多内容 ↓