⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 243-248.html

📁 dshfghfhhgsfgfghfhfghgfhfghfgh fg hfg hh ghghf hgf hghg gh fg hg hfg hfh f hg hgfh gkjh kjkh g yj f
💻 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=243-248//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="240-243.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="248-253.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading34"></A><FONT COLOR="#000077">Building the WaveTable</FONT></H4>
<P>The <I>AudioDataFromTable</I> method in the <I>Oscillator</I> class is used to turn a single cycle of <I>WaveTable</I> into a long array of audio data. A constraint on the <I>audioData</I> array is that it must have an absolute value that is strictly less than 1 (because of the companding formulas).</P>
<!-- CODE SNIP //-->
<PRE>
1. private double[] AudioDataFromTable() {
2.     int k = 0;
3.     for (int i = 0; i &lt; audioData.length; i++) {
</PRE>
<!-- END CODE SNIP //-->
<P>Line 4 builds the <I>audioData</I> from the <I>waveTable</I>. The indexes, <I>i</I> and <I>k</I> , both begin at 0. Lines 6 and 7 reset <I>k</I>, while index <I>i</I> continues to increment.</P>
<!-- CODE //-->
<PRE>
4.          audioData[i] = waveTable[k];
5.          k++;
6.          if (k &gt; = waveTable.length)
7.               k = 0;
8.     }
9.     System.out.println("\nlambda="+lambda+
10.          "\nfrequency = "+frequency+
11.          "\nwaveTable.length = "+waveTable.length+
12.          "\nsampleRate = "+sampleRate+
13.          "\naudioData.length = "+audioData.length+
14.          "\nactual frequency = "+actualFrequency());
15.     return audioData;
16.     }
</PRE>
<!-- END CODE //-->
<P>In the <I>getSineWave</I> method, the <I>waveTable</I> is computed for a single cycle. To make sure that the absolute value of the amplitude of the sine wave is always less than 1, it is first multiplied by 0.98 (line 20).</P>
<!-- CODE SNIP //-->
<PRE>
17.     public double[] getSineWave() {
18.     for (int i = 0; i&lt;waveTable.length; i++)
19.          waveTable[i] =
20.               0.98*Math.sin(twopi * i/waveTable.length);
21.     return AudioDataFromTable();
22.     }
</PRE>
<!-- END CODE SNIP //-->
<P>To build a wavetable for a saw wave, we set the initial voltage to -1 and then compute a change in voltage, <I>dv</I> , using the length of the wavetable, <I>L</I> so that</P>
<P ALIGN="CENTER"><IMG SRC="images/05-43d.jpg"></P>
<P>Then, after L-1 intervals, the final voltage will reach a value of 1-dv. The following code implements the <I>getSawWave</I> method:</P>
<!-- CODE SNIP //-->
<PRE>
1.     public double[] getSawWave() {
</PRE>
<!-- END CODE SNIP //-->
<P>In line 2, the initial voltage is set to a value that is a little higher than 1.0 because of the constraint on the CODEC&#146;s input. Also, in line 4, the check is i&lt;<I>waveTable</I>.<I>length</I> rather than i &lt;= <I>waveTable</I>.<I>length</I>. Thus, the saw wave will end at (<I>v</I>-d<I>v</I>) rather than at 1.0 volts.</P>
<!-- CODE //-->
<PRE>
2.     double v = -0.99;
3.     double dv = 2.0 / (double) waveTable.length;
4.     for (int i = 0; i&lt;waveTable.length; i++){
5.          waveTable[i] = v;
6.          v + = dv;
7.     }
8.     System.out.println("Sawwave ends at:"+(double)(v-dv));
9.     return  AudioDataFromTable();
10.     }
</PRE>
<!-- END CODE //-->
<P>The saw wave output is shown in Figure 5.8.
</P>
<P><A NAME="Fig8"></A><A HREF="javascript:displayWindow('images/05-08.jpg',217,307 )"><IMG SRC="images/05-08t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/05-08.jpg',217,307)"><FONT COLOR="#000077"><B>Figure 5.8</B></FONT></A>&nbsp;&nbsp;The saw wave output.</P>
<H3><A NAME="Heading35"></A><FONT COLOR="#000077">The DoubleDataProducer Interface</FONT></H3>
<P>The <I>DoubleDataProducer</I> interface is a public interface that resides in the <I>lyon.audio</I> package. The <I>DoubleDataProducer</I> interface isolates the <I>OscopeFrame</I> class (see next section) from application-specific code needed to obtain an array of data.</P>
<P>Classes that implement the <I>DoubleDataProducer</I> interface must provide methods whose signature is consistent with lines 3 and 4:</P>
<!-- CODE SNIP //-->
<PRE>
1.     package lyon.audio;
2.     public interface DoubleDataProducer {
3.     double [] getDoubleData();
4.     void openDataFile();
5.     }
</PRE>
<!-- END CODE SNIP //-->
<P>For an example of usage, see the following section.
</P>
<H3><A NAME="Heading36"></A><FONT COLOR="#000077">The OscopeFrame Class</FONT></H3>
<P>The <I>OscopeFrame</I> class is a public abstract class in the <I>lyon.audio</I> package. The <I>OscopeFrame</I> can be extended to add an oscilloscope-type feature to any frame. <I>OscopeFrame</I> has its own paint method, so the user must be careful to call <I>super.paint</I> if a paint method is implemented in the subclass.</P>
<P><I>OscopeFrame</I> has four private scroll bars whose events are handled locally. Thus, any subframe that handles events must be sure to call <I>super.handleEvent</I> at the end of the <I>handleEvent</I> method. Also, the <I>OscopeFrame</I> has a main menu bar setting. It can be overridden by the subclass, although doing so will remove the main menu bar features.</P>
<I>OscopeFrame</I> extends the <I>PictFrame</I> class, which implements a feature in the main menu bar that enables the <I>OscopeFrame</I> to save a copy of itself as a pict file. The vector part of the pict file format is used so that the <I>OscopeFrame</I> has a vector output that can be edited with any draw program (including Microsoft Word&#146;s draw utility). Figure 5.9 is an example of a vector output generated by <I>OscopeFrame</I>. An example of the main menu bar that the OscopeFrame sets up is shown in Figure 5.10.
<P><A NAME="Fig9"></A><A HREF="javascript:displayWindow('images/05-09.jpg',184,56 )"><IMG SRC="images/05-09t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/05-09.jpg',184,56)"><FONT COLOR="#000077"><B>Figure 5.9</B></FONT></A>&nbsp;&nbsp;An example of the vector output from <I>OscopeFrame</I>.
</P>
<P><A NAME="Fig10"></A><A HREF="javascript:displayWindow('images/05-10.jpg',500,192 )"><IMG SRC="images/05-10t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/05-10.jpg',500,192)"><FONT COLOR="#000077"><B>Figure 5.10</B></FONT></A>&nbsp;&nbsp;The <I>OscopeFrame</I> Save menu permits the saving of vector output.
</P>
<P><I>OscopeFrame</I> implements the <I>DoubleDataProducer</I> interface. As a result, the programmer must implement the <I>getDoubleData</I> and <I>openDataFile</I> methods, or the subclass will be abstract. When <I>openDataFile</I> is invoked, the subclass must respond by invoking <I>setDoubleData</I>.</P>
<P>An example of the <I>OscopeFrame</I> is shown in Figure 5.11.</P>
<P><A NAME="Fig11"></A><A HREF="javascript:displayWindow('images/05-11.jpg',282,168 )"><IMG SRC="images/05-11t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/05-11.jpg',282,168)"><FONT COLOR="#000077"><B>Figure 5.11</B></FONT></A>&nbsp;&nbsp;The triangle wave in <I>OscopeFrame</I>.
</P>
<P>Scroll bar adjustments permit translation and scaling of the waveform in both the time domain and the amplitude domain. Another view of the triangle wave of Figure 5.11 is shown in Figure 5.12.
</P>
<P><A NAME="Fig12"></A><A HREF="javascript:displayWindow('images/05-12.jpg',320,179 )"><IMG SRC="images/05-12t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/05-12.jpg',320,179)"><FONT COLOR="#000077"><B>Figure 5.12</B></FONT></A>&nbsp;&nbsp;Another view of the triangle wave in the <I>OscopeFrame</I>.
</P>
<P>From Figure 5.12 we can visually measure ten 250-microsecond divisions cycles in the waveform. This corresponds to a frequency of 1/(2,500 micro seconds) = 400 Hz. This is exactly what was specified for the oscillator (a multiple of the 8,000-Hz sampling rate).
</P>
<H4 ALIGN="LEFT"><A NAME="Heading37"></A><FONT COLOR="#000077">Class Summary</FONT></H4>
<!-- CODE //-->
<PRE>
package lyon.audio;
import java.awt.*;
import futils.utils.Draw;
import futils.Futil;
import lyon.dclap.PictFrame;


public abstract class OscopeFrame
     extends PictFrame implements DoubleDataProducer {
public OscopeFrame(String title)
public void setDoubleData(double [] d)
public void setGridColor(Color c)
public void paint(Graphics g)
public boolean handleEvent(Event e)
}
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="240-243.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="248-253.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>

<hr width="90%" size="1" noshade><div align="center"><font face="Verdana,sans-serif" size="1">Copyright &copy; <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 + -