鼎誉网络科技-长沙专业建站网
首 页 | 网站建设 | 域名知识 | 网站空间 | 网站维护 | 网站防黑 | 服务器专区 | 网站营销 | 网站赚钱 | 网站备案
站长工具 | 网页设计 | 作品集 | 鼎誉网络科技 | 网站SEO优化 | 免费优化分析 | 网站赚钱啦 | 邮件群发 | 站长墙 | 联系我们
网站搜索 网站搜索:
鼎誉网络科技让您企业的网络营销至少少走一年弯路!
免费的邮件推广工具送给您!

长沙网站制作长沙网站建设长沙建站网站建站网站设计网站学习ASP程序程序学习美工设计页面设计好玩网站商务型网站制作株洲网站制作湖南网站制作,北京网站制作湖北网站制作湘潭网站制作怀化网站制作郴州网站制作邵阳网站制作常德网站制作我要做网站我公司要做网站做网站网站益阳网站制作湘西网站制作永州网站制作娄底网站制作张家界网站制作旅游网站制作我的网站网站除木马网站优化网站SEO免费推广免费优化长沙最好的网络公司,长沙最低价的网络公司长沙最牛的网站长沙最牛的优化长沙最好的人长沙最好的网站长沙低价网站免费做网站 小陈网站制作长沙小陈网站制作长沙交友长沙网络交友

您现在的位置: 鼎誉网络科技营销系统 >> 文章中心 >> 网站建设 >> 正文

网络的发展

作者:admin 文章来源:本站原创 点击数: 更新时间:2010/9/24 17:06:26

 网络

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

多媒体基本概念及常识

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

正常人耳听觉的声音频率范围大约在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;i<bufferlen;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(waitingPut>0)putManager.notify();
}
synchronized(getManager){
if(waitingGet>0)getManager.notify();
}
}
public void clearData(){
...
}
public void suspend(){ispause=true;}
public void resume(){ispause=false;}
public void write(int i){
synchronized(putManager){
while(emptyBytes<1){
waitingPut++;
try{
putManager.wait();
}catch(InterruptedException _ex){}
waitingPut--;
}
...
}
synchronized(getManager){
usedBytes++;
if(waitingGet>0)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(waitingGet>0)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(waitingPut>0)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做好就可以使用

本文关键字:|网站优化改版|网站建设,网站制作,做网站的公司|湖南网站制作|长沙网站制作,长沙网站建设,长沙做网站的公司,长沙网站公司,网站营销|


·以上内容部份或全部来自网络,由鼎誉网科搜集整理,如有侵权请联系我们立即删除,如转载请注明原文出处,并保留以下内容。
    [鼎誉网科] http://www.dywlkj.comhttp://www.xckww.com 是长沙市鼎誉网络科技有限公司的品牌,专业经营域名注册虚拟主机网站建设服务器租用托管 , 网站优化 , 网站改版杀毒等业务。经过多年的高速发展,“鼎誉网科”已经成为我国一家知名的互联网服务提供商。
  • 上一篇文章:

  • 下一篇文章:
  •   本文相关文章:

     让你的网站更加美观,网站建设之网页设计的优质方法
    如果做出一个用户体验上乘的优质网站?
    域名知识解读
    微信搜索:又一个被高估的“微信功能”
    网络变革:四大关键词解读5G
    小网站的赚钱之路
    网站备案详细流程
    数据中心发生故障后如何进行事故分析
    网站防黑应该做到的几点
    SEO网站优化怎么做

    点击排行  
    固顶文章市面上便宜网站制作利弊
    普通文章史上 全推广渠道总汇,不可不知道的优质
    普通文章什么是网络营销,网络营销包含哪些方面
    普通文章网络推广优质干活,做一次保证一年的流
    普通文章网络推广的有效渠道有哪些
    普通文章从小白到高手,网络推广的一百种方法
    普通文章SEO与SEO,为什么你做的没效果,用这四
    普通文章外链为王,内容为皇,SEO到底应该怎么做
    普通文章网站建设中这几件事你一定要注意
    普通文章移动建站与电脑建站哪方更重要,弹窗真
    网站建设
    固顶文章市面上便宜网站制作利弊
    普通文章史上 全推广渠道总汇,不可不知道的优质
    普通文章什么是网络营销,网络营销包含哪些方面
    普通文章网络推广优质干活,做一次保证一年的流
    普通文章网络推广的有效渠道有哪些
    普通文章从小白到高手,网络推广的一百种方法
    普通文章SEO与SEO,为什么你做的没效果,用这四
    普通文章外链为王,内容为皇,SEO到底应该怎么做
    普通文章网站建设中这几件事你一定要注意
    普通文章移动建站与电脑建站哪方更重要,弹窗真
    普通文章 优质的建站方案,H5一站式建站pc移动同
    普通文章优化网站,从每一个细节开始,一篇优质
    普通文章免费的好用助手,免费运营助手助你运营
    普通文章如何快速诊断一个网站是否有优化到位
    普通文章如何通过伪原创文章来提升网站权重,伪
    普通文章网站建设时如何做好网站页面的关键词设
    普通文章网站优化的常见方法
    普通文章网站优化很重要,网站优化应该如何做
    普通文章让你的网站更加美观,网站建设之网页设
    普通文章如果做出一个用户体验上乘的优质网站?
    普通文章网站备案详细流程
    普通文章网站防黑应该做到的几点
    普通文章SEO网站优化怎么做
    普通文章微信6.0该这么改?看微信重度用户的猜想
    普通文章中小企业是否应该做营销型网站?
    - 友情链接 - 我要去主站申请链接
    [申请链接]
    [更多链接]
    关于湖南鼎誉网络 | 各地网站制作 | 域名空间 | 服务器托管 | 网站学习 | 培训天地 | 免费推广鼎誉网络 | 友情链接 | 邮件系统
    Copyright 2015 powered by dywlkj.com & 鼎誉网络 湘ICP备09029911号 All Rights Reserved.
    Baidu

    (工作日:9:00-18:30)

    在线QQ

    商务咨询①

    商务咨询②

    商务咨询③

    商务咨询④

    联系电话0731-854196570731-83527868

    免费服务热线400-0731-269

    微博鼎誉网络官方微博

    博客鼎誉网络官方博客