﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客- 攀升·Uranus-随笔分类-嵌入式</title><link>http://www.cppblog.com/iuranus/category/4280.html</link><description>&lt;br&gt;&lt;font color="#ADFF2F"&gt;Something Different，Something New&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Sun, 19 Jul 2009 17:53:22 GMT</lastBuildDate><pubDate>Sun, 19 Jul 2009 17:53:22 GMT</pubDate><ttl>60</ttl><item><title>G1硬件配置(spec)</title><link>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Sun, 19 Jul 2009 14:27:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/90549.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/90549.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/90549.html</trackback:ping><description><![CDATA[<div>William, Windy, Steven都买了G1，对于数码狂人的我当然也想一个了，但怪就怪在Iphone没坏呀(上次在三楼掉下来也没问题)，唉，CC不会让我买的，所以还是等把，我这个坏了再买，赫赫赫赫.<br>&nbsp;<br>最近刚好也在做android移植工作，顺便把G1的spec贴出来，有兴趣的看看<br></div>
<div><span style="FONT-SIZE: 14px; COLOR: rgb(44,41,37); LINE-HEIGHT: 22px; FONT-FAMILY: Verdana; BORDER-COLLAPSE: collapse"><img height=486 alt="" src="http://www.cppblog.com/images/cppblog_com/iuranus/G1_W.jpg" width=600 border=0><br>Product Features &amp; Specifications Technical Specifications
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Operating System</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Google Android 1.0&nbsp; （最新的是2.0 donut）</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Network Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GSM/GPRS/EDGE/HSDPA, UMTS: 1700/2<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=100">100</span>MHz, GSM: 850/900/1800/1900MHz&nbsp; 中国也可以用3G哦</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Screen</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">3.2" HVGA (320 x 480px), 65k Color TFT</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Input Method</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Glass Capacitive&nbsp;<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=Touch">Touch</span>screen, Slide-out 5-row QWERTY Keyboard, Trackball navigation</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Wi-Fi</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">802.11b/g</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS navigation capabilities with Google Maps</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth v2.0+edr</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Camera</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">3.2MP Camera with auto focus</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Storage</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Internal 256MB Storage, External MicroSDHC Slot</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Connection Ports</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">ExtUSB 2.0 Hi-Speed (Mini-USB compatible for data-transfer, charger, and audio port)</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Physical Attributes</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Dimensions: 117.7mm x 55.7mm x 17.1mm, Weight: 158g with battery</td>
        </tr>
    </tbody>
</table>
<br style="LINE-HEIGHT: normal; WORD-WRAP: break-word">Media Support
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Audio Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Codecs: MP3/WMA/AAC+/MPEG4/WAV/MIDI/Real Audio/Ogg</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Video Support</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Codecs: H.264/3GPP/MPEG4</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Browser</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Google WebKit-based Browser, streaming video</td>
        </tr>
    </tbody>
</table>
<br style="LINE-HEIGHT: normal; WORD-WRAP: break-word"><br style="LINE-HEIGHT: normal; WORD-WRAP: break-word">Bill of Materials
<table class=t_table style="TABLE-LAYOUT: fixed; MARGIN-LEFT: 1px; WIDTH: 981px; LINE-HEIGHT: normal; BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; empty-cells: show" cellSpacing=0>
    <tbody style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Processor</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Qualcomm MSM7201A @ 528MHz</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Screen</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Sharp 3.2" HVGA LCD, 65k Color TFT</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Capacitive Sensor IC</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Synaptics 1007A</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Storage</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Samsung MCP - 256MB NAND Flash + 128MB DDR SDRAM</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">USB PHY</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">SMSC USB3316</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Wi-Fi</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Texas Instruments WL1251B</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Bluetooth</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Texas Instruments BRF6300</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">GPS</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Integrated into Baseband Processor</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Audio</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Integrated into Baseband Processor</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Accele<span class=t_tag style="CURSOR: pointer; LINE-HEIGHT: normal; BORDER-BOTTOM: rgb(255,0,0) 1px solid; WHITE-SPACE: nowrap; WORD-WRAP: break-word" onclick=tagshow(event) href="tag.php?name=rom">rom</span>eter</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Unknown</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">RF Transceiver</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Qualcomm RTR6285 Quad-band GSM/Dual-band UMTS</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Management</td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">PMIC: Qualcomm PM7540</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word"></td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Amp (Quad-band GSM): TriQuint Semiconductor TQS-7M5008</td>
        </tr>
        <tr style="LINE-HEIGHT: normal; WORD-WRAP: break-word">
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word"></td>
            <td style="PADDING-RIGHT: 4px; OVERFLOW-Y: hidden; PADDING-LEFT: 4px; OVERFLOW-X: hidden; PADDING-BOTTOM: 4px; FONT: 14px/1.6em Verdana, Helvetica, Arial, sans-serif; COLOR: rgb(44,41,37); PADDING-TOP: 4px; WORD-WRAP: break-word">Power Amp (UMTS-2100MHz): Avago ACPM-7381; (UMTS-1700MHz): Avago ACPM-7391</td>
        </tr>
    </tbody>
</table>
</span><br></div>
<img src ="http://www.cppblog.com/iuranus/aggbug/90549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-07-19 22:27 <a href="http://www.cppblog.com/iuranus/archive/2009/07/19/90549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)Linux音频编程指南</title><link>http://www.cppblog.com/iuranus/archive/2009/05/12/82689.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 12 May 2009 07:27:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/05/12/82689.html</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;源地址：<a href="http://www.ibm.com/developerworks/cn/linux/l-audio/index.html">http://www.ibm.com/developerworks/cn/linux/l-audio/index.html</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作者：&nbsp;&nbsp;&nbsp;肖文鹏<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虽然目前Linux的优势主要体现在网络服务方面，但事实上同样也有着非常丰富的媒体功能，本文就是以多媒体应用中最基本的声音为对象，介绍如何在Linux平台下开发实际的音频应用程序，同时还给出了一些常用的音频编程框架<a name=1><span class=atitle><br><br>一、数字音频</span></a></p>
<p>音频信号是一种连续变化的模拟信号，但计算机只能处理和记录二进制的数字信号，由自然音源得到的音频信号必须经过一定的变换，成为数字音频信号之后，才能送到计算机中作进一步的处理。</p>
<p>数字音频系统通过将声波的波型转换成一系列二进制数据，来实现对原始声音的重现，实现这一步骤的设备常被称为模/数转换器（A/D）。A/D转换器以每秒钟上万次的速率对声波进行采样，每个采样点都记录下了原始模拟声波在某一时刻的状态，通常称之为样本（sample），而每一秒钟所采样的数目则称为采样频率，通过将一串连续的样本连接起来，就可以在计算机中描述一段声音了。对于采样过程中的每一个样本来说，数字音频系统会分配一定存储位来记录声波的振幅，一般称之为采样分辩率或者采样精度，采样精度越高，声音还原时就会越细腻。</p>
<p>数字音频涉及到的概念非常多，对于在Linux 下进行音频编程的程序员来说，最重要的是理解声音数字化的两个关键步骤：采样和量化。采样就是每隔一定时间就读一次声音信号的幅度，而量化则是将采样得到的声音信号幅度转换为数字值，从本质上讲，采样是时间上的数字化，而量化则是幅度上的数字化。下面介绍几个在进行音频编程时经常需要用到的技术指标：</p>
<ol>
    <li><strong>采样频率</strong> <br>采样频率是指将模拟声音波形进行数字化时，每秒钟抽取声波幅度样本的次数。采样频率的选择应该遵循奈奎斯特（Harry Nyquist）采样理论：如果对某一模拟信号进行采样，则采样后可还原的最高信号频率只有采样频率的一半，或者说只要采样频率高于输入信号最高频率的两倍，就能从采样信号系列重构原始信号。正常人听觉的频率范围大约在20Hz~20kHz之间，根据奈奎斯特采样理论，为了保证声音不失真，采样频率应该在 40kHz左右。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等，如果采用更高的采样频率，还可以达到DVD的音质。
    <li><strong>量化位数</strong> <br>量化位数是对模拟音频信号的幅度进行数字化，它决定了模拟信号数字化以后的动态范围，常用的有8位、12位和16位。量化位越高，信号的动态范围越大，数字化后的音频信号就越可能接近原始信号，但所需要的存贮空间也越大。
    <li><strong>声道数</strong> <br>声道数是反映音频数字化质量的另一个重要因素，它有单声道和双声道之分。双声道又称为立体声，在硬件中有两条线路，音质和音色都要优于单声道，但数字化后占据的存储空间的大小要比单声道多一倍。 </li>
