📄 236-240.html
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1558515682"><META name=vstitle content="Java Digital Signal Processing"><META name=vsauthor content="Douglas A. Lyon"><META name=vsimprint content="M&T Books"><META name=vspublisher content="IDG Books Worldwide, Inc."><META name=vspubdate content="11/01/97"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Java Digital Signal Processing:Digital Audio Processing</TITLE>
<!-- HEADER --><STYLE type="text/css"> <!-- A:hover { color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<!--ISBN=1558515682//-->
<!--TITLE=Java Digital Signal Processing//-->
<!--AUTHOR=Douglas A. Lyon//-->
<!--PUBLISHER=IDG Books Worldwide, Inc.//-->
<!--IMPRINT=M & T Books//-->
<!--CHAPTER=5//-->
<!--PAGES=236-240//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="229-236.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="240-243.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading27"></A><FONT COLOR="#000077">Class Usage</FONT></H4>
<P>The <I>UlawCodec</I> class has several constructors. Each must, as its main goal, construct a [mu]-law-encoded byte array in a private storage area. The only way to obtain access to this storage area is by the <I>getUlawData</I> and <I>setUlawData</I> methods, in part because of a series of parallel data structures that must maintain their consistency. For example, when you invoke the <I>getDoubleArray</I> method, a check is performed to see whether the internal <I>DoubleArray</I> is null. If the array is null, it is set using computations involving <I>ulawData</I>. The consistency maintenance mechanism is invisible to the programmer.</P>
<P>Suppose the following variables are predefined:</P>
<!-- CODE SNIP //-->
<PRE>
UlawCodec ulc;
String fileName;
byte ulawArrayOfByte[];
short linearArrayOfShort[];
Double linearArrayOfDouble[];
int length;
double timeInSeconds;
String args[];
</PRE>
<!-- END CODE SNIP //-->
<P>To read a Sun AU file using a standard file open dialog box, use this code:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc = new UlawCodec();
</PRE>
<!-- END CODE SNIP //-->
<P>To read in a Sun AU file using a file name:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc = new UlawCodec(fileName);
</PRE>
<!-- END CODE SNIP //-->
<P>To construct a <I>UlawCodec</I> instance from a 16-bit linear data array:</P>
<!-- CODE SNIP //-->
<PRE>
ulc = new UlawCodec(linearArrayOfShort);
</PRE>
<!-- END CODE SNIP //-->
<P>To construct a <I>UlawCodec</I> instance from a linear double array:</P>
<!-- CODE SNIP //-->
<PRE>
ulc = new UlawCodec(linearArrayOfDouble);
</PRE>
<!-- END CODE SNIP //-->
<P>To overwrite the internal data and read a new AU file, given a file name:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.readAUFile(fileName);
</PRE>
<!-- END CODE SNIP //-->
<P>To prompt the user for a file name and overwrite the internal data:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.readAUFile();
</PRE>
<!-- END CODE SNIP //-->
<P>To write the internal data as a new AU file, given a file name:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.writeAUFile(fileName);
</PRE>
<!-- END CODE SNIP //-->
<P>To prompt the user for a file name and then write a Sun AU file:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.writeAUFile();
</PRE>
<!-- END CODE SNIP //-->
<P>To play synchronously, returning only after the sound is played:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.playSync();
</PRE>
<!-- END CODE SNIP //-->
<P>To play asynchronously, returning right away and playing the sound in the background:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.playAsync();
</PRE>
<!-- END CODE SNIP //-->
<P>To get the raw companded byte data:
</P>
<!-- CODE SNIP //-->
<PRE>
ulawArrayOfByte = ulc.getUlawData();
</PRE>
<!-- END CODE SNIP //-->
<P>To set the raw companded byte data:
</P>
<!-- CODE SNIP //-->
<PRE>
ulc.setUlawData(ulawArrayOfByte);
</PRE>
<!-- END CODE SNIP //-->
<P>To get the data as an array of linear doubles:
</P>
<!-- CODE SNIP //-->
<PRE>
linearArrayOfDouble = ulc.getDoubleArray();
</PRE>
<!-- END CODE SNIP //-->
<P>To get the number of samples:
</P>
<!-- CODE SNIP //-->
<PRE>
length = ulc.getLength();
</PRE>
<!-- END CODE SNIP //-->
<P>To get the play time in seconds:
</P>
<!-- CODE SNIP //-->
<PRE>
timeInSeconds = ulc.getDuration();
</PRE>
<!-- END CODE SNIP //-->
<P>To reverse the <I>Ulaw</I> data, forcing recomputation of the <I>DoubleArray</I>:</P>
<!-- CODE SNIP //-->
<PRE>
ulc.reverseUlaw();
</PRE>
<!-- END CODE SNIP //-->
<P>To test the read, play, and write methods:
</P>
<!-- CODE SNIP //-->
<PRE>
UlawCODEC.main(args);
</PRE>
<!-- END CODE SNIP //-->
<H4 ALIGN="LEFT"><A NAME="Heading28"></A><FONT COLOR="#000077">Reading and Writing [mu]-law</FONT></H4>
<P>The following example, excerpted from the <I>UlawCodec.java file</I>, shows how the main method is implemented:</P>
<!-- CODE SNIP //-->
<PRE>
1. public static void main(String argc[]){
2. UlawCodec ulc = new UlawCodec();
3. ulc.playSync();
4. ulc.writeAUFile();
5. }
</PRE>
<!-- END CODE SNIP //-->
<P>Line 2 shows the default constructor for the CODEC. The default constructor opens the standard file dialog box to let the user select an AU file. Line 3 plays the sound and does not return until the sound has completed playing. The <I>writeAUFile</I> opens a dialog box, where the user must type a file name to save the AU file.</P>
<H3><A NAME="Heading29"></A><FONT COLOR="#000077">The Oscillator Class</FONT></H3>
<P>The <I>Oscillator</I> class is a public class in the <I>lyon.audio</I> package and is independent of all other packages. Several instances of the <I>Oscillator</I> class can be made to create banks of oscillators. The <I>Oscillator</I> class uses double-precision data arrays and can make very low distortion waveforms. The weak link in the chain is the Java API’s voice-grade audio realization. To combat this limitation (before Sun does) would require the development of Java native methods for playing audio on all platforms. Such a development effort requires many hours of skilled labor.</P>
<H4 ALIGN="LEFT"><A NAME="Heading30"></A><FONT COLOR="#000077">Class Summary</FONT></H4>
<!-- CODE //-->
<PRE>
public class Oscillator {
public Oscillator(double frequency, int length)
public double[] getSineWave()
public double[] getSquareWave()
public double[] getSawWave()
public double[] getTriangleWave()
public double getDuration()
public int getSampleRate()
public double getFrequency()
public void setModulationIndex(double I)
public void setModulationFrequency(double fm)
public double[] getFM()
public double[] getAM()
}
</PRE>
<!-- END CODE //-->
<H4 ALIGN="LEFT"><A NAME="Heading31"></A><FONT COLOR="#000077">Class Usage</FONT></H4>
<P>The <I>Oscillator</I> class has a number of private properties that are accessed via get and set methods. An <I>Oscillator</I> instance is created for a fixed carrier frequency and number of samples. All waveforms vary from -1 to 1. Suppose the following variables are predefined:</P>
<!-- CODE SNIP //-->
<PRE>
double frequency = 440;
double length = 2000; // the total number of samples
Oscillator osc;
double audioData[];
double timeInSeconds;
int sampleRate;
double indexOfModulation;
</PRE>
<!-- END CODE SNIP //-->
<P>To make an instance of an <I>Oscillator</I>, use this code:</P>
<!-- CODE SNIP //-->
<PRE>
osc = new Oscillator(frequency, length);
</PRE>
<!-- END CODE SNIP //-->
<P>To get sine, square, sawtooth, and triangle waves:
</P>
<!-- CODE SNIP //-->
<PRE>
audioData = osc.getSineWave();
audioData = osc.getSquareWave();
audioData = osc.getSawWave();
audioData = osc.getTriangleWave();
</PRE>
<!-- END CODE SNIP //-->
<P>To get the time the wave form will last, in seconds:
</P>
<!-- CODE SNIP //-->
<PRE>
timeInSeconds = osc.getDuration();
</PRE>
<!-- END CODE SNIP //-->
<P>To get the sample rate in Hz:
</P>
<!-- CODE SNIP //-->
<PRE>
sampleRate = osc.getSampleRate()
</PRE>
<!-- END CODE SNIP //-->
<P>To get the frequency in Hz:
</P>
<!-- CODE SNIP //-->
<PRE>
frequency = osc.getFrequency()
</PRE>
<!-- END CODE SNIP //-->
<P>To set the index of modulation of the FM oscillator:
</P>
<!-- CODE SNIP //-->
<PRE>
osc.setModulationIndex(indexOfModulation);
</PRE>
<!-- END CODE SNIP //-->
<P>To set the modulation frequency of both the AM and FM oscillators:
</P>
<!-- CODE SNIP //-->
<PRE>
osc.setModulationFrequency(frequency);
audioData = osc.getFM()
audioData = osc.getAM()
</PRE>
<!-- END CODE SNIP //-->
<P>The index of modulation and the modulation frequency are covered in more detail in Chapter 6.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="229-236.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="240-243.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<hr width="90%" size="1" noshade><div align="center"><font face="Verdana,sans-serif" size="1">Copyright © <a href="/reference/idgbooks00001.html">IDG Books Worldwide, Inc.</a></font></div>
<!-- all of the reference materials (books) have the footer and subfoot reveresed --><!-- reference_subfoot = footer --><!-- reference_footer = subfoot --></BODY></HTML><!-- END FOOTER -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -