二、存在的问题  在网络上传输音频的方面存在的问题主要可以归纳为以下几点:   1 双方之间的网络连接  要进行频数据的传输,首先就是要建立数据连结。常用的通讯协议中,TCP较可靠,所以用在不允许数据丢失的应用上。而UDP则较多应用于处理速度要求较快、数据传输可靠性要求不是很高的应用上,如数据广播。通信协议的选择取决于我们所要做的应用的类型。怎样建立网络连接,稳定的接收和发送音频信号的数据流是关键。  2 音频信号的采集以及回放  在进行音频信号的采集中我们必须考虑到采样率的问题,声音信号的采样率有8Khz、16Khz、32Khz、44Khz等,每种数据采样虑产生的数据量都不一样,越高的采样率产生的数据量越大,所以我们要选择合适的采样率以适应网络的带宽。  3 音频数字信号的编码与解码。  如果把直接采集到的音频信号数据流在网络上进行传输,它所占有的带宽也是十分大的,以8Khz的采样率采集14位的音频数据那么就有以下这样的一个式子: 14 bit * 8000/second=112,000 bits/second or112kbps   从中我们可以看出以这样的方式传输音频数据,每秒需要向网络中发送112kb的数据。所以。从节省带宽的角度考虑,我们很有必要对这样的数据进行压缩。对多媒体信号的压缩我们有许多可以选择的格式,如mp2、mp3、GSM等等。同样,我们这里也存在一个对压缩格式进行选择的问题,考虑到音频数据传输的及时性,对传输的音频数据质量的要求,以及各种压缩格式的压缩比率以及进行压缩和解压缩所要耗费的系统资源等方面问题,选择合适的压缩格式就显得尤为重要。
    

