📄 278-282.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 Transform Recipes</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=6//-->
<!--PAGES=278-282//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="273-278.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="282-286.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<P>The input and output are highly correlated for both the DFT and FFT. The accuracy of these two radically different algorithms and implementations is surprising. Also, recall that the execution time for the DFT was benchmarked at 55 seconds. The FFT implementation is run in 0.178 seconds, a 308-fold improvement in speed. At 8,000 samples per second, the 2,048 samples represent 0.256 seconds of data on a limited data rate connection (such as a 28.8 kbps modem), the time to transmit the data is 2,048*8 bits /28,800 bits/sec = 0.56 seconds. Many dial-up users experience a slower connection than the maximum their modem permits. Thus, there is a window of opportunity for devising a real-time CODEC (In Java) that can perform FFT-based compression algorithms. An algorithm based on transform compression typically takes the original data, performs the forward transform, selects coefficients, quantizes, and then transmits. Data is recovered by performing an inverse transform on the coefficients. Very low bit rate voice compression (VLBRVC) is a rich and growing field that lies beyond the scope of this book. See <A HREF="http://www.bdti.com/faq/dsp_faq.htm">http://www.bdti.com/faq/dsp_faq.htm</A> for an FAQ that relates to this and other DSP topics.</P>
<H4 ALIGN="LEFT"><A NAME="Heading15"></A><FONT COLOR="#000077">Implementing the FFT.testFFT Method</FONT></H4>
<P>The following code shows how to use the <I>FFT</I> class to perform a forward and inverse FFT. The static nature of the <I>testFFT</I> method indicates that you can invoke it without making an instance of the <I>FFT</I> class.</P>
<P>Line 3 makes an instance of the <I>FFT</I> class without allocating any memory for the internal data structures. Thus, arrays are allocated and copied outside the <I>forwardFFT</I> methods, in part, because of the destructive nature of the in-place Cooley-Tukey FFT algorithm. The trade-off is that the programmer must keep track of the data that is being processed by <I>forwardFFT</I>. The alternative is to automatically copy arrays, perform the in-place <I>forwardFFT</I>, and then return the copies. Our findings indicate that the dynamic allocation of memory (particularly during image processing, discussed later in this book) can slow performance as much as 100-fold. The housekeeping chores required of the programmer are warranted by the gain in performance.</P>
<!-- CODE SNIP //-->
<PRE>
1. public static void testFFT() {
2. System.out.println(“Starting 1D FFT test...”);
3. FFT f = new FFT();
</PRE>
<!-- END CODE SNIP //-->
<P>Line 4 can be altered to any number of samples, <I>N</I>, but a large <I>N</I> will result in a large printout.</P>
<!-- CODE SNIP //-->
<PRE>
4. int N = 8;
5. int numBits = f.log2(N);
</PRE>
<!-- END CODE SNIP //-->
<P>Lines 6–8 set up the input data as a ramp that varies from 0 to <I>N</I>.</P>
<!-- CODE SNIP //-->
<PRE>
6. double x1[] = new double[N];
7. for (int j=0; j<N; j++)
8. x1[j] = j;
</PRE>
<!-- END CODE SNIP //-->
<P>Now the housekeeping. To keep copies of the original data, the result of the forward FFT, and the result of the inverse FFT, you must allocate four arrays. This case is unusual, because it requires you to keep all intermediate results for checking purposes. Normally, production code would not have to keep all intermediate results.
</P>
<!-- CODE SNIP //-->
<PRE>
9. double[] in_r = new double[N];
10. double[] in_i = new double[N];
</PRE>
<!-- END CODE SNIP //-->
<P>The <I>in_r</I> and <I>in_i</I> arrays are copies of the input data, with the imaginary component equal to zero. Real data (such as audio data) often has a zero imaginary component, which lets some algorithms save significant time. This requires a different FFT implementation.</P>
<!-- CODE SNIP //-->
<PRE>
11. double[] fftResult_r = new double[N];
12. double[] fftResult_i = new double[N];
13. // copy test signal.
14. in_r = arrayCopy(x1);
</PRE>
<!-- END CODE SNIP //-->
<P>Line 14 copies the input data into <I>in_r</I> and line 15 replaces <I>in_r</I> and <I>in_i</I> with the forward FFT results.</P>
<!-- CODE //-->
<PRE>
15. f.forwardFFT(in_r, in_i);
16. // Copy to new array because IFFT will
17. // destroy the FFT results.
18. fftResult_r = arrayCopy(in_r);
19. fftResult_i = arrayCopy(in_i);
20. f.reverseFFT(in_r, in_i);
21. System.out.println(“j\tx1[j]\tre[j]\tim[j]\tv[j]”);
22. for(int i=0; i<N; i++) {
23. System.out.println(
24. i + “\t” +
25. x1[i] + “\t” +
26. fftResult_r[i] + “\t” +
27. fftResult_i[i] + “\t” +
28. in_r[i]);
29. }
30. }
</PRE>
<!-- END CODE //-->
<H3><A NAME="Heading16"></A><FONT COLOR="#000077">PSD Computations</FONT></H3>
<P>To compute the PSD of the FFT output, we use the <I>computePSD</I> method in the <I>FFT</I> class. It squares the real and imaginary parts of the output of the FFT and places them in a new array.</P>
<!-- CODE //-->
<PRE>
public double [] computePSD () {
double [] psd = new double[r_data.length];
for (int k = 0; k < r_data.length; k++) {
psd[k] =
r_data[k] * r_data[k] +
i_data[k] * i_data[k];
}
return psd;
}
</PRE>
<!-- END CODE //-->
<P>To test the PSD, we use a private method in the <I>FFT</I> class called <I>testPSD</I>.</P>
<!-- CODE //-->
<PRE>
private static void testPSD() {
FFT f = new FFT();
int N = 8;
int numBits = f.log2(N);
double x1[] = new double[N];
for (int j=0; j<N; j++)
x1[j] = j;
double[] in_r = new double[N];
double[] in_i = new double[N];
// copy test signal.
in_r = arrayCopy(x1);
f.forwardFFT(in_r, in_i);
f.printArrays(“After the FFT”);
double psd[] = f.computePSD();
FFT.printArray(psd,”The psd”);
}
</PRE>
<!-- END CODE //-->
<P>Here is the output of the test method.
</P>
<!-- CODE //-->
<PRE>
After the FFT
[0]=(3.5,0)
[1]=(-0.5,1.20711)
[2]=(-0.5,0.5)
[3]=(-0.5,0.207107)
[4]=(-0.5,0)
[5]=(-0.500000,-0.207107)
[6]=(-0.500000,-0.5)
[7]=(-0.500000,-1.20711)
The psd
v[0]=12.25
v[1]=1.70711
v[2]=0.5
v[3]=0.292893
v[4]=0.25
v[5]=0.292893
v[6]=0.500000
v[7]=1.70711
Completed(0)
</PRE>
<!-- END CODE //-->
<P>You can readily verify that the PSD is the sum of the squares of the real and the imaginary parts of the spectra (see Figure 6.14).
</P>
<P><A NAME="Fig4"></A><A HREF="javascript:displayWindow('images/06-04.jpg',333,183 )"><IMG SRC="images/06-04t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/06-04.jpg',333,183)"><FONT COLOR="#000077"><B>Figure 6.4</B></FONT></A> The PSD of a 2,048 sampled waveform.</P>
<P>The implementation of the PSD computation and graphing is discussed next.
</P>
<H4 ALIGN="LEFT"><A NAME="Heading17"></A><FONT COLOR="#000077">Implementation of the Transforms in the AudioFrame</FONT></H4>
<P>In the <I>AudioFrame</I> class, we assume that we will be taking the FFT of a real signal. A real signal, such as audio, has no imaginary part; it has only a single value that varies from sample to sample. Thus, we construct a complex input to the FFT, setting the imaginary part of the input equal to zero.</P>
<P>When taking the IFFT, a signal that starts as real will end up as a real signal. The exception occurs when a spectral modification introduces terms that do not null out in the imaginary plane. This would happen, for example, if we added the spectra from real and imaginary signals.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="273-278.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="282-286.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 + -