</ol>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=2><span class=atitle>二、声卡驱动</span></a></p>
<p>出于对安全性方面的考虑，Linux下的应用程序无法直接对声卡这类硬件设备进行操作，而是必须通过内核提供的驱动程序才能完成。在Linux上进行音频编程的本质就是要借助于驱动程序，来完成对声卡的各种操作。</p>
<p>对硬件的控制涉及到寄存器中各个比特位的操作，通常这是与设备直接相关并且对时序的要求非常严格，如果这些工作都交由应用程序员来负责，那么对声卡的编程将变得异常复杂而困难起来，驱动程序的作用正是要屏蔽硬件的这些底层细节，从而简化应用程序的编写。目前Linux下常用的声卡驱动程序主要有两种：OSS 和ALSA。</p>
<p>最早出现在Linux上的音频编程接口是OSS（Open Sound System），它由一套完整的内核驱动程序模块组成，可以为绝大多数声卡提供统一的编程接口。OSS出现的历史相对较长，这些内核模块中的一部分（OSS/Free）是与Linux内核源码共同免费发布的，另外一些则以二进制的形式由4Front Technologies公司提供。由于得到了商业公司的鼎力支持，OSS已经成为在Linux下进行音频编程的事实标准，支持OSS的应用程序能够在绝大多数声卡上工作良好。</p>
<p>虽然OSS已经非常成熟，但它毕竟是一个没有完全开放源代码的商业产品，ALSA（Advanced Linux Sound Architecture）恰好弥补了这一空白，它是在Linux下进行音频编程时另一个可供选择的声卡驱动程序。ALSA除了像OSS那样提供了一组内核驱动程序模块之外，还专门为简化应用程序的编写提供了相应的函数库，与OSS提供的基于ioctl的原始编程接口相比，ALSA函数库使用起来要更加方便一些。ALSA的主要特点有：</p>
<ul>
    <li>支持多种声卡设备
    <li>模块化的内核驱动程序
    <li>支持SMP和多线程
    <li>提供应用开发函数库
    <li>兼容OSS应用程序 </li>
</ul>
<p>ALSA 和OSS最大的不同之处在于ALSA是由志愿者维护的自由项目，而OSS则是由公司提供的商业产品，因此在对硬件的适应程度上OSS要优于ALSA，它能够支持的声卡种类更多。ALSA虽然不及OSS运用得广泛，但却具有更加友好的编程接口，并且完全兼容于OSS，对应用程序员来讲无疑是一个更佳的选择。</p>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=3><span class=atitle>三、编程接口</span></a></p>
<p>如何对各种音频设备进行操作是在Linux上进行音频编程的关键，通过内核提供的一组系统调用，应用程序能够访问声卡驱动程序提供的各种音频设备接口，这是在Linux下进行音频编程最简单也是最直接的方法。</p>
<p><a name=N10090><span class=smalltitle>3.1 访问音频设备</span></a></p>
<p>无论是OSS还是ALSA，都是以内核驱动程序的形式运行在Linux内核空间中的，应用程序要想访问声卡这一硬件设备，必须借助于Linux内核所提供的系统调用（system call）。从程序员的角度来说，对声卡的操作在很大程度上等同于对磁盘文件的操作：首先使用open系统调用建立起与硬件间的联系，此时返回的文件描述符将作为随后操作的标识；接着使用read系统调用从设备接收数据，或者使用write系统调用向设备写入数据，而其它所有不符合读/写这一基本模式的操作都可以由ioctl系统调用来完成；最后，使用close系统调用告诉Linux内核不会再对该设备做进一步的处理。</p>
<ul>
    <li><strong>open系统调用</strong> <br>系统调用open可以获得对声卡的访问权，同时还能为随后的系统调用做好准备，其函数原型如下所示：
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>int open(const char *pathname, int flags, int mode);
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>参数pathname是将要被打开的设备文件的名称，对于声卡来讲一般是/dev/dsp。参数flags用来指明应该以什么方式打开设备文件，它可以是 O_RDONLY、O_WRONLY或者O_RDWR，分别表示以只读、只写或者读写的方式打开设备文件；参数mode通常是可选的，它只有在指定的设备文件不存在时才会用到，指明新创建的文件应该具有怎样的权限。 <br>如果open系统调用能够成功完成，它将返回一个正整数作为文件标识符，在随后的系统调用中需要用到该标识符。如果open系统调用失败，它将返回-1，同时还会设置全局变量errno，指明是什么原因导致了错误的发生。
    <li><strong>read系统调用</strong> <br>系统调用read用来从声卡读取数据，其函数原型如下所示：
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>int read(int fd, char *buf, size_t count);
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>参数fd是设备文件的标识符，它是通过之前的open系统调用获得的；参数buf是指向缓冲区的字符指针，它用来保存从声卡获得的数据；参数count则用来限定从声卡获得的最大字节数。如果read系统调用成功完成，它将返回从声卡实际读取的字节数，通常情况会比count的值要小一些；如果read系统调用失败，它将返回-1，同时还会设置全局变量errno，来指明是什么原因导致了错误的发生。
    <li><strong>write系统调用</strong> <br>系统调用write用来向声卡写入数据，其函数原型如下所示：
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>size_t write(int fd, const char *buf, size_t count);
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>系统调用write和系统调用read在很大程度是类似的，差别只在于write是向声卡写入数据，而read则是从声卡读入数据。参数fd同样是设备文件的标识符，它也是通过之前的open系统调用获得的；参数buf是指向缓冲区的字符指针，它保存着即将向声卡写入的数据；参数count则用来限定向声卡写入的最大字节数。 <br>如果write系统调用成功完成，它将返回向声卡实际写入的字节数；如果read系统调用失败，它将返回-1，同时还会设置全局变量errno，来指明是什么原因导致了错误的发生。无论是read还是write，一旦调用之后Linux内核就会阻塞当前应用程序，直到数据成功地从声卡读出或者写入为止。
    <li><strong>ioctl系统调用</strong> <br>系统调用ioctl可以对声卡进行控制，凡是对设备文件的操作不符合读/写基本模式的，都是通过ioctl来完成的，它可以影响设备的行为，或者返回设备的状态，其函数原型如下所示： <br>
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>int ioctl(int fd, int request, ...);
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>参数fd是设备文件的标识符，它是在设备打开时获得的；如果设备比较复杂，那么对它的控制请求相应地也会有很多种，参数request的目的就是用来区分不同的控制请求；通常说来，在对设备进行控制时还需要有其它参数，这要根据不同的控制请求才能确定，并且可能是与硬件设备直接相关的。
    <li><strong>close系统调用</strong> <br>当应用程序使用完声卡之后，需要用close系统调用将其关闭，以便及时释放占用的硬件资源，其函数原型如下所示：
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>int close(int fd);
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>参数fd是设备文件的标识符，它是在设备打开时获得的。一旦应用程序调用了close系统调用，Linux内核就会释放与之相关的各种资源，因此建议在不需要的时候尽量及时关闭已经打开的设备。 </li>
</ul>
<p><a name=N100E3><span class=smalltitle>3.2 音频设备文件</span></a></p>
<p>对于Linux应用程序员来讲，音频编程接口实际上就是一组音频设备文件，通过它们可以从声卡读取数据，或者向声卡写入数据，并且能够对声卡进行控制，设置采样频率和声道数目等等。</p>
<ul>
    <li><strong>/dev/sndstat</strong> <br>设备文件/dev/sndstat是声卡驱动程序提供的最简单的接口，通常它是一个只读文件，作用也仅仅只限于汇报声卡的当前状态。一般说来，/dev/sndstat是提供给最终用户来检测声卡的，不宜用于程序当中，因为所有的信息都可以通过ioctl系统调用来获得。 Linux提供的cat命令可以很方便地从/dev/sndstat获得声卡的当前状态： [xiaowp@linuxgam sound]$ cat /dev/sndstat
    <li><strong>/dev/dsp</strong> <br>
    <p>声卡驱动程序提供的/dev/dsp是用于数字采样（sampling）和数字录音（recording）的设备文件，它对于Linux下的音频编程来讲非常重要：向该设备写数据即意味着激活声卡上的D/A转换器进行放音，而向该设备读数据则意味着激活声卡上的A/D转换器进行录音。目前许多声卡都提供有多个数字采样设备，它们在Linux下可以通过/dev/dsp1等设备文件进行访问。</p>
    <p>DSP是数字信号处理器（Digital Signal Processor）的简称，它是用来进行数字信号处理的特殊芯片，声卡使用它来实现模拟信号和数字信号的转换。声卡中的DSP设备实际上包含两个组成部分：在以只读方式打开时，能够使用A/D转换器进行声音的输入；而在以只写方式打开时，则能够使用D/A转换器进行声音的输出。严格说来，Linux下的应用程序要么以只读方式打开/dev/dsp输入声音，要么以只写方式打开/dev/dsp输出声音，但事实上某些声卡驱动程序仍允许以读写的方式打开 /dev/dsp，以便同时进行声音的输入和输出，这对于某些应用场合（如IP电话）来讲是非常关键的。</p>
    <p>在从 DSP设备读取数据时，从声卡输入的模拟信号经过A/D转换器变成数字采样后的样本（sample），保存在声卡驱动程序的内核缓冲区中，当应用程序通过 read系统调用从声卡读取数据时，保存在内核缓冲区中的数字采样结果将被复制到应用程序所指定的用户缓冲区中。需要指出的是，声卡采样频率是由内核中的驱动程序所决定的，而不取决于应用程序从声卡读取数据的速度。如果应用程序读取数据的速度过慢，以致低于声卡的采样频率，那么多余的数据将会被丢弃；如果读取数据的速度过快，以致高于声卡的采样频率，那么声卡驱动程序将会阻塞那些请求数据的应用程序，直到新的数据到来为止。</p>
    <p>在向DSP设备写入数据时，数字信号会经过D/A转换器变成模拟信号，然后产生出声音。应用程序写入数据的速度同样应该与声卡的采样频率相匹配，否则过慢的话会产生声音暂停或者停顿的现象，过快的话又会被内核中的声卡驱动程序阻塞，直到硬件有能力处理新的数据为止。与其它设备有所不同，声卡通常不会支持非阻塞（non-blocking）的I/O操作。</p>
    <p>无论是从声卡读取数据，或是向声卡写入数据，事实上都具有特定的格式（format），默认为8位无符号数据、单声道、8KHz采样率，如果默认值无法达到要求，可以通过ioctl系统调用来改变它们。通常说来，在应用程序中打开设备文件/dev/dsp之后，接下去就应该为其设置恰当的格式，然后才能从声卡读取或者写入数据。</p>
    <li><strong>/dev/audio</strong> <br>/dev/audio类似于/dev/dsp，它兼容于Sun工作站上的音频设备，使用的是mu-law编码方式。如果声卡驱动程序提供了对/dev /audio的支持，那么在Linux上就可以通过cat命令，来播放在Sun工作站上用mu-law进行编码的音频文件：
    <table cellSpacing=0 cellPadding=0 width="70%" border=0>
        <tbody>
            <tr>
                <td class=code-outline>
                <pre class=displaycode>[xiaowp@linuxgam sound]$ cat audio.au &gt; /dev/audio
                </pre>
                </td>
            </tr>
        </tbody>
    </table>
    <br>由于设备文件/dev/audio主要出于对兼容性的考虑，所以在新开发的应用程序中最好不要尝试用它，而应该以/dev/dsp进行替代。对于应用程序来说，同一时刻只能使用/dev/audio或者/dev/dsp其中之一，因为它们是相同硬件的不同软件接口。
    <li><strong>/dev/mixer</strong> <br>在声卡的硬件电路中，混音器（mixer）是一个很重要的组成部分，它的作用是将多个信号组合或者叠加在一起，对于不同的声卡来说，其混音器的作用可能各不相同。运行在Linux内核中的声卡驱动程序一般都会提供/dev/mixer这一设备文件，它是应用程序对混音器进行操作的软件接口。混音器电路通常由两个部分组成：输入混音器（input mixer）和输出混音器（output mixer）。 <br>输入混音器负责从多个不同的信号源接收模拟信号，这些信号源有时也被称为混音通道或者混音设备。模拟信号通过增益控制器和由软件控制的音量调节器后，在不同的混音通道中进行级别（level）调制，然后被送到输入混音器中进行声音的合成。混音器上的电子开关可以控制哪些通道中有信号与混音器相连，有些声卡只允许连接一个混音通道作为录音的音源，而有些声卡则允许对混音通道做任意的连接。经过输入混音器处理后的信号仍然为模拟信号，它们将被送到A/D转换器进行数字化处理。 <br>输出混音器的工作原理与输入混音器类似，同样也有多个信号源与混音器相连，并且事先都经过了增益调节。当输出混音器对所有的模拟信号进行了混合之后，通常还会有一个总控增益调节器来控制输出声音的大小，此外还有一些音调控制器来调节输出声音的音调。经过输出混音器处理后的信号也是模拟信号，它们最终会被送给喇叭或者其它的模拟输出设备。对混音器的编程包括如何设置增益控制器的级别，以及怎样在不同的音源间进行切换，这些操作通常来讲是不连续的，而且不会像录音或者放音那样需要占用大量的计算机资源。由于混音器的操作不符合典型的读/写操作模式，因此除了open和close两个系统调用之外，大部分的操作都是通过ioctl系统调用来完成的。与/dev/dsp不同，/dev/mixer允许多个应用程序同时访问，并且混音器的设置值会一直保持到对应的设备文件被关闭为止。 <br>为了简化应用程序的设计，Linux上的声卡驱动程序大多都支持将混音器的ioctl操作直接应用到声音设备上，也就是说如果已经打开了/dev /dsp，那么就不用再打开/dev/mixer来对混音器进行操作，而是可以直接用打开/dev/dsp时得到的文件标识符来设置混音器。
    <li><strong>/dev/sequencer</strong> <br>目前大多数声卡驱动程序还会提供/dev/sequencer这一设备文件，用来对声卡内建的波表合成器进行操作，或者对MIDI总线上的乐器进行控制，一般只用于计算机音乐软件中。 </li>