解决方案 »

  1.   

    三、解决的方法  下面就针对前面提出的问题讨论一下解决的办法。  1 双方之间的网络连接  Java在这方面有其独特的优势,Java提供了丰富的网络类库的支持,可以轻松编写多种类型的网络通信程序。在我下面的例子中我就使用了TCP/IP协议,通过Java的Socket类进行编程。  2 音频信号的采集和回放以及音频数字信号的编码与解码  在解决这两个问题的时候,在网上很幸运地通过一些文章的介绍,找到了Answer Machine 演示程序的源代码(由of jsresources.org的Florian Bomers 和Matthias Pfisterer编写,网址http://www.jsresources.org/apps/am.html)。在这个程序代码中,有几个解决我们问题所需要的类,而且作者将这些类封装的很好,我们基本不需要做什么改动,只需要屏蔽其中的调试信息的输出就行了,更可贵的是它还封装了几种常见的音频格式。其中的GSM格式(Global System for Mobile Telecommunications)就是我们下面例子中采用的压缩格式,GSM格式可以将128kbps 的音频数据流 (16bit通过8k Hz的音频采样) 压缩为13kbps 的音频数据流,非常适合语音信号的传送,所以可谓是一石二鸟。  我分析过这几个类的源代码,不得不佩服它的作者,每个类的源代码都很精炼,大家可以自己分析一下。好了下面就给大家讲讲这几个类,并且将它们用到的Java Sound API中的类和函数等一并做个简单介绍,让大家对Java Sound API中常用的类也有个大致的了解。由于Java Sound API中的类比较多。限于篇幅无法对所有用到的类做详尽的解释,以下内容只是简单提及了各个类的用途和使用规范,有关Java Sound API中类的具体介绍请大家访问这里http://java.sun.com/j2se/1.4.2/docs/api/, 查找javax.sound.sampled的相关内容。  以下的提到几个文件是从Answer Machine 演示程序的源代码中提取出来的,由于是开放源代码的程序,大家在使用的时候请注意相关的公共协议。  ① AMAudioFormat类(封装在AMAudioFormat.java文件中)  AMAudioFormat类封装了CD、FM、TELEPHONE、GSM这四种质量的音频格式的参数,使用起来也非常简单,这样我们在使用Java Sound API时就不用自己去写那些复杂的代码了,但为了明白Java Sound API的原理,我们需要对它的代码做一下分析。它使用了Java Sound API中的AudioFormat这个类,这个类非常重要,在Java中对任何音频数据的使用都要实现通过它指定所需要使用的音频格式,AudioFormat类有一个嵌套的类AudioFormat.Encoding,实际上大部分对AudioFormat类的使用都是使用的这个嵌套的类。  AMAudioFormat类的重要方法:   名称:getLineAudioFormat
      调用格式:getLineAudioFormat(整型音频格式代号)
      返回值: 根据传递音频格式代号生成的AudioFormat对象。  说道这里大家可能要问了,那么通过Java Sound API可以直接使用GSM格式吗?答案是比较复杂,但同样有解决的办法,作者在这里使用了另外的开源程序的类库-tritonus的GSM编码解码库。大家需要在这里www.tritonus.org/plugins.html下载tritonous_share.jar和tritonus_gsm.jar两个文件,并在AMAudioFormat类中引用,这样就完成了GSM格式的设置。需要告诉大家的是在对AMAudioFormat.java这个类进行编译后,我们的程序运行的时候就可以不需要tritonous_share.jar和tritonus_gsm.jar这两个文件的支持了。  ② AudioCapture类(封装在AudioCapture.java文件中)  AudioCapture类封装了从音频硬件捕获音频数据并自动编码为GSM音频压缩数据的过程,并且通过它的getAudioInputStream()方法提供给我们一个音频数据输入流,我们就可以直接将这个流发送到网络中。  AudioCapture 类的重要方法: 
      名称:getAudioInputStream
      调用格式:getAudioInputStream()
      返回值:AudioInputStream对象  AudioCapture 类使用了Java Sound API中的AudioInputStream、AudioFormat、AudioSystem这几个类和TargetDataLine、LineListener接口。除了AudioFormat类我再简单介绍一下其他的类:   AudioInputStream 类是带有特殊音频格式和长度的InputStream类,它有两个构造方法,分别是AudioInputStream(InputStream stream, AudioFormat format,long length)和AudioInputStream(TargetData -Line line)。  TargetDataLine 接口是DataLine接口的一种,通过它就可以直接从音频硬件获取数据了,它有几个常用的方法,分别是:open(AudioFormat format)、void open(AudioFormat format, int bufferSize)、int read(byte[] b, int off, int len)。  AudioSystem 类是Java标准音频系统的入口点,在AudioSystem 类中使用他的getLine() 方法创建TargetDataLine对象。  LineListener接口用来对线路状态改变的时间进行监听,他的重要的方法是update(LineEvent event)方法。  ③ AudioPlayStream类(封装在AudioPlayStream.java文件中)  AudioPlayStream类与AudioCapture类刚好相反,它封装了GSM压缩音频数据的解码和音频信号的回放过程,提供给我们一个音频信号输出流。AudioCapture类用到的Java Sound API中的类它也基本都用到了,只是它使用了SourceDataLine接口而不是TargetDataLine接口  ④ Debug类(封装在Debug.java文件中)  Debug类主要用来在调试时输出讯息,代码很少,后来我把其中输出信息的语句都屏蔽了,对程序运行没有影响。  为了方便使用以上的几个类,我们需要对它们进行编译和打包,编译时需要设置相关的编译环境,以下是我们需要用到的命令行set CLASSPATH=%CLASSPATH%;.;tritonus_gsm.jar;tritonus_share.jar 
    javac am\*.java am\audio\*.java 
    jar cmf packaging\manifest.mf am.jar am\*.class 
    am\audio\*.class   说明一下,我将以上提到的Java源码文件放在了am目录下,编译之后可以得到一个8k的am.jar文件,我们下一步所需要做的就是在我们的程序中引用这个包。
      

  2.   

    能给代码我吗
    [email protected]
    谢谢
      

  3.   

    能把代码也给我吗?[email protected]  谢谢~~
      

  4.   

    我也想要代码!谢谢楼主了![email protected]
      

  5.   

    很不错,给我份代码,谢谢。[email protected]
      

  6.   

    太帅了!!!
    谢谢!
    [email protected]
      

  7.   

    非常感谢楼主的分享[email protected]
      

  8.   

    太好了,一直想了解一些视频通信和语音通信方面的资料,一直没有找到,上面写的太好了!!
    谢谢楼主分享[email protected]
      

  9.   

    楼主真是个大好人,我也想要一份代码 我的[email protected]
      

  10.   

    楼主给我一份,[email protected]
      

  11.   

    非常感谢楼主的分享[email protected]
      

  12.   

    要东西..谢谢..
    [email protected]
      

  13.   

    这几天在网上找这方面的东西,恰好找到这篇文章,原来是出自这里。
    如果能分享楼主的成果,真是感激万分!
    [email protected]
      

  14.   

    我也要一份,
    楼主可能累死了^_^
    我就不求楼主了。
    各位大侠,楼主传给你们后发一份给我吧
    [email protected]
      

  15.   

    我也要一份,
    我找这个找的好苦呀,找了好几天才找到了这里。
    各位大侠,楼主发一份给我吧,万分感激
    [email protected]
      

  16.   

    各位高人,
    小弟现在急需这个代码,我在做一个相关的java程序,好急啊!
    请那位帮帮小弟吧,不会忘了大家的 呵呵
    邮箱:  [email protected]