</ul>
<br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br></td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=4><span class=atitle>四、应用框架</span></a></p>
<p>在Linux下进行音频编程时，重点在于如何正确地操作声卡驱动程序所提供的各种设备文件，由于涉及到的概念和因素比较多，所以遵循一个通用的框架无疑将有助于简化应用程序的设计。</p>
<p><a name=N1013A><span class=smalltitle>4.1 DSP编程</span></a></p>
<p>对声卡进行编程时首先要做的是打开与之对应的硬件设备，这是借助于open系统调用来完成的，并且一般情况下使用的是/dev/dsp文件。采用何种模式对声卡进行操作也必须在打开设备时指定，对于不支持全双工的声卡来说，应该使用只读或者只写的方式打开，只有那些支持全双工的声卡，才能以读写的方式打开，并且还要依赖于驱动程序的具体实现。Linux允许应用程序多次打开或者关闭与声卡对应的设备文件，从而能够很方便地在放音状态和录音状态之间进行切换，建议在进行音频编程时只要有可能就尽量使用只读或者只写的方式打开设备文件，因为这样不仅能够充分利用声卡的硬件资源，而且还有利于驱动程序的优化。下面的代码示范了如何以只写方式打开声卡进行放音（playback）操作：</p>
<table cellSpacing=0 cellPadding=0 width="70%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int handle = open("/dev/dsp", O_WRONLY);
            if (handle == -1) {
            perror("open /dev/dsp");
            return -1;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>运行在Linux内核中的声卡驱动程序专门维护了一个缓冲区，其大小会影响到放音和录音时的效果，使用ioctl系统调用可以对它的尺寸进行恰当的设置。调节驱动程序中缓冲区大小的操作不是必须的，如果没有特殊的要求，一般采用默认的缓冲区大小也就可以了。但需要注意的是，缓冲区大小的设置通常应紧跟在设备文件打开之后，这是因为对声卡的其它操作有可能会导致驱动程序无法再修改其缓冲区的大小。下面的代码示范了怎样设置声卡驱动程序中的内核缓冲区的大小：</p>
<table cellSpacing=0 cellPadding=0 width="70%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int setting = 0xnnnnssss;
            int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &amp;setting);
            if (result == -1) {
            perror("ioctl buffer size");
            return -1;
            }
            // 检查设置值的正确性
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>在设置缓冲区大小时，参数setting实际上由两部分组成，其低16位标明缓冲区的尺寸，相应的计算公式为buffer_size = 2^ssss，即若参数setting低16位的值为16，那么相应的缓冲区的大小会被设置为65536字节。参数setting的高16位则用来标明分片（fragment）的最大序号，它的取值范围从2一直到0x7FFF，其中0x7FFF表示没有任何限制。</p>
<p>接下来要做的是设置声卡工作时的声道（channel）数目，根据硬件设备和驱动程序的具体情况，可以将其设置为0（单声道，mono）或者1（立体声，stereo）。下面的代码示范了应该怎样设置声道数目：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int channels = 0; // 0=mono 1=stereo
            int result = ioctl(handle, SNDCTL_DSP_STEREO, &amp;channels);
            if ( result == -1 ) {
            perror("ioctl channel number");
            return -1;
            }
            if (channels != 0) {
            // 只支持立体声
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>采样格式和采样频率是在进行音频编程时需要考虑的另一个问题，声卡支持的所有采样格式可以在头文件soundcard.h中找到，而通过ioctl系统调用则可以很方便地更改当前所使用的采样格式。下面的代码示范了如何设置声卡的采样格式：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int format = AFMT_U8;
            int result = ioctl(handle, SNDCTL_DSP_SETFMT, &amp;format);
            if ( result == -1 ) {
            perror("ioctl sample format");
            return -1;
            }
            // 检查设置值的正确性
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>声卡采样频率的设置也非常容易，只需在调用 ioctl时将第二个参数的值设置为SNDCTL_DSP_SPEED，同时在第三个参数中指定采样频率的数值就行了。对于大多数声卡来说，其支持的采样频率范围一般为5kHz到44.1kHz或者48kHz，但并不意味着该范围内的所有频率都会被硬件支持，在Linux下进行音频编程时最常用到的几种采样频率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。下面的代码示范了如何设置声卡的采样频率：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int rate = 22050;
            int result = ioctl(handle, SNDCTL_DSP_SPEED, &amp;rate);
            if ( result == -1 ) {
            perror("ioctl sample format");
            return -1;
            }
            // 检查设置值的正确性
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><a name=N10168><span class=smalltitle>4.2 Mixer编程</span></a></p>
<p>声卡上的混音器由多个混音通道组成，它们可以通过驱动程序提供的设备文件/dev/mixer进行编程。对混音器的操作是通过ioctl系统调用来完成的，并且所有控制命令都由SOUND_MIXER或者MIXER开头，表1列出了常用的几个混音器控制命令：</p>
<table width="60%" border=1>
    <tbody>
        <tr>
            <td>名 称</td>
            <td>作 用</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_VOLUME</td>
            <td>主音量调节</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_BASS</td>
            <td>低音控制</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_TREBLE</td>
            <td>高音控制</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_SYNTH</td>
            <td>FM合成器</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_PCM</td>
            <td>主D/A转换器</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_SPEAKER</td>
            <td>PC喇叭</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_LINE</td>
            <td>音频线输入</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_MIC</td>
            <td>麦克风输入</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_CD</td>
            <td>CD输入</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_IMIX</td>
            <td>回放音量</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_ALTPCM</td>
            <td>从D/A 转换器</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_RECLEV</td>
            <td>录音音量</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_IGAIN</td>
            <td>输入增益</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_OGAIN</td>
            <td>输出增益</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_LINE1</td>
            <td>声卡的第1输入</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_LINE2</td>
            <td>声卡的第2输入</td>
        </tr>
        <tr>
            <td>SOUND_MIXER_LINE3</td>
            <td>声卡的第3输入</td>
        </tr>
    </tbody>
</table>
<br>表1 混音器命令
<p>对声卡的输入增益和输出增益进行调节是混音器的一个主要作用，目前大部分声卡采用的是8位或者16位的增益控制器，但作为程序员来讲并不需要关心这些，因为声卡驱动程序会负责将它们变换成百分比的形式，也就是说无论是输入增益还是输出增益，其取值范围都是从0到100。在进行混音器编程时，可以使用 SOUND_MIXER_READ宏来读取混音通道的增益大小，例如在获取麦克风的输入增益时，可以使用如下的代码：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int vol;
            ioctl(fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &amp;vol);
            printf("Mic gain is at %d %%\n", vol);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>对于只有一个混音通道的单声道设备来说，返回的增益大小保存在低位字节中。而对于支持多个混音通道的双声道设备来说，返回的增益大小实际上包括两个部分，分别代表左、右两个声道的值，其中低位字节保存左声道的音量，而高位字节则保存右声道的音量。下面的代码可以从返回值中依次提取左右声道的增益大小：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>int left, right;
            left = vol &amp; 0xff;
            right = (vol &amp; 0xff00) &gt;&gt; 8;
            printf("Left gain is %d %%, Right gain is %d %%\n", left, right);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>类似地，如果想设置混音通道的增益大小，则可以通过SOUND_MIXER_WRITE宏来实现，此时遵循的原则与获取增益值时的原则基本相同，例如下面的语句可以用来设置麦克风的输入增益：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>vol = (right &lt;&lt; 8) + left;
            ioctl(fd, SOUND_MIXER_WRITE(SOUND_MIXER_MIC), &amp;vol);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>在编写实用的音频程序时，混音器是在涉及到兼容性时需要重点考虑的一个对象，这是因为不同的声卡所提供的混音器资源是有所区别的。声卡驱动程序提供了多个ioctl系统调用来获得混音器的信息，它们通常返回一个整型的位掩码（bitmask），其中每一位分别代表一个特定的混音通道，如果相应的位为1，则说明与之对应的混音通道是可用的。例如通过 SOUND_MIXER_READ_DEVMASK返回的位掩码，可以查询出能够被声卡支持的每一个混音通道，而通过 SOUND_MIXER_READ_RECMAS返回的位掩码，则可以查询出能够被当作录音源的每一个通道。下面的代码可以用来检查CD输入是否是一个有效的混音通道：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>  ioctl(fd, SOUND_MIXER_READ_DEVMASK, &amp;devmask);
            if (devmask &amp; SOUND_MIXER_CD)
            printf("The CD input is supported");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>如果进一步还想知道其是否是一个有效的录音源，则可以使用如下语句：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>ioctl(fd, SOUND_MIXER_READ_RECMASK, &amp;recmask);
            if (recmask &amp; SOUND_MIXER_CD)
            printf("The CD input can be a recording source");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>目前大多数声卡提供多个录音源，通过 SOUND_MIXER_READ_RECSRC可以查询出当前正在使用的录音源，同一时刻能够使用几个录音源是由声卡硬件决定的。类似地，使用 SOUND_MIXER_WRITE_RECSRC可以设置声卡当前使用的录音源，例如下面的代码可以将CD输入作为声卡的录音源使用：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>devmask = SOUND_MIXER_CD;
            ioctl(fd, SOUND_MIXER_WRITE_DEVMASK, &amp;devmask);
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>此外，所有的混音通道都有单声道和双声道的区别，如果需要知道哪些混音通道提供了对立体声的支持，可以通过SOUND_MIXER_READ_STEREODEVS来获得。</p>
<p><a name=N10247><span class=smalltitle>4.3 音频录放框架</span></a></p>
<p>下面给出一个利用声卡上的DSP设备进行声音录制和回放的基本框架，它的功能是先录制几秒种音频数据，将其存放在内存缓冲区中，然后再进行回放，其所有的功能都是通过读写/dev/dsp设备文件来完成的：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>/*
            * sound.c
            */
            #include &lt;unistd.h&gt;
            #include &lt;fcntl.h&gt;
            #include &lt;sys/types.h&gt;
            #include &lt;sys/ioctl.h&gt;
            #include &lt;stdlib.h&gt;
            #include &lt;stdio.h&gt;
            #include &lt;linux/soundcard.h&gt;
            #define LENGTH 3    /* 存储秒数 */
            #define RATE 8000   /* 采样频率 */
            #define SIZE 8      /* 量化位数 */
            #define CHANNELS 1  /* 声道数目 */
            /* 用于保存数字音频数据的内存缓冲区 */
            unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/8];
            int main()
            {
            int fd;	/* 声音设备的文件描述符 */
            int arg;	/* 用于ioctl调用的参数 */
            int status;   /* 系统调用的返回值 */
            /* 打开声音设备 */
            fd = open("/dev/dsp", O_RDWR);
            if (fd &lt; 0) {
            perror("open of /dev/dsp failed");
            exit(1);
            }
            /* 设置采样时的量化位数 */
            arg = SIZE;
            status = ioctl(fd, SOUND_PCM_WRITE_BITS, &amp;arg);
            if (status == -1)
            perror("SOUND_PCM_WRITE_BITS ioctl failed");
            if (arg != SIZE)
            perror("unable to set sample size");
            /* 设置采样时的声道数目 */
            arg = CHANNELS;
            status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &amp;arg);
            if (status == -1)
            perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
            if (arg != CHANNELS)
            perror("unable to set number of channels");
            /* 设置采样时的采样频率 */
            arg = RATE;
            status = ioctl(fd, SOUND_PCM_WRITE_RATE, &amp;arg);
            if (status == -1)
            perror("SOUND_PCM_WRITE_WRITE ioctl failed");
            /* 循环，直到按下Control-C */
            while (1) {
            printf("Say something:\n");
            status = read(fd, buf, sizeof(buf)); /* 录音 */
            if (status != sizeof(buf))
            perror("read wrong number of bytes");
            printf("You said:\n");
            status = write(fd, buf, sizeof(buf)); /* 回放 */
            if (status != sizeof(buf))
            perror("wrote wrong number of bytes");
            /* 在继续录音前等待回放结束 */
            status = ioctl(fd, SOUND_PCM_SYNC, 0);
            if (status == -1)
            perror("SOUND_PCM_SYNC ioctl failed");
            }
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p><a name=N10254><span class=smalltitle>4.4 混音器框架</span></a></p>
<p>下面再给出一个对混音器进行编程的基本框架，利用它可以对各种混音通道的增益进行调节，其所有的功能都是通过读写/dev/mixer设备文件来完成的：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>/*
            * mixer.c
            */
            #include &lt;unistd.h&gt;
            #include &lt;stdlib.h&gt;
            #include &lt;stdio.h&gt;
            #include &lt;sys/ioctl.h&gt;
            #include &lt;fcntl.h&gt;
            #include &lt;linux/soundcard.h&gt;
            /* 用来存储所有可用混音设备的名称 */
            const char *sound_device_names[] = SOUND_DEVICE_NAMES;
            int fd;                  /* 混音设备所对应的文件描述符 */
            int devmask, stereodevs; /* 混音器信息对应的位图掩码 */
            char *name;
            /* 显示命令的使用方法及所有可用的混音设备 */
            void usage()
            {
            int i;
            fprintf(stderr, "usage: %s &lt;device&gt; &lt;left-gain%%&gt; &lt;right-gain%%&gt;\n"
            "       %s &lt;device&gt; &lt;gain%%&gt;\n\n"
            "Where &lt;device&gt; is one of:\n", name, name);
            for (i = 0 ; i &lt; SOUND_MIXER_NRDEVICES ; i++)
            if ((1 &lt;&lt; i) &amp; devmask) /* 只显示有效的混音设备 */
            fprintf(stderr, "%s ", sound_device_names[i]);
            fprintf(stderr, "\n");
            exit(1);
            }
            int main(int argc, char *argv[])
            {
            int left, right, level;  /* 增益设置 */
            int status;              /* 系统调用的返回值 */
            int device;              /* 选用的混音设备 */
            char *dev;               /* 混音设备的名称 */
            int i;
            name = argv[0];
            /* 以只读方式打开混音设备 */
            fd = open("/dev/mixer", O_RDONLY);
            if (fd == -1) {
            perror("unable to open /dev/mixer");
            exit(1);
            }
            /* 获得所需要的信息 */
            status = ioctl(fd, SOUND_MIXER_READ_DEVMASK, &amp;devmask);
            if (status == -1)
            perror("SOUND_MIXER_READ_DEVMASK ioctl failed");
            status = ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &amp;stereodevs);
            if (status == -1)
            perror("SOUND_MIXER_READ_STEREODEVS ioctl failed");
            /* 检查用户输入 */
            if (argc != 3 &amp;&amp; argc != 4)
            usage();
            /* 保存用户输入的混音器名称 */
            dev = argv[1];
            /* 确定即将用到的混音设备 */
            for (i = 0 ; i &lt; SOUND_MIXER_NRDEVICES ; i++)
            if (((1 &lt;&lt; i) &amp; devmask) &amp;&amp; !strcmp(dev, sound_device_names[i]))
            break;
            if (i == SOUND_MIXER_NRDEVICES) { /* 没有找到匹配项 */
            fprintf(stderr, "%s is not a valid mixer device\n", dev);
            usage();
            }
            /* 查找到有效的混音设备 */
            device = i;
            /* 获取增益值 */
            if (argc == 4) {
            /* 左、右声道均给定 */
            left  = atoi(argv[2]);
            right = atoi(argv[3]);
            } else {
            /* 左、右声道设为相等 */
            left  = atoi(argv[2]);
            right = atoi(argv[2]);
            }
            /* 对非立体声设备给出警告信息 */
            if ((left != right) &amp;&amp; !((1 &lt;&lt; i) &amp; stereodevs)) {
            fprintf(stderr, "warning: %s is not a stereo device\n", dev);
            }
            /* 将两个声道的值合到同一变量中 */
            level = (right &lt;&lt; 8) + left;
            /* 设置增益 */
            status = ioctl(fd, MIXER_WRITE(device), &amp;level);
            if (status == -1) {
            perror("MIXER_WRITE ioctl failed");
            exit(1);
            }
            /* 获得从驱动返回的左右声道的增益 */
            left  = level &amp; 0xff;
            right = (level &amp; 0xff00) &gt;&gt; 8;
            /* 显示实际设置的增益 */
            fprintf(stderr, "%s gain set to %d%% / %d%%\n", dev, left, right);
            /* 关闭混音设备 */
            close(fd);
            return 0;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>编译好上面的程序之后，先不带任何参数执行一遍，此时会列出声卡上所有可用的混音通道：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>[xiaowp@linuxgam sound]$ ./mixer
            usage: ./mixer &lt;device&gt; &lt;left-gain%&gt; &lt;right-gain%&gt;
            ./mixer &lt;device&gt; &lt;gain%&gt;
            Where &lt;device&gt; is one of:
            vol pcm speaker line mic cd igain line1 phin video
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br>
<p>之后就可以很方便地设置各个混音通道的增益大小了，例如下面的命令就能够将CD输入的左、右声道的增益分别设置为80%和90%：</p>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td class=code-outline>
            <pre class=displaycode>[xiaowp@linuxgam sound]$ ./mixer cd 80 90
            cd gain set to 80% / 90%
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td><img height=1 alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%"><br><img height=6 alt="" src="http://www.ibm.com/i/c.gif" width=8 border=0></td>
        </tr>
    </tbody>
</table>
<table class=no-print cellSpacing=0 cellPadding=0 align=right>
    <tbody>
        <tr align=right>
            <td><img height=4 alt="" src="http://www.ibm.com/i/c.gif" width="100%"><br>
            <table cellSpacing=0 cellPadding=0 border=0>
                <tbody>
                    <tr>
                        <td vAlign=center><img height=16 alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width=16 border=0><br></td>
                        <td vAlign=top align=right><a class=fbox href="http://www.ibm.com/developerworks/cn/linux/l-audio/index.html#main"><strong><u><font color=#0000ff>回页首</font></u></strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br><br>
<p><a name=5><span class=atitle>五、小结</span></a></p>
<p>随着Linux平台下多媒体应用的逐渐深入，需要用到数字音频的场合必将越来越广泛。虽然数字音频牵涉到的概念非常多，但在Linux下进行最基本的音频编程却并不十分复杂，关键是掌握如何与OSS或者ALSA这类声卡驱动程序进行交互，以及如何充分利用它们提供的各种功能，熟悉一些最基本的音频编程框架和模式对初学者来讲大有裨益。</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/82689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-05-12 15:27 <a href="http://www.cppblog.com/iuranus/archive/2009/05/12/82689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于嵌入式设备用户体验的一些认识</title><link>http://www.cppblog.com/iuranus/archive/2009/04/22/80718.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Wed, 22 Apr 2009 06:01:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2009/04/22/80718.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/80718.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2009/04/22/80718.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/80718.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/80718.html</trackback:ping><description><![CDATA[<p>1. Gesture,&nbsp;<br><br>&nbsp;a. 与具体应用配合用，Iphone上面看图<br>&nbsp;b. 与共通的独立应用，比如问号叫帮助，Copy&amp;Paste</p>
<p>2. Graphic<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a. 整体布局中，用户关心的数据越清晰越好（大，多），UIWidget显示的越少越好，只有必要的，配合Gesture完成。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b. 画面的切换，转场动画<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b1. 不要过于参考PC上的表现形式：(Windows关闭点X, Mac OS也是X, Window CE6 关闭点X，但Iphone就是全部Home键<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b2. 符合人感觉的潜意识：当快速drag画面时，画面应该快速闪过，慢慢drag时画面应该慢慢闪过，迁移速度静止-&gt;匀加速－&gt;匀减速－&gt;静止<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c. 按键的特效<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c1. 亮，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c2. 图形关系小Force feedback：3月28 Samsung Anycall Haptic<br><br>3. 与硬件结合<br>&nbsp;&nbsp; 陀螺仪<br>&nbsp;&nbsp; Gsense<br>&nbsp;&nbsp; 热传感</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/80718.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2009-04-22 14:01 <a href="http://www.cppblog.com/iuranus/archive/2009/04/22/80718.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iphone SDK &amp; gPhone SDK Android</title><link>http://www.cppblog.com/iuranus/archive/2008/09/25/62742.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Thu, 25 Sep 2008 02:07:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2008/09/25/62742.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/62742.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2008/09/25/62742.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/62742.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/62742.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:       当前手机开发平台越来越多，最近android平台又被炒到空前的高度，大家都是怎么看待这些平台的，以下是我的一些想法。<br>    最近几个博友bob，小舟，Yang Jungang，jawfneo都提了一些关于iphone开发的问题。但由于我最近一直都在忙工作的事，一直都没有回，也没有更新blog，请见谅。那么我再来说说关于SDK的事吧。&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2008/09/25/62742.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/62742.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2008-09-25 10:07 <a href="http://www.cppblog.com/iuranus/archive/2008/09/25/62742.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Iphone开发-让我开心让我烦</title><link>http://www.cppblog.com/iuranus/archive/2008/04/01/45949.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 01 Apr 2008 12:55:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2008/04/01/45949.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/45949.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2008/04/01/45949.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/45949.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/45949.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码昨天release给客户，终于一个阶段结束了，将近三个月没写blog了，真的太忙了，除了忙于工作，生活以外，其实我还在研究Iphone的开发。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iphone入手已经两三个月了，从中我看到了iphone OS的很多优点，确实觉得这个手机不管从外形上还是内部application都是那么的完美，所以衍生了想在iphone os上开发的念头。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 研习的cocoa的基本开发框架，学习了objective c的基本语法，在Iphone sdk发布的那天莫名的开心和激动，但是最后还是不能如愿以偿，只有一个破解的sdk toolchain编译过的hello world在Iphone上恶心得运行着。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iphone sdk要运行在基于intel 酷睿2，操作系统是Mac OS leopard 10.5.2以上的Mac上，尝试安装leopard在家的电脑和本子上都因各种原因而失败，那就算我有mac了，其实也不行，因为sdk写的代码只能在iphone&nbsp;固件 2.0上运行， 2.0估计会在今年6月发布，所以一切都是那么的不确定，这也不断的打断我结束开发Iphone app的念头，但今天看到一个往日同窗的blog让我又重新燃起了奋斗之火。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;现在我已经是某iphone开发群的群主，某网站也曾经让我加入他们将要成立的iphone专栏，认识了很多对Iphone开发狂热的技术人员， 其实我已经有一些结果了，我真的该把这件事做好！</p>
<img src ="http://www.cppblog.com/iuranus/aggbug/45949.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2008-04-01 20:55 <a href="http://www.cppblog.com/iuranus/archive/2008/04/01/45949.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Wimax小结</title><link>http://www.cppblog.com/iuranus/archive/2007/12/18/38936.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Tue, 18 Dec 2007 12:44:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/12/18/38936.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/38936.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/12/18/38936.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/38936.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/38936.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要:   项目可能要加入Wimax了，我当先遣队，先调查一把。<br><br>WiMax简介：<br><br>            WiMAX 的全名是微波存取全球互通(Worldwide Interoperability for Microwave Access)，一种基于IEEE 802.16标准的宽带无线接入城域网技术。<br><br>目前所说的IEEE 802.16标准主要包括IEEE 802.16a、IEEE 802.16d和IEEE 802.16e三个标准。其中IEEE 802.16a和IEEE 802.16d是固定无线接入标准,也就是定点的用户端。而IEEE 802.16e的目标是在IEEE 802.16d固定无线接入标准的基础上加入了新的特性，主要是加入移动性还有如切换、安全等，该标准于2005年12月正式批准。<br><br>            WiMAX将分三个阶段进行部署。第一阶段是通过室内天线来部署采用IEEE802.16d规范的WiMAX技术，目标用户是固定地点的已知订户。第二阶段会大量部署室内天线，将WiMAX技术的吸引力拓宽到寻求简化用户点&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2007/12/18/38936.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/38936.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-12-18 20:44 <a href="http://www.cppblog.com/iuranus/archive/2007/12/18/38936.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>争做优秀的嵌入式人（一） Wireless networking(下)</title><link>http://www.cppblog.com/iuranus/archive/2007/05/16/24188.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Wed, 16 May 2007 02:39:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/05/16/24188.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/24188.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/05/16/24188.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/24188.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/24188.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下篇主要简述无线网卡的芯片组，驱动和LWE&nbsp;&nbsp;<a href='http://www.cppblog.com/iuranus/archive/2007/05/16/24188.html'>阅读全文</a><img src ="http://www.cppblog.com/iuranus/aggbug/24188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-05-16 10:39 <a href="http://www.cppblog.com/iuranus/archive/2007/05/16/24188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>争做优秀的嵌入式人（一） Wireless networking(上)</title><link>http://www.cppblog.com/iuranus/archive/2007/04/27/23069.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Fri, 27 Apr 2007 14:27:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2007/04/27/23069.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/23069.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2007/04/27/23069.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/23069.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/23069.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>&nbsp;&nbsp;&nbsp; 拿到入职申请书的时候发现自己的职位是嵌入式软件工程师，呵呵，这个时候我脑子里回想了下从小到大的学计算机的理想。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; 初中买了电脑时，想做的就是打游戏，希望以后能做游戏开发工程师（当时还在想有没有这个职位），自己乱买</span><span>3D MAX</span><span>的书看；上了高中的时候，我幻想当网络安全专家，也可以是黑客，然后就研究盗</span><span>QQ</span><span>号的工具，呵呵；上了大学，才确定了做程序员，做的最多的是</span><span>JAVA</span><span>，</span><span>JSP</span><span>；现在到了公司开始又做嵌入式的东西，计算机的东西可真多！每一个技术要学深入都要花很长时间，但很有意思。我也就沉静在计算机的乐趣中。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; 在我的脑海中，硬件的东西我是不屑一顾的，因为我觉的那些东西的制作和生产没有我的参加，我只想写软件，就像找了一张纸让我画画一样，但现在看来是不行了，嵌入式的东西与底层相关性比较大，所以一些基本的硬件知识和一些设备都得了解。所以我今天想总结下我这两天用到的无线网络，这也是我现在项目中用到的，</span><span>WiFi</span><span>。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; 笔记本带回家搜索了下，周围竟然有十几个</span><span>AP</span><span>，所以现在看来无线技术已经是很常见的了。无线网络也解决了以前布线，插座，接头，集线器等施工和成本问题。有人说无线网络技术能发展，有些原因要归功于笔记本的畅销，现在几乎每个无线都集成了</span><span>802.11b</span><span>或</span><st1:chmetcnv TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="802.11" UnitName="g"><span>802.11g</span></st1:chmetcnv><span>，再加上</span><span>BlueTooth USB</span><span>，使每个电脑都能轻而易举的使用无线。</span></p>
<p><span>802.11</span><span>标准</span></p>
<p><span>&nbsp;&nbsp;&nbsp; 应用于</span><span>PC</span><span>的无线网络由</span><span>IEEE</span><span>（怎么中国就没有这样的组织）制定了标准，</span><span>802.11</span><span>就是就是无线局域网的标准，它还有好多子标准：</span></p>
<p><st1:chmetcnv TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="802.11" UnitName="a"><span>802.11a</span></st1:chmetcnv><span>：</span><span>5GHz</span><span>频段，</span><span> 54Mbps</span><span>，距离短，成本高，非主流。</span></p>
<p><span>802.11b</span><span>：</span><span>2.4GHz</span><span>频段，</span><span>11Mbps</span><span>，</span><st1:chmetcnv TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="500" UnitName="m"><span>500m</span></st1:chmetcnv><span>，可以接受。</span></p>
<p><st1:chmetcnv TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="802.11" UnitName="g"><span>802.11g</span></st1:chmetcnv><span>：</span><span>2.4GHz</span><span>频段，</span><span>54Mbps</span><span>，引进</span><span>WPA</span><span>，</span><span>WEP</span><span>提高安全性。目前都在使用这个。</span></p>
<p><span>802.11i</span><span>：</span> <span>研究阶段，主要解决安全问题。</span></p>
<p><span>802.11n</span><span>：</span><span>2.4GHz</span><span>频段，</span><span>100Mbps</span><span>，研究阶段，不过已有产品，但不够完善。</span></p>
<p><span>802.11</span><span>有多种网络拓扑模式，但最基础的还是</span><span>infrastructure mode</span><span>和</span><span>ad-hoc mode</span><span>。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; infrastructure mode</span><span>：也可以说是一个集中星型无线网络，有一个所谓的无线接入点（</span><span>Access Point</span><span>，</span><span>AP</span><span>）来连接各节点之间的计算机通讯，其传输速度接近有线网络，很适合配置在家里，或者办公室。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; Ad-hoc mode</span><span>：属于对等型无线网络，各个设备可以直接连接不通过其他设备，组成点对点网络。像</span><span>PC</span><span>之间传输数据，</span><span>PSP</span><span>之间玩游戏等等。</span></p>
<p><span>&nbsp;&nbsp;&nbsp; 现在比较头疼的就是安全问题了（呵呵，这也是我比较头疼的，我的程序有时候</span><span>WEP KEY</span><span>错也能连上），无线的传输媒介是电波，只要在电波涵盖范围内的就可以接收到网络信号，所有不防有一些人接到你的</span><span>AP</span><span>下面做一些非法的事情，因为</span><span>WEP</span><span>加密已经宣布可以被破解了，所以现在新的标准也在这一方面下功夫呢！</span></p>
<img src ="http://www.cppblog.com/iuranus/aggbug/23069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2007-04-27 22:27 <a href="http://www.cppblog.com/iuranus/archive/2007/04/27/23069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>找到qt的相关资源</title><link>http://www.cppblog.com/iuranus/archive/2006/11/13/17079.html</link><dc:creator>攀升</dc:creator><author>攀升</author><pubDate>Mon, 13 Nov 2006 02:27:00 GMT</pubDate><guid>http://www.cppblog.com/iuranus/archive/2006/11/13/17079.html</guid><wfw:comment>http://www.cppblog.com/iuranus/comments/17079.html</wfw:comment><comments>http://www.cppblog.com/iuranus/archive/2006/11/13/17079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/iuranus/comments/commentRss/17079.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/iuranus/services/trackbacks/17079.html</trackback:ping><description><![CDATA[<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>qt是Trolltech提供的一个用于跨平台图形用户界面应用程序开发的C++工具包。Qt提供了可以跨Microsoft Windows、Mac OS X、Linux、所有Unix的主要商业变种以及嵌入式Linux多平台移植的单一源程序。在嵌入式Linux上，Qt应用程序编程接口是通过Qtopia Core实现的。</p>
            <p>Qt为应用程序开发者提供了构建目前使用最新水平的图形用户界面的应用程序所需要的全部功能。Qt是完全面向对象的、容易扩展的、并且允许真正的组件编程。请阅读白皮书来得到一个全面的技术概述。</p>
            <p>自从1996年早期Qt进入商业领域，它已经成为了世界范围中数千个成功应用程序的基础。Qt还是大众化的KDE Linux桌面环境的基础，KDE现在是所有主流Linux发行版的一个标准组件。请参考我们的客户成功故事来得到一些Qt的商业开发的实例。</p>
            <p>Qt被下面这些平台支持： <br>Microsoft Windows -- 98、NT 4.0、ME、2000和XP <br>Unix/X11 -- Linux、Sun Solaris、HP-UX、HP Tru64 UNIX、IBM AIX、SGI IRIX和很多其它Unix变种 <br>Mac OS X -- Mac OS X 10.2+ <br>嵌入式Linux -- 支持帧缓冲（framebuffer）的Linux平台</p>
            <p>请参考Trolltech的网站获得支持的平台和编译器的完整列表。</p>
            <p>Qt被按不同的版本发布： <br>Qt商业版被用于商业软件开发。它们提供传统商业软件发行版并且提供免费升级和技术支持服务。如果要获得最新报价，请浏览在线的价格信息页面或者与sales@trolltech.com联系。 <br>Qt开源版仅被用于开发自由和开源软件。基于Q公共许可协议和GNU通用公共许可协议的条款下，它是被免费提供的。</p>
            <p>Trolltech还提供了Qt解决方案，它是一套正在增多的用于完善Qt的适用于工业领域和平台特定范围的组件。它们中的一些组件仅提供给商业客户，其它的对于所有Qt用户都是可用的。 <br>国内相关网站不多，在这里我推荐一个QT的网站：http://www.qtcn.org/bbs/ <br>相关资源下载：ftp://ftp.trolltech.com/qt/source</p>
            </td>
        </tr>
    </tbody>
</table>
<br><br><a href="http://www.cppblog.com/iuranus/admin/%20%20%20%0A%20%20%20%20http://uranus.javaeye.com/blog/33976%0A%20%20%20%20"></a>
<img src ="http://www.cppblog.com/iuranus/aggbug/17079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/iuranus/" target="_blank">攀升</a> 2006-11-13 10:27 <a href="http://www.cppblog.com/iuranus/archive/2006/11/13/17079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>