Ignore:
Timestamp:
Aug 2, 2010, 9:27:30 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/examples/multimedia/audiodevices/audiodevices.cpp

    r651 r769  
    4444
    4545#include "audiodevices.h"
     46
     47// Utility functions for converting QAudioFormat fields into text
     48
     49QString toString(QAudioFormat::SampleType sampleType)
     50{
     51    QString result("Unknown");
     52    switch (sampleType) {
     53    case QAudioFormat::SignedInt:
     54        result = "SignedInt";
     55        break;
     56    case QAudioFormat::UnSignedInt:
     57        result = "UnSignedInt";
     58        break;
     59    case QAudioFormat::Float:
     60        result = "Float";
     61        break;
     62    }
     63    return result;
     64}
     65
     66QString toString(QAudioFormat::Endian endian)
     67{
     68    QString result("Unknown");
     69    switch (endian) {
     70    case QAudioFormat::LittleEndian:
     71        result = "LittleEndian";
     72        break;
     73    case QAudioFormat::BigEndian:
     74        result = "BigEndian";
     75        break;
     76    }
     77    return result;
     78}
     79
    4680
    4781AudioDevicesBase::AudioDevicesBase(QWidget *parent, Qt::WFlags f)
     
    68102    connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int)));
    69103    connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int)));
     104    connect(populateTableButton, SIGNAL(clicked()), SLOT(populateTable()));
    70105
    71106    modeBox->setCurrentIndex(0);
     
    82117{
    83118    // tries to set all the settings picked.
    84     logOutput->clear();
    85     logOutput->append("NOTE: an invalid codec audio/test exists for testing, to get a fail condition.");
     119    testResult->clear();
    86120
    87121    if (!deviceInfo.isNull()) {
    88122        if (deviceInfo.isFormatSupported(settings)) {
    89             logOutput->append(tr("Success"));
     123            testResult->setText(tr("Success"));
    90124            nearestFreq->setText("");
    91125            nearestChannel->setText("");
     
    96130        } else {
    97131            QAudioFormat nearest = deviceInfo.nearestFormat(settings);
    98             logOutput->append(tr("Failed"));
     132            testResult->setText(tr("Failed"));
    99133            nearestFreq->setText(QString("%1").arg(nearest.frequency()));
    100134            nearestChannel->setText(QString("%1").arg(nearest.channels()));
    101135            nearestCodec->setText(nearest.codec());
    102136            nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize()));
    103 
    104             switch(nearest.sampleType()) {
    105                 case QAudioFormat::SignedInt:
    106                     nearestSampleType->setText("SignedInt");
    107                     break;
    108                 case QAudioFormat::UnSignedInt:
    109                     nearestSampleType->setText("UnSignedInt");
    110                     break;
    111                 case QAudioFormat::Float:
    112                     nearestSampleType->setText("Float");
    113                     break;
    114                 case QAudioFormat::Unknown:
    115                     nearestSampleType->setText("Unknown");
    116             }
    117             switch(nearest.byteOrder()) {
    118                 case QAudioFormat::LittleEndian:
    119                     nearestEndian->setText("LittleEndian");
    120                     break;
    121                 case QAudioFormat::BigEndian:
    122                     nearestEndian->setText("BigEndian");
    123             }
     137            nearestSampleType->setText(toString(nearest.sampleType()));
     138            nearestEndian->setText(toString(nearest.byteOrder()));
    124139        }
    125140    }
    126141    else
    127         logOutput->append(tr("No Device"));
     142        testResult->setText(tr("No Device"));
    128143}
    129144
    130145void AudioTest::modeChanged(int idx)
    131146{
     147    testResult->clear();
     148
    132149    // mode has changed
    133150    if (idx == 0)
     
    139156    foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode))
    140157        deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
     158
     159    deviceBox->setCurrentIndex(0);
     160    deviceChanged(0);
    141161}
    142162
    143163void AudioTest::deviceChanged(int idx)
    144164{
     165    testResult->clear();
     166
    145167    if (deviceBox->count() == 0)
    146168        return;
     
    181203    sampleTypesBox->clear();
    182204    QList<QAudioFormat::SampleType> sampleTypez = deviceInfo.supportedSampleTypes();
    183     for (int i = 0; i < sampleTypez.size(); ++i) {
    184         switch(sampleTypez.at(i)) {
    185             case QAudioFormat::SignedInt:
    186                 sampleTypesBox->addItem("SignedInt");
    187                 break;
    188             case QAudioFormat::UnSignedInt:
    189                 sampleTypesBox->addItem("UnSignedInt");
    190                 break;
    191             case QAudioFormat::Float:
    192                 sampleTypesBox->addItem("Float");
    193                 break;
    194             case QAudioFormat::Unknown:
    195                 sampleTypesBox->addItem("Unknown");
    196         }
    197         if (sampleTypez.size())
    198             settings.setSampleType(sampleTypez.at(0));
    199     }
     205
     206    for (int i = 0; i < sampleTypez.size(); ++i)
     207        sampleTypesBox->addItem(toString(sampleTypez.at(i)));
     208    if (sampleTypez.size())
     209        settings.setSampleType(sampleTypez.at(0));
    200210
    201211    endianBox->clear();
    202212    QList<QAudioFormat::Endian> endianz = deviceInfo.supportedByteOrders();
    203     for (int i = 0; i < endianz.size(); ++i) {
    204         switch (endianz.at(i)) {
    205             case QAudioFormat::LittleEndian:
    206                 endianBox->addItem("Little Endian");
    207                 break;
    208             case QAudioFormat::BigEndian:
    209                 endianBox->addItem("Big Endian");
    210                 break;
    211         }
    212     }
     213    for (int i = 0; i < endianz.size(); ++i)
     214        endianBox->addItem(toString(endianz.at(i)));
    213215    if (endianz.size())
    214216        settings.setByteOrder(endianz.at(0));
     217
     218    allFormatsTable->clearContents();
     219}
     220
     221void AudioTest::populateTable()
     222{
     223    int row = 0;
     224
     225    QAudioFormat format;
     226    foreach (QString codec, deviceInfo.supportedCodecs()) {
     227        format.setCodec(codec);
     228        foreach (int frequency, deviceInfo.supportedFrequencies()) {
     229            format.setFrequency(frequency);
     230            foreach (int channels, deviceInfo.supportedChannels()) {
     231                format.setChannels(channels);
     232                foreach (QAudioFormat::SampleType sampleType, deviceInfo.supportedSampleTypes()) {
     233                    format.setSampleType(sampleType);
     234                    foreach (int sampleSize, deviceInfo.supportedSampleSizes()) {
     235                        format.setSampleSize(sampleSize);
     236                        foreach (QAudioFormat::Endian endian, deviceInfo.supportedByteOrders()) {
     237                            format.setByteOrder(endian);
     238                            if (deviceInfo.isFormatSupported(format)) {
     239                                allFormatsTable->setRowCount(row + 1);
     240
     241                                QTableWidgetItem *codecItem = new QTableWidgetItem(format.codec());
     242                                allFormatsTable->setItem(row, 0, codecItem);
     243
     244                                QTableWidgetItem *frequencyItem = new QTableWidgetItem(QString("%1").arg(format.frequency()));
     245                                allFormatsTable->setItem(row, 1, frequencyItem);
     246
     247                                QTableWidgetItem *channelsItem = new QTableWidgetItem(QString("%1").arg(format.channels()));
     248                                allFormatsTable->setItem(row, 2, channelsItem);
     249
     250                                QTableWidgetItem *sampleTypeItem = new QTableWidgetItem(toString(format.sampleType()));
     251                                allFormatsTable->setItem(row, 3, sampleTypeItem);
     252
     253                                QTableWidgetItem *sampleSizeItem = new QTableWidgetItem(QString("%1").arg(format.sampleSize()));
     254                                allFormatsTable->setItem(row, 4, sampleSizeItem);
     255
     256                                QTableWidgetItem *byteOrderItem = new QTableWidgetItem(toString(format.byteOrder()));
     257                                allFormatsTable->setItem(row, 5, byteOrderItem);
     258
     259                                ++row;
     260                            }
     261                        }
     262                    }
     263                }
     264            }
     265        }
     266    }
    215267}
    216268
  • trunk/examples/multimedia/audiodevices/audiodevices.h

    r651 r769  
    7575    void endianChanged(int idx);
    7676    void test();
     77    void populateTable();
     78
    7779};
    7880
  • trunk/examples/multimedia/audiodevices/audiodevicesbase.ui

    r561 r769  
    77    <x>0</x>
    88    <y>0</y>
    9     <width>504</width>
    10     <height>702</height>
     9    <width>679</width>
     10    <height>598</height>
    1111   </rect>
    1212  </property>
     
    1717   <layout class="QVBoxLayout" name="verticalLayout">
    1818    <item>
    19      <layout class="QGridLayout" name="gridLayout">
    20       <item row="0" column="0">
    21        <widget class="QLabel" name="deviceLabel">
    22         <property name="sizePolicy">
    23          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
    24           <horstretch>1</horstretch>
    25           <verstretch>0</verstretch>
    26          </sizepolicy>
    27         </property>
    28         <property name="text">
    29          <string>Device</string>
    30         </property>
    31        </widget>
    32       </item>
    33       <item row="0" column="1">
    34        <widget class="QLabel" name="modeLabel">
    35         <property name="text">
    36          <string>Mode</string>
    37         </property>
    38        </widget>
    39       </item>
    40       <item row="1" column="0">
    41        <widget class="QComboBox" name="deviceBox"/>
    42       </item>
    43       <item row="1" column="1">
    44        <widget class="QComboBox" name="modeBox">
    45         <item>
    46          <property name="text">
    47           <string>Input</string>
    48          </property>
     19     <widget class="QScrollArea" name="scrollArea">
     20      <property name="sizePolicy">
     21       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
     22        <horstretch>0</horstretch>
     23        <verstretch>0</verstretch>
     24       </sizepolicy>
     25      </property>
     26      <property name="widgetResizable">
     27       <bool>true</bool>
     28      </property>
     29      <widget class="QWidget" name="scrollAreaWidgetContents">
     30       <property name="geometry">
     31        <rect>
     32         <x>0</x>
     33         <y>0</y>
     34         <width>659</width>
     35         <height>558</height>
     36        </rect>
     37       </property>
     38       <layout class="QGridLayout" name="gridLayout_4">
     39        <item row="0" column="0">
     40         <layout class="QGridLayout" name="gridLayout_2">
     41          <item row="0" column="0">
     42           <widget class="QLabel" name="modeLabel">
     43            <property name="text">
     44             <string>Mode</string>
     45            </property>
     46           </widget>
     47          </item>
     48          <item row="0" column="1">
     49           <widget class="QLabel" name="deviceLabel">
     50            <property name="text">
     51             <string>Device</string>
     52            </property>
     53           </widget>
     54          </item>
     55          <item row="1" column="0">
     56           <widget class="QComboBox" name="modeBox">
     57            <item>
     58             <property name="text">
     59              <string>Input</string>
     60             </property>
     61            </item>
     62            <item>
     63             <property name="text">
     64              <string>Output</string>
     65             </property>
     66            </item>
     67           </widget>
     68          </item>
     69          <item row="1" column="1">
     70           <widget class="QComboBox" name="deviceBox"/>
     71          </item>
     72          <item row="2" column="0" colspan="2">
     73           <widget class="QTabWidget" name="tabWidget">
     74            <property name="currentIndex">
     75             <number>0</number>
     76            </property>
     77            <widget class="QWidget" name="testFormatTab">
     78             <attribute name="title">
     79              <string>Test format</string>
     80             </attribute>
     81             <layout class="QGridLayout" name="gridLayout">
     82              <item row="0" column="1">
     83               <widget class="QLabel" name="actualLabel">
     84                <property name="sizePolicy">
     85                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
     86                  <horstretch>0</horstretch>
     87                  <verstretch>0</verstretch>
     88                 </sizepolicy>
     89                </property>
     90                <property name="frameShape">
     91                 <enum>QFrame::NoFrame</enum>
     92                </property>
     93                <property name="frameShadow">
     94                 <enum>QFrame::Plain</enum>
     95                </property>
     96                <property name="text">
     97                 <string>&lt;i&gt;Actual Settings&lt;/i&gt;</string>
     98                </property>
     99                <property name="textFormat">
     100                 <enum>Qt::RichText</enum>
     101                </property>
     102                <property name="alignment">
     103                 <set>Qt::AlignCenter</set>
     104                </property>
     105               </widget>
     106              </item>
     107              <item row="0" column="2">
     108               <widget class="QLabel" name="nearestLabel">
     109                <property name="sizePolicy">
     110                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
     111                  <horstretch>0</horstretch>
     112                  <verstretch>0</verstretch>
     113                 </sizepolicy>
     114                </property>
     115                <property name="frameShape">
     116                 <enum>QFrame::NoFrame</enum>
     117                </property>
     118                <property name="frameShadow">
     119                 <enum>QFrame::Plain</enum>
     120                </property>
     121                <property name="text">
     122                 <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
     123&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
     124p, li { white-space: pre-wrap; }
     125&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
     126&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Nearest Settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
     127                </property>
     128                <property name="textFormat">
     129                 <enum>Qt::RichText</enum>
     130                </property>
     131                <property name="alignment">
     132                 <set>Qt::AlignCenter</set>
     133                </property>
     134               </widget>
     135              </item>
     136              <item row="3" column="1">
     137               <widget class="QComboBox" name="frequencyBox">
     138                <property name="sizePolicy">
     139                 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
     140                  <horstretch>0</horstretch>
     141                  <verstretch>0</verstretch>
     142                 </sizepolicy>
     143                </property>
     144               </widget>
     145              </item>
     146              <item row="3" column="2">
     147               <widget class="QLineEdit" name="nearestFreq">
     148                <property name="enabled">
     149                 <bool>false</bool>
     150                </property>
     151               </widget>
     152              </item>
     153              <item row="5" column="1">
     154               <widget class="QComboBox" name="channelsBox"/>
     155              </item>
     156              <item row="5" column="2">
     157               <widget class="QLineEdit" name="nearestChannel">
     158                <property name="enabled">
     159                 <bool>false</bool>
     160                </property>
     161               </widget>
     162              </item>
     163              <item row="9" column="1">
     164               <widget class="QComboBox" name="sampleSizesBox"/>
     165              </item>
     166              <item row="9" column="2">
     167               <widget class="QLineEdit" name="nearestSampleSize">
     168                <property name="enabled">
     169                 <bool>false</bool>
     170                </property>
     171               </widget>
     172              </item>
     173              <item row="14" column="1">
     174               <widget class="QComboBox" name="endianBox"/>
     175              </item>
     176              <item row="14" column="2">
     177               <widget class="QLineEdit" name="nearestEndian">
     178                <property name="enabled">
     179                 <bool>false</bool>
     180                </property>
     181               </widget>
     182              </item>
     183              <item row="15" column="1">
     184               <widget class="QPushButton" name="testButton">
     185                <property name="text">
     186                 <string>Test</string>
     187                </property>
     188               </widget>
     189              </item>
     190              <item row="15" column="2">
     191               <widget class="QLabel" name="testResult">
     192                <property name="text">
     193                 <string/>
     194                </property>
     195               </widget>
     196              </item>
     197              <item row="3" column="0">
     198               <widget class="QLabel" name="actualFreqLabel">
     199                <property name="text">
     200                 <string>Frequency (Hz)</string>
     201                </property>
     202               </widget>
     203              </item>
     204              <item row="5" column="0">
     205               <widget class="QLabel" name="actualChannelLabel">
     206                <property name="text">
     207                 <string>Channels</string>
     208                </property>
     209               </widget>
     210              </item>
     211              <item row="9" column="0">
     212               <widget class="QLabel" name="actualSampleSizeLabel">
     213                <property name="text">
     214                 <string>Sample size (bits)</string>
     215                </property>
     216               </widget>
     217              </item>
     218              <item row="14" column="0">
     219               <widget class="QLabel" name="actualEndianLabel">
     220                <property name="text">
     221                 <string>Endianess</string>
     222                </property>
     223               </widget>
     224              </item>
     225              <item row="16" column="0" colspan="3">
     226               <widget class="QLabel" name="label">
     227                <property name="sizePolicy">
     228                 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
     229                  <horstretch>0</horstretch>
     230                  <verstretch>0</verstretch>
     231                 </sizepolicy>
     232                </property>
     233                <property name="text">
     234                 <string>Note: an invalid codec 'audio/test' exists in order to allow an invalid format to be constructed, and therefore to trigger a 'nearest format' calculation.</string>
     235                </property>
     236                <property name="wordWrap">
     237                 <bool>true</bool>
     238                </property>
     239               </widget>
     240              </item>
     241              <item row="2" column="0">
     242               <widget class="QLabel" name="actualCodecLabel">
     243                <property name="text">
     244                 <string>Codec</string>
     245                </property>
     246               </widget>
     247              </item>
     248              <item row="2" column="2">
     249               <widget class="QLineEdit" name="nearestCodec">
     250                <property name="enabled">
     251                 <bool>false</bool>
     252                </property>
     253               </widget>
     254              </item>
     255              <item row="2" column="1">
     256               <widget class="QComboBox" name="codecsBox"/>
     257              </item>
     258              <item row="6" column="0">
     259               <widget class="QLabel" name="actualSampleTypeLabel">
     260                <property name="text">
     261                 <string>SampleType</string>
     262                </property>
     263               </widget>
     264              </item>
     265              <item row="6" column="1">
     266               <widget class="QComboBox" name="sampleTypesBox"/>
     267              </item>
     268              <item row="6" column="2">
     269               <widget class="QLineEdit" name="nearestSampleType">
     270                <property name="enabled">
     271                 <bool>false</bool>
     272                </property>
     273               </widget>
     274              </item>
     275             </layout>
     276            </widget>
     277            <widget class="QWidget" name="tab">
     278             <attribute name="title">
     279              <string>All formats</string>
     280             </attribute>
     281             <layout class="QVBoxLayout" name="verticalLayout_2">
     282              <item>
     283               <widget class="QPushButton" name="populateTableButton">
     284                <property name="text">
     285                 <string>Populate table</string>
     286                </property>
     287               </widget>
     288              </item>
     289              <item>
     290               <widget class="QTableWidget" name="allFormatsTable">
     291                <property name="editTriggers">
     292                 <set>QAbstractItemView::NoEditTriggers</set>
     293                </property>
     294                <property name="dragDropOverwriteMode">
     295                 <bool>false</bool>
     296                </property>
     297                <property name="selectionMode">
     298                 <enum>QAbstractItemView::NoSelection</enum>
     299                </property>
     300                <property name="selectionBehavior">
     301                 <enum>QAbstractItemView::SelectItems</enum>
     302                </property>
     303                <property name="textElideMode">
     304                 <enum>Qt::ElideNone</enum>
     305                </property>
     306                <property name="sortingEnabled">
     307                 <bool>false</bool>
     308                </property>
     309                <property name="wordWrap">
     310                 <bool>false</bool>
     311                </property>
     312                <property name="cornerButtonEnabled">
     313                 <bool>false</bool>
     314                </property>
     315                <attribute name="horizontalHeaderHighlightSections">
     316                 <bool>false</bool>
     317                </attribute>
     318                <attribute name="verticalHeaderVisible">
     319                 <bool>false</bool>
     320                </attribute>
     321                <attribute name="verticalHeaderHighlightSections">
     322                 <bool>false</bool>
     323                </attribute>
     324                <attribute name="verticalHeaderVisible">
     325                 <bool>false</bool>
     326                </attribute>
     327                <attribute name="horizontalHeaderHighlightSections">
     328                 <bool>false</bool>
     329                </attribute>
     330                <attribute name="verticalHeaderHighlightSections">
     331                 <bool>false</bool>
     332                </attribute>
     333                <column>
     334                 <property name="text">
     335                  <string>Codec</string>
     336                 </property>
     337                 <property name="textAlignment">
     338                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     339                 </property>
     340                </column>
     341                <column>
     342                 <property name="text">
     343                  <string>Frequency (Hz)</string>
     344                 </property>
     345                 <property name="textAlignment">
     346                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     347                 </property>
     348                </column>
     349                <column>
     350                 <property name="text">
     351                  <string>Channels</string>
     352                 </property>
     353                 <property name="textAlignment">
     354                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     355                 </property>
     356                </column>
     357                <column>
     358                 <property name="text">
     359                  <string>Sample type</string>
     360                 </property>
     361                 <property name="textAlignment">
     362                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     363                 </property>
     364                </column>
     365                <column>
     366                 <property name="text">
     367                  <string>Sample size (bits)</string>
     368                 </property>
     369                 <property name="textAlignment">
     370                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     371                 </property>
     372                </column>
     373                <column>
     374                 <property name="text">
     375                  <string>Endianness</string>
     376                 </property>
     377                 <property name="textAlignment">
     378                  <set>AlignHCenter|AlignVCenter|AlignCenter</set>
     379                 </property>
     380                </column>
     381               </widget>
     382              </item>
     383             </layout>
     384            </widget>
     385           </widget>
     386          </item>
     387         </layout>
    49388        </item>
    50         <item>
    51          <property name="text">
    52           <string>Output</string>
    53          </property>
    54         </item>
    55        </widget>
    56       </item>
    57       <item row="2" column="0">
    58        <widget class="QLabel" name="actualLabel">
    59         <property name="frameShape">
    60          <enum>QFrame::Panel</enum>
    61         </property>
    62         <property name="frameShadow">
    63          <enum>QFrame::Raised</enum>
    64         </property>
    65         <property name="text">
    66          <string>Actual Settings</string>
    67         </property>
    68         <property name="alignment">
    69          <set>Qt::AlignCenter</set>
    70         </property>
    71        </widget>
    72       </item>
    73       <item row="2" column="1">
    74        <widget class="QLabel" name="nearestLabel">
    75         <property name="frameShape">
    76          <enum>QFrame::Panel</enum>
    77         </property>
    78         <property name="frameShadow">
    79          <enum>QFrame::Raised</enum>
    80         </property>
    81         <property name="text">
    82          <string>Nearest Settings</string>
    83         </property>
    84         <property name="alignment">
    85          <set>Qt::AlignCenter</set>
    86         </property>
    87        </widget>
    88       </item>
    89       <item row="3" column="0">
    90        <widget class="QLabel" name="actualFreqLabel">
    91         <property name="text">
    92          <string>Frequency</string>
    93         </property>
    94        </widget>
    95       </item>
    96       <item row="3" column="1">
    97        <widget class="QLabel" name="nearestFreqLabel">
    98         <property name="text">
    99          <string>Frequency</string>
    100         </property>
    101        </widget>
    102       </item>
    103       <item row="4" column="0">
    104        <widget class="QComboBox" name="frequencyBox"/>
    105       </item>
    106       <item row="4" column="1">
    107        <widget class="QLineEdit" name="nearestFreq">
    108         <property name="enabled">
    109          <bool>false</bool>
    110         </property>
    111        </widget>
    112       </item>
    113       <item row="5" column="0">
    114        <widget class="QLabel" name="actualChannelsLabel">
    115         <property name="text">
    116          <string>Channels</string>
    117         </property>
    118        </widget>
    119       </item>
    120       <item row="5" column="1">
    121        <widget class="QLabel" name="nearestChannelLabel">
    122         <property name="text">
    123          <string>Channel</string>
    124         </property>
    125        </widget>
    126       </item>
    127       <item row="6" column="0">
    128        <widget class="QComboBox" name="channelsBox"/>
    129       </item>
    130       <item row="6" column="1">
    131        <widget class="QLineEdit" name="nearestChannel">
    132         <property name="enabled">
    133          <bool>false</bool>
    134         </property>
    135        </widget>
    136       </item>
    137       <item row="7" column="0">
    138        <widget class="QLabel" name="actualCodecLabel">
    139         <property name="text">
    140          <string>Codecs</string>
    141         </property>
    142        </widget>
    143       </item>
    144       <item row="7" column="1">
    145        <widget class="QLabel" name="nearestCodecLabel">
    146         <property name="text">
    147          <string>Codec</string>
    148         </property>
    149        </widget>
    150       </item>
    151       <item row="8" column="0">
    152        <widget class="QComboBox" name="codecsBox"/>
    153       </item>
    154       <item row="8" column="1">
    155        <widget class="QLineEdit" name="nearestCodec">
    156         <property name="enabled">
    157          <bool>false</bool>
    158         </property>
    159        </widget>
    160       </item>
    161       <item row="9" column="0">
    162        <widget class="QLabel" name="actualSampleSizeLabel">
    163         <property name="text">
    164          <string>SampleSize</string>
    165         </property>
    166        </widget>
    167       </item>
    168       <item row="9" column="1">
    169        <widget class="QLabel" name="nearestSampleSizeLabel">
    170         <property name="text">
    171          <string>SampleSize</string>
    172         </property>
    173        </widget>
    174       </item>
    175       <item row="10" column="0">
    176        <widget class="QComboBox" name="sampleSizesBox"/>
    177       </item>
    178       <item row="10" column="1">
    179        <widget class="QLineEdit" name="nearestSampleSize">
    180         <property name="enabled">
    181          <bool>false</bool>
    182         </property>
    183        </widget>
    184       </item>
    185       <item row="11" column="0">
    186        <widget class="QLabel" name="actualSampleTypeLabel">
    187         <property name="text">
    188          <string>SampleType</string>
    189         </property>
    190        </widget>
    191       </item>
    192       <item row="11" column="1">
    193        <widget class="QLabel" name="nearestSampleTypeLabel">
    194         <property name="text">
    195          <string>SampleType</string>
    196         </property>
    197        </widget>
    198       </item>
    199       <item row="12" column="0">
    200        <widget class="QComboBox" name="sampleTypesBox"/>
    201       </item>
    202       <item row="12" column="1">
    203        <widget class="QLineEdit" name="nearestSampleType">
    204         <property name="enabled">
    205          <bool>false</bool>
    206         </property>
    207        </widget>
    208       </item>
    209       <item row="13" column="0">
    210        <widget class="QLabel" name="actualEndianLabel">
    211         <property name="text">
    212          <string>Endianess</string>
    213         </property>
    214        </widget>
    215       </item>
    216       <item row="13" column="1">
    217        <widget class="QLabel" name="nearestEndianLabel">
    218         <property name="text">
    219          <string>Endianess</string>
    220         </property>
    221        </widget>
    222       </item>
    223       <item row="14" column="0">
    224        <widget class="QComboBox" name="endianBox"/>
    225       </item>
    226       <item row="14" column="1">
    227        <widget class="QLineEdit" name="nearestEndian">
    228         <property name="enabled">
    229          <bool>false</bool>
    230         </property>
    231        </widget>
    232       </item>
    233       <item row="15" column="0" colspan="2">
    234        <widget class="QTextEdit" name="logOutput">
    235         <property name="enabled">
    236          <bool>false</bool>
    237         </property>
    238         <property name="minimumSize">
    239          <size>
    240           <width>0</width>
    241           <height>40</height>
    242          </size>
    243         </property>
    244        </widget>
    245       </item>
    246       <item row="16" column="0" colspan="2">
    247        <widget class="QPushButton" name="testButton">
    248         <property name="text">
    249          <string>Test</string>
    250         </property>
    251        </widget>
    252       </item>
    253      </layout>
     389       </layout>
     390      </widget>
     391     </widget>
    254392    </item>
    255393   </layout>
  • trunk/examples/multimedia/audiodevices/main.cpp

    r651 r769  
    5050
    5151    AudioTest audio;
     52#ifdef Q_OS_SYMBIAN
     53    audio.showMaximized();
     54#else
    5255    audio.show();
     56#endif
    5357
    5458    return app.exec();
  • trunk/examples/multimedia/audioinput/audioinput.cpp

    r651 r769  
    4949#include <QAudioDeviceInfo>
    5050#include <QAudioInput>
     51
     52#include <QtCore/qendian.h>
     53
    5154#include "audioinput.h"
    5255
    53 #define BUFFER_SIZE 4096
    54 
    55 AudioInfo::AudioInfo(QObject *parent, QAudioInput *device)
    56     :QIODevice(parent)
    57 {
    58     input = device;
    59 
    60     m_maxValue = 0;
     56const QString InputTest::PushModeLabel(tr("Enable push mode"));
     57const QString InputTest::PullModeLabel(tr("Enable pull mode"));
     58const QString InputTest::SuspendLabel(tr("Suspend recording"));
     59const QString InputTest::ResumeLabel(tr("Resume recording"));
     60
     61const int BufferSize = 4096;
     62
     63AudioInfo::AudioInfo(const QAudioFormat &format, QObject *parent)
     64    :   QIODevice(parent)
     65    ,   m_format(format)
     66    ,   m_maxAmplitude(0)
     67    ,   m_level(0.0)
     68
     69{
     70    switch (m_format.sampleSize()) {
     71    case 8:
     72        switch (m_format.sampleType()) {
     73        case QAudioFormat::UnSignedInt:
     74            m_maxAmplitude = 255;
     75            break;
     76        case QAudioFormat::SignedInt:
     77            m_maxAmplitude = 127;
     78            break;
     79        default: ;
     80        }
     81        break;
     82    case 16:
     83        switch (m_format.sampleType()) {
     84        case QAudioFormat::UnSignedInt:
     85            m_maxAmplitude = 65535;
     86            break;
     87        case QAudioFormat::SignedInt:
     88            m_maxAmplitude = 32767;
     89            break;
     90        default: ;
     91        }
     92        break;
     93    }
    6194}
    6295
     
    85118qint64 AudioInfo::writeData(const char *data, qint64 len)
    86119{
    87     int samples = len/2; // 2 bytes per sample
    88     int maxAmp = 32768; // max for S16 samples
    89     bool clipping = false;
    90 
    91     m_maxValue = 0;
    92 
    93     qint16 *s = (qint16*)data;
    94 
    95     // sample format is S16LE, only!
    96 
    97     for (int i = 0; i < samples; ++i) {
    98         qint16 sample = *s;
    99         s++;
    100         if (abs(sample) > m_maxValue) m_maxValue = abs(sample);
    101     }
    102     // check for clipping
    103     if (m_maxValue >= (maxAmp - 1))
    104         clipping = true;
    105 
    106     float value = ((float)m_maxValue/(float)maxAmp);
    107     if (clipping)
    108         m_maxValue = 100;
    109     else
    110         m_maxValue = (int)(value*100);
     120    if (m_maxAmplitude) {
     121        Q_ASSERT(m_format.sampleSize() % 8 == 0);
     122        const int channelBytes = m_format.sampleSize() / 8;
     123        const int sampleBytes = m_format.channels() * channelBytes;
     124        Q_ASSERT(len % sampleBytes == 0);
     125        const int numSamples = len / sampleBytes;
     126
     127        quint16 maxValue = 0;
     128        const unsigned char *ptr = reinterpret_cast<const unsigned char *>(data);
     129
     130        for (int i = 0; i < numSamples; ++i) {
     131            for(int j = 0; j < m_format.channels(); ++j) {
     132                quint16 value = 0;
     133
     134                if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
     135                    value = *reinterpret_cast<const quint8*>(ptr);
     136                } else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) {
     137                    value = qAbs(*reinterpret_cast<const qint8*>(ptr));
     138                } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
     139                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
     140                        value = qFromLittleEndian<quint16>(ptr);
     141                    else
     142                        value = qFromBigEndian<quint16>(ptr);
     143                } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) {
     144                    if (m_format.byteOrder() == QAudioFormat::LittleEndian)
     145                        value = qAbs(qFromLittleEndian<qint16>(ptr));
     146                    else
     147                        value = qAbs(qFromBigEndian<qint16>(ptr));
     148                }
     149
     150                maxValue = qMax(value, maxValue);
     151                ptr += channelBytes;
     152            }
     153        }
     154
     155        maxValue = qMin(maxValue, m_maxAmplitude);
     156        m_level = qreal(maxValue) / m_maxAmplitude;
     157    }
    111158
    112159    emit update();
    113 
    114160    return len;
    115 }
    116 
    117 int AudioInfo::LinearMax()
    118 {
    119     return m_maxValue;
    120161}
    121162
     
    126167    setAutoFillBackground(true);
    127168
    128     level = 0;
     169    m_level = 0;
    129170    setMinimumHeight(30);
    130171    setMinimumWidth(200);
     
    140181                           painter.viewport().right()-20,
    141182                           painter.viewport().bottom()-20));
    142     if (level == 0)
     183    if (m_level == 0.0)
    143184        return;
    144185
    145186    painter.setPen(Qt::red);
    146187
    147     int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*level/100;
     188    int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*m_level;
    148189    for (int i = 0; i < 10; ++i) {
    149190        int x1 = painter.viewport().left()+11;
     
    158199}
    159200
    160 void RenderArea::setLevel(int value)
    161 {
    162     level = value;
     201void RenderArea::setLevel(qreal value)
     202{
     203    m_level = value;
    163204    repaint();
    164205}
     
    166207
    167208InputTest::InputTest()
    168 {
    169     QWidget *window = new QWidget;
    170     QVBoxLayout* layout = new QVBoxLayout;
    171 
    172     canvas = new RenderArea;
    173     layout->addWidget(canvas);
    174 
    175     deviceBox = new QComboBox(this);
     209    :   m_canvas(0)
     210    ,   m_modeButton(0)
     211    ,   m_suspendResumeButton(0)
     212    ,   m_deviceBox(0)
     213    ,   m_device(QAudioDeviceInfo::defaultInputDevice())
     214    ,   m_audioInfo(0)
     215    ,   m_audioInput(0)
     216    ,   m_input(0)
     217    ,   m_pullMode(false)
     218    ,   m_buffer(BufferSize, 0)
     219{
     220    initializeWindow();
     221    initializeAudio();
     222}
     223
     224InputTest::~InputTest() {}
     225
     226void InputTest::initializeWindow()
     227{
     228    QScopedPointer<QWidget> window(new QWidget);
     229    QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
     230
     231    m_canvas = new RenderArea(this);
     232    layout->addWidget(m_canvas);
     233
     234    m_deviceBox = new QComboBox(this);
    176235    QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
    177236    for(int i = 0; i < devices.size(); ++i)
    178         deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i)));
    179 
    180     connect(deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
    181     layout->addWidget(deviceBox);
    182 
    183     button = new QPushButton(this);
    184     button->setText(tr("Click for Push Mode"));
    185     connect(button, SIGNAL(clicked()), SLOT(toggleMode()));
    186     layout->addWidget(button);
    187 
    188     button2 = new QPushButton(this);
    189     button2->setText(tr("Click To Suspend"));
    190     connect(button2, SIGNAL(clicked()), SLOT(toggleSuspend()));
    191     layout->addWidget(button2);
    192 
    193     window->setLayout(layout);
    194     setCentralWidget(window);
    195     window->show();
    196 
    197     buffer = new char[BUFFER_SIZE];
    198 
    199     pullMode = true;
    200 
    201     format.setFrequency(8000);
    202     format.setChannels(1);
    203     format.setSampleSize(16);
    204     format.setSampleType(QAudioFormat::SignedInt);
    205     format.setByteOrder(QAudioFormat::LittleEndian);
    206     format.setCodec("audio/pcm");
     237        m_deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i)));
     238
     239    connect(m_deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
     240    layout->addWidget(m_deviceBox);
     241
     242    m_modeButton = new QPushButton(this);
     243    m_modeButton->setText(PushModeLabel);
     244    connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
     245    layout->addWidget(m_modeButton);
     246
     247    m_suspendResumeButton = new QPushButton(this);
     248    m_suspendResumeButton->setText(SuspendLabel);
     249    connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspend()));
     250    layout->addWidget(m_suspendResumeButton);
     251
     252    window->setLayout(layout.data());
     253    layout.take(); // ownership transferred
     254
     255    setCentralWidget(window.data());
     256    QWidget *const windowPtr = window.take(); // ownership transferred
     257    windowPtr->show();
     258}
     259
     260void InputTest::initializeAudio()
     261{
     262    m_pullMode = true;
     263
     264    m_format.setFrequency(8000);
     265    m_format.setChannels(1);
     266    m_format.setSampleSize(16);
     267    m_format.setSampleType(QAudioFormat::SignedInt);
     268    m_format.setByteOrder(QAudioFormat::LittleEndian);
     269    m_format.setCodec("audio/pcm");
    207270
    208271    QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
    209     if (!info.isFormatSupported(format)) {
    210         qWarning()<<"default format not supported try to use nearest";
    211         format = info.nearestFormat(format);
    212     }
    213 
    214     if(format.sampleSize() != 16) {
    215         qWarning()<<"audio device doesn't support 16 bit samples, example cannot run";
    216         audioInput = 0;
    217         button->setDisabled(true);
    218         button2->setDisabled(true);
     272    if (!info.isFormatSupported(m_format)) {
     273        qWarning() << "Default format not supported - trying to use nearest";
     274        m_format = info.nearestFormat(m_format);
     275    }
     276
     277    m_audioInfo  = new AudioInfo(m_format, this);
     278    connect(m_audioInfo, SIGNAL(update()), SLOT(refreshDisplay()));
     279
     280    createAudioInput();
     281}
     282
     283void InputTest::createAudioInput()
     284{
     285    m_audioInput = new QAudioInput(m_device, m_format, this);
     286    connect(m_audioInput, SIGNAL(notify()), SLOT(notified()));
     287    connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
     288    m_audioInfo->start();
     289    m_audioInput->start(m_audioInfo);
     290}
     291
     292void InputTest::notified()
     293{
     294    qWarning() << "bytesReady = " << m_audioInput->bytesReady()
     295               << ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs()
     296               << ", " << "processedUSecs = "<<m_audioInput->processedUSecs();
     297}
     298
     299void InputTest::readMore()
     300{
     301    if(!m_audioInput)
    219302        return;
    220     }
    221 
    222     audioInput = new QAudioInput(format,this);
    223     connect(audioInput, SIGNAL(notify()), SLOT(status()));
    224     connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(state(QAudio::State)));
    225     audioinfo  = new AudioInfo(this,audioInput);
    226     connect(audioinfo, SIGNAL(update()), SLOT(refreshDisplay()));
    227     audioinfo->start();
    228     audioInput->start(audioinfo);
    229 }
    230 
    231 InputTest::~InputTest() {}
    232 
    233 void InputTest::status()
    234 {
    235     qWarning()<<"bytesReady = "<<audioInput->bytesReady()<<" bytes, elapsedUSecs = "<<audioInput->elapsedUSecs()<<", processedUSecs = "<<audioInput->processedUSecs();
    236 }
    237 
    238 void InputTest::readMore()
    239 {
    240     if(!audioInput)
    241         return;
    242     qint64 len = audioInput->bytesReady();
     303    qint64 len = m_audioInput->bytesReady();
    243304    if(len > 4096)
    244305        len = 4096;
    245     qint64 l = input->read(buffer,len);
     306    qint64 l = m_input->read(m_buffer.data(), len);
    246307    if(l > 0) {
    247         audioinfo->write(buffer,l);
     308        m_audioInfo->write(m_buffer.constData(), l);
    248309    }
    249310}
     
    252313{
    253314    // Change bewteen pull and push modes
    254     audioInput->stop();
    255 
    256     if (pullMode) {
    257         button->setText(tr("Click for Pull Mode"));
    258         input = audioInput->start();
    259         connect(input, SIGNAL(readyRead()), SLOT(readMore()));
    260         pullMode = false;
     315    m_audioInput->stop();
     316
     317    if (m_pullMode) {
     318        m_modeButton->setText(PullModeLabel);
     319        m_input = m_audioInput->start();
     320        connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
     321        m_pullMode = false;
    261322    } else {
    262         button->setText(tr("Click for Push Mode"));
    263         pullMode = true;
    264         audioInput->start(audioinfo);
    265     }
     323        m_modeButton->setText(PushModeLabel);
     324        m_pullMode = true;
     325        m_audioInput->start(m_audioInfo);
     326    }
     327
     328    m_suspendResumeButton->setText(SuspendLabel);
    266329}
    267330
     
    269332{
    270333    // toggle suspend/resume
    271     if(audioInput->state() == QAudio::SuspendedState) {
     334    if(m_audioInput->state() == QAudio::SuspendedState) {
    272335        qWarning() << "status: Suspended, resume()";
    273         audioInput->resume();
    274         button2->setText("Click To Suspend");
    275     } else if (audioInput->state() == QAudio::ActiveState) {
     336        m_audioInput->resume();
     337        m_suspendResumeButton->setText(SuspendLabel);
     338    } else if (m_audioInput->state() == QAudio::ActiveState) {
    276339        qWarning() << "status: Active, suspend()";
    277         audioInput->suspend();
    278         button2->setText("Click To Resume");
    279     } else if (audioInput->state() == QAudio::StoppedState) {
     340        m_audioInput->suspend();
     341        m_suspendResumeButton->setText(ResumeLabel);
     342    } else if (m_audioInput->state() == QAudio::StoppedState) {
    280343        qWarning() << "status: Stopped, resume()";
    281         audioInput->resume();
    282         button2->setText("Click To Suspend");
    283     } else if (audioInput->state() == QAudio::IdleState) {
     344        m_audioInput->resume();
     345        m_suspendResumeButton->setText(SuspendLabel);
     346    } else if (m_audioInput->state() == QAudio::IdleState) {
    284347        qWarning() << "status: IdleState";
    285348    }
    286349}
    287350
    288 void InputTest::state(QAudio::State state)
    289 {
    290     qWarning() << " state=" << state;
     351void InputTest::stateChanged(QAudio::State state)
     352{
     353    qWarning() << "state = " << state;
    291354}
    292355
    293356void InputTest::refreshDisplay()
    294357{
    295     canvas->setLevel(audioinfo->LinearMax());
    296     canvas->repaint();
    297 }
    298 
    299 void InputTest::deviceChanged(int idx)
    300 {
    301     audioinfo->stop();
    302     audioInput->stop();
    303     audioInput->disconnect(this);
    304     delete audioInput;
    305 
    306     device = deviceBox->itemData(idx).value<QAudioDeviceInfo>();
    307     audioInput = new QAudioInput(device, format, this);
    308     connect(audioInput, SIGNAL(notify()), SLOT(status()));
    309     connect(audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(state(QAudio::State)));
    310     audioinfo->start();
    311     audioInput->start(audioinfo);
    312 }
     358    m_canvas->setLevel(m_audioInfo->level());
     359    m_canvas->repaint();
     360}
     361
     362void InputTest::deviceChanged(int index)
     363{
     364    m_audioInfo->stop();
     365    m_audioInput->stop();
     366    m_audioInput->disconnect(this);
     367    delete m_audioInput;
     368
     369    m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
     370    createAudioInput();
     371}
  • trunk/examples/multimedia/audioinput/audioinput.h

    r651 r769  
    4646#include <QPushButton>
    4747#include <QComboBox>
     48#include <QByteArray>
    4849
    4950#include <qaudioinput.h>
     
    5354    Q_OBJECT
    5455public:
    55     AudioInfo(QObject *parent, QAudioInput *device);
     56    AudioInfo(const QAudioFormat &format, QObject *parent);
    5657    ~AudioInfo();
    5758
     
    5960    void stop();
    6061
    61     int LinearMax();
     62    qreal level() const { return m_level; }
    6263
    6364    qint64 readData(char *data, qint64 maxlen);
    6465    qint64 writeData(const char *data, qint64 len);
    6566
    66     QAudioInput *input;
    67 
    6867private:
    69     int m_maxValue;
     68    const QAudioFormat m_format;
     69    quint16 m_maxAmplitude;
     70    qreal m_level; // 0.0 <= m_level <= 1.0
    7071
    7172signals:
     
    8182    RenderArea(QWidget *parent = 0);
    8283
    83     void setLevel(int value);
     84    void setLevel(qreal value);
    8485
    8586protected:
     
    8788
    8889private:
    89     int level;
    90     QPixmap pixmap;
     90    qreal m_level;
     91    QPixmap m_pixmap;
    9192};
    9293
     
    9899    ~InputTest();
    99100
     101private:
     102    void initializeWindow();
     103    void initializeAudio();
     104    void createAudioInput();
     105
    100106private slots:
    101107    void refreshDisplay();
    102     void status();
     108    void notified();
    103109    void readMore();
    104110    void toggleMode();
    105111    void toggleSuspend();
    106     void state(QAudio::State s);
    107     void deviceChanged(int idx);
     112    void stateChanged(QAudio::State state);
     113    void deviceChanged(int index);
    108114
    109115private:
    110     AudioInfo *audioinfo;
    111     QAudioDeviceInfo device;
    112     QAudioFormat format;
    113     QAudioInput *audioInput;
    114     QIODevice *input;
    115     RenderArea *canvas;
     116    // Owned by layout
     117    RenderArea *m_canvas;
     118    QPushButton *m_modeButton;
     119    QPushButton *m_suspendResumeButton;
     120    QComboBox *m_deviceBox;
    116121
    117     bool pullMode;
     122    QAudioDeviceInfo m_device;
     123    AudioInfo *m_audioInfo;
     124    QAudioFormat m_format;
     125    QAudioInput *m_audioInput;
     126    QIODevice *m_input;
     127    bool m_pullMode;
     128    QByteArray m_buffer;
    118129
    119     QPushButton *button;
    120     QPushButton *button2;
    121     QComboBox *deviceBox;
    122 
    123     char *buffer;
     130    static const QString PushModeLabel;
     131    static const QString PullModeLabel;
     132    static const QString SuspendLabel;
     133    static const QString ResumeLabel;
    124134};
    125135
  • trunk/examples/multimedia/audioinput/audioinput.pro

    r561 r769  
    1313symbian {
    1414    TARGET.UID3 = 0xA000D7BF
     15    TARGET.CAPABILITY += UserEnvironment
    1516    include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
    1617}
  • trunk/examples/multimedia/audiooutput/audiooutput.cpp

    r651 r769  
    4545#include <QAudioOutput>
    4646#include <QAudioDeviceInfo>
     47#include <QtCore/qmath.h>
     48#include <QtCore/qendian.h>
    4749#include "audiooutput.h"
    4850
    49 #ifndef M_PI
    50 #define M_PI 3.14159265358979323846
    51 #endif
    52 
    53 #define SECONDS     1
    54 #define FREQ        600
    55 #define SYSTEM_FREQ 44100
    56 
    57 Generator::Generator(QObject *parent)
    58     :QIODevice( parent )
    59 {
    60     finished = false;
    61     buffer = new char[SECONDS*SYSTEM_FREQ*4+1000];
    62     t=buffer;
    63     len=fillData(t,FREQ,SECONDS); /* mono FREQHz sine */
    64     pos   = 0;
    65     total = len;
     51const QString AudioTest::PushModeLabel(tr("Enable push mode"));
     52const QString AudioTest::PullModeLabel(tr("Enable pull mode"));
     53const QString AudioTest::SuspendLabel(tr("Suspend playback"));
     54const QString AudioTest::ResumeLabel(tr("Resume playback"));
     55
     56const int DurationSeconds = 1;
     57const int ToneFrequencyHz = 600;
     58const int DataFrequencyHz = 44100;
     59const int BufferSize      = 32768;
     60
     61
     62Generator::Generator(const QAudioFormat &format,
     63                     qint64 durationUs,
     64                     int frequency,
     65                     QObject *parent)
     66    :   QIODevice(parent)
     67    ,   m_pos(0)
     68{
     69    generateData(format, durationUs, frequency);
    6670}
    6771
    6872Generator::~Generator()
    6973{
    70     delete [] buffer;
     74
    7175}
    7276
     
    7882void Generator::stop()
    7983{
     84    m_pos = 0;
    8085    close();
    8186}
    8287
    83 int Generator::putShort(char *t, unsigned int value)
    84 {
    85     *(unsigned char *)(t++)=value&255;
    86     *(unsigned char *)(t)=(value/256)&255;
    87     return 2;
    88 }
    89 
    90 int Generator::fillData(char *start, int frequency, int seconds)
    91 {
    92     int i, len=0;
    93     int value;
    94     for(i=0; i<seconds*SYSTEM_FREQ; i++) {
    95         value=(int)(32767.0*sin(2.0*M_PI*((double)(i))*(double)(frequency)/SYSTEM_FREQ));
    96         putShort(start, value);
    97         start += 4;
    98         len+=2;
    99     }
    100     return len;
    101 }
    102 
    103 qint64 Generator::readData(char *data, qint64 maxlen)
    104 {
    105     int len = maxlen;
    106     if (len > 16384)
    107         len = 16384;
    108 
    109     if (len < (SECONDS*SYSTEM_FREQ*2)-pos) {
    110         // Normal
    111         memcpy(data,t+pos,len);
    112         pos+=len;
    113         return len;
    114     } else {
    115         // Whats left and reset to start
    116         qint64 left = (SECONDS*SYSTEM_FREQ*2)-pos;
    117         memcpy(data,t+pos,left);
    118         pos=0;
    119         return left;
    120     }
     88void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int frequency)
     89{
     90    const int channelBytes = format.sampleSize() / 8;
     91    const int sampleBytes = format.channels() * channelBytes;
     92
     93    qint64 length = (format.frequency() * format.channels() * (format.sampleSize() / 8))
     94                        * durationUs / 100000;
     95
     96    Q_ASSERT(length % sampleBytes == 0);
     97    Q_UNUSED(sampleBytes) // suppress warning in release builds
     98
     99    m_buffer.resize(length);
     100    unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
     101    int sampleIndex = 0;
     102
     103    while (length) {
     104        const qreal x = qSin(2 * M_PI * frequency * qreal(sampleIndex % format.frequency()) / format.frequency());
     105        for (int i=0; i<format.channels(); ++i) {
     106            if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
     107                const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
     108                *reinterpret_cast<quint8*>(ptr) = value;
     109            } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
     110                const qint8 value = static_cast<qint8>(x * 127);
     111                *reinterpret_cast<quint8*>(ptr) = value;
     112            } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
     113                quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
     114                if (format.byteOrder() == QAudioFormat::LittleEndian)
     115                    qToLittleEndian<quint16>(value, ptr);
     116                else
     117                    qToBigEndian<quint16>(value, ptr);
     118            } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
     119                qint16 value = static_cast<qint16>(x * 32767);
     120                if (format.byteOrder() == QAudioFormat::LittleEndian)
     121                    qToLittleEndian<qint16>(value, ptr);
     122                else
     123                    qToBigEndian<qint16>(value, ptr);
     124            }
     125
     126            ptr += channelBytes;
     127            length -= channelBytes;
     128        }
     129        ++sampleIndex;
     130    }
     131}
     132
     133qint64 Generator::readData(char *data, qint64 len)
     134{
     135    qint64 total = 0;
     136    while (len - total) {
     137        const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
     138        memcpy(data, m_buffer.constData() + m_pos, chunk);
     139        m_pos = (m_pos + chunk) % m_buffer.size();
     140        total += chunk;
     141    }
     142    return total;
    121143}
    122144
     
    129151}
    130152
     153qint64 Generator::bytesAvailable() const
     154{
     155    return m_buffer.size() + QIODevice::bytesAvailable();
     156}
     157
    131158AudioTest::AudioTest()
    132 {
    133     QWidget *window = new QWidget;
    134     QVBoxLayout* layout = new QVBoxLayout;
    135 
    136     deviceBox = new QComboBox(this);
     159    :   m_pullTimer(new QTimer(this))
     160    ,   m_modeButton(0)
     161    ,   m_suspendResumeButton(0)
     162    ,   m_deviceBox(0)
     163    ,   m_device(QAudioDeviceInfo::defaultOutputDevice())
     164    ,   m_generator(0)
     165    ,   m_audioOutput(0)
     166    ,   m_output(0)
     167    ,   m_buffer(BufferSize, 0)
     168{
     169    initializeWindow();
     170    initializeAudio();
     171}
     172
     173void AudioTest::initializeWindow()
     174{
     175    QScopedPointer<QWidget> window(new QWidget);
     176    QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
     177
     178    m_deviceBox = new QComboBox(this);
    137179    foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
    138         deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
    139     connect(deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int)));
    140     layout->addWidget(deviceBox);
    141 
    142     button = new QPushButton(this);
    143     button->setText(tr("Click for Push Mode"));
    144     connect(button,SIGNAL(clicked()),SLOT(toggle()));
    145     layout->addWidget(button);
    146 
    147     button2 = new QPushButton(this);
    148     button2->setText(tr("Click To Suspend"));
    149     connect(button2,SIGNAL(clicked()),SLOT(togglePlay()));
    150     layout->addWidget(button2);
    151 
    152     window->setLayout(layout);
    153     setCentralWidget(window);
    154     window->show();
    155 
    156     buffer = new char[BUFFER_SIZE];
    157 
    158     gen = new Generator(this);
    159 
    160     pullMode = true;
    161 
    162     timer = new QTimer(this);
    163     connect(timer,SIGNAL(timeout()),SLOT(writeMore()));
    164 
    165     gen->start();
    166 
    167     settings.setFrequency(SYSTEM_FREQ);
    168     settings.setChannels(1);
    169     settings.setSampleSize(16);
    170     settings.setCodec("audio/pcm");
    171     settings.setByteOrder(QAudioFormat::LittleEndian);
    172     settings.setSampleType(QAudioFormat::SignedInt);
     180        m_deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
     181    connect(m_deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int)));
     182    layout->addWidget(m_deviceBox);
     183
     184    m_modeButton = new QPushButton(this);
     185    m_modeButton->setText(PushModeLabel);
     186    connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
     187    layout->addWidget(m_modeButton);
     188
     189    m_suspendResumeButton = new QPushButton(this);
     190    m_suspendResumeButton->setText(SuspendLabel);
     191    connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
     192    layout->addWidget(m_suspendResumeButton);
     193
     194    window->setLayout(layout.data());
     195    layout.take(); // ownership transferred
     196
     197    setCentralWidget(window.data());
     198    QWidget *const windowPtr = window.take(); // ownership transferred
     199    windowPtr->show();
     200}
     201
     202void AudioTest::initializeAudio()
     203{
     204    connect(m_pullTimer, SIGNAL(timeout()), SLOT(pullTimerExpired()));
     205
     206    m_pullMode = true;
     207
     208    m_format.setFrequency(DataFrequencyHz);
     209    m_format.setChannels(1);
     210    m_format.setSampleSize(16);
     211    m_format.setCodec("audio/pcm");
     212    m_format.setByteOrder(QAudioFormat::LittleEndian);
     213    m_format.setSampleType(QAudioFormat::SignedInt);
    173214
    174215    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
    175     if (!info.isFormatSupported(settings)) {
    176         qWarning()<<"default format not supported try to use nearest";
    177         settings = info.nearestFormat(settings);
    178     }
    179 
    180     if(settings.sampleSize() != 16) {
    181         qWarning()<<"audio device doesn't support 16 bit samples, example cannot run";
    182         button->setDisabled(true);
    183         button2->setDisabled(true);
    184         audioOutput = 0;
    185         return;
    186     }
    187 
    188     audioOutput = new QAudioOutput(settings,this);
    189     connect(audioOutput,SIGNAL(notify()),SLOT(status()));
    190     connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State)));
    191 
    192     audioOutput->start(gen);
     216    if (!info.isFormatSupported(m_format)) {
     217        qWarning() << "Default format not supported - trying to use nearest";
     218        m_format = info.nearestFormat(m_format);
     219    }
     220
     221    m_generator = new Generator(m_format, DurationSeconds*1000000, ToneFrequencyHz, this);
     222
     223    createAudioOutput();
     224}
     225
     226void AudioTest::createAudioOutput()
     227{
     228    delete m_audioOutput;
     229    m_audioOutput = 0;
     230    m_audioOutput = new QAudioOutput(m_device, m_format, this);
     231    connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
     232    connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
     233    m_generator->start();
     234    m_audioOutput->start(m_generator);
    193235}
    194236
    195237AudioTest::~AudioTest()
    196238{
    197     delete [] buffer;
    198 }
    199 
    200 void AudioTest::deviceChanged(int idx)
    201 {
    202     timer->stop();
    203     gen->stop();
    204     audioOutput->stop();
    205     audioOutput->disconnect(this);
    206     delete audioOutput;
    207 
    208     device = deviceBox->itemData(idx).value<QAudioDeviceInfo>();
    209     audioOutput = new QAudioOutput(device,settings,this);
    210     connect(audioOutput,SIGNAL(notify()),SLOT(status()));
    211     connect(audioOutput,SIGNAL(stateChanged(QAudio::State)),SLOT(state(QAudio::State)));
    212     gen->start();
    213     audioOutput->start(gen);
    214 }
    215 
    216 void AudioTest::status()
    217 {
    218     qWarning() << "byteFree = " << audioOutput->bytesFree() << " bytes, elapsedUSecs = " << audioOutput->elapsedUSecs() << ", processedUSecs = " << audioOutput->processedUSecs();
    219 }
    220 
    221 void AudioTest::writeMore()
    222 {
    223     if (!audioOutput)
    224         return;
    225 
    226     if (audioOutput->state() == QAudio::StoppedState)
    227         return;
    228 
    229     int    l;
    230     int    out;
    231 
    232     int chunks = audioOutput->bytesFree()/audioOutput->periodSize();
    233     while(chunks) {
    234        l = gen->read(buffer,audioOutput->periodSize());
    235        if (l > 0)
    236            out = output->write(buffer,l);
    237        if (l != audioOutput->periodSize())
    238            break;
    239        chunks--;
    240     }
    241 }
    242 
    243 void AudioTest::toggle()
    244 {
    245     // Change between pull and push modes
    246 
    247     timer->stop();
    248     audioOutput->stop();
    249 
    250     if (pullMode) {
    251         button->setText("Click for Pull Mode");
    252         output = audioOutput->start();
    253         pullMode = false;
    254         timer->start(20);
     239
     240}
     241
     242void AudioTest::deviceChanged(int index)
     243{
     244    m_pullTimer->stop();
     245    m_generator->stop();
     246    m_audioOutput->stop();
     247    m_audioOutput->disconnect(this);
     248    m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
     249    createAudioOutput();
     250}
     251
     252void AudioTest::notified()
     253{
     254    qWarning() << "bytesFree = " << m_audioOutput->bytesFree()
     255               << ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs()
     256               << ", " << "processedUSecs = " << m_audioOutput->processedUSecs();
     257}
     258
     259void AudioTest::pullTimerExpired()
     260{
     261    if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
     262        int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize();
     263        while (chunks) {
     264           const qint64 len = m_generator->read(m_buffer.data(), m_audioOutput->periodSize());
     265           if (len)
     266               m_output->write(m_buffer.data(), len);
     267           if (len != m_audioOutput->periodSize())
     268               break;
     269           --chunks;
     270        }
     271    }
     272}
     273
     274void AudioTest::toggleMode()
     275{
     276    m_pullTimer->stop();
     277    m_audioOutput->stop();
     278
     279    if (m_pullMode) {
     280        m_modeButton->setText(PullModeLabel);
     281        m_output = m_audioOutput->start();
     282        m_pullMode = false;
     283        m_pullTimer->start(20);
    255284    } else {
    256         button->setText("Click for Push Mode");
    257         pullMode = true;
    258         audioOutput->start(gen);
    259     }
    260 }
    261 
    262 void AudioTest::togglePlay()
    263 {
    264     // toggle suspend/resume
    265     if (audioOutput->state() == QAudio::SuspendedState) {
     285        m_modeButton->setText(PushModeLabel);
     286        m_pullMode = true;
     287        m_audioOutput->start(m_generator);
     288    }
     289
     290    m_suspendResumeButton->setText(SuspendLabel);
     291}
     292
     293void AudioTest::toggleSuspendResume()
     294{
     295    if (m_audioOutput->state() == QAudio::SuspendedState) {
    266296        qWarning() << "status: Suspended, resume()";
    267         audioOutput->resume();
    268         button2->setText("Click To Suspend");
    269     } else if (audioOutput->state() == QAudio::ActiveState) {
     297        m_audioOutput->resume();
     298        m_suspendResumeButton->setText(SuspendLabel);
     299    } else if (m_audioOutput->state() == QAudio::ActiveState) {
    270300        qWarning() << "status: Active, suspend()";
    271         audioOutput->suspend();
    272         button2->setText("Click To Resume");
    273     } else if (audioOutput->state() == QAudio::StoppedState) {
     301        m_audioOutput->suspend();
     302        m_suspendResumeButton->setText(ResumeLabel);
     303    } else if (m_audioOutput->state() == QAudio::StoppedState) {
    274304        qWarning() << "status: Stopped, resume()";
    275         audioOutput->resume();
    276         button2->setText("Click To Suspend");
    277     } else if (audioOutput->state() == QAudio::IdleState) {
     305        m_audioOutput->resume();
     306        m_suspendResumeButton->setText(SuspendLabel);
     307    } else if (m_audioOutput->state() == QAudio::IdleState) {
    278308        qWarning() << "status: IdleState";
    279309    }
    280310}
    281311
    282 void AudioTest::state(QAudio::State state)
    283 {
    284     qWarning() << " state=" << state;
    285 }
     312void AudioTest::stateChanged(QAudio::State state)
     313{
     314    qWarning() << "state = " << state;
     315}
  • trunk/examples/multimedia/audiooutput/audiooutput.h

    r651 r769  
    4242#include <math.h>
    4343
    44 #define BUFFER_SIZE 32768
    45 
    4644#include <QObject>
    4745#include <QMainWindow>
     
    5048#include <QPushButton>
    5149#include <QComboBox>
     50#include <QByteArray>
    5251
    5352#include <QAudioOutput>
     
    5756    Q_OBJECT
    5857public:
    59     Generator(QObject *parent);
     58    Generator(const QAudioFormat &format, qint64 durationUs, int frequency, QObject *parent);
    6059    ~Generator();
    6160
     
    6362    void stop();
    6463
    65     char *t;
    66     int  len;
    67     int  pos;
    68     int  total;
    69     char *buffer;
    70     bool finished;
    71     int  chunk_size;
    72 
    7364    qint64 readData(char *data, qint64 maxlen);
    7465    qint64 writeData(const char *data, qint64 len);
     66    qint64 bytesAvailable() const;
    7567
    7668private:
    77     int putShort(char *t, unsigned int value);
    78     int fillData(char *start, int frequency, int seconds);
     69    void generateData(const QAudioFormat &format, qint64 durationUs, int frequency);
     70
     71private:
     72    qint64 m_pos;
     73    QByteArray m_buffer;
    7974};
    8075
     
    8681    ~AudioTest();
    8782
    88     QAudioDeviceInfo  device;
    89     Generator*        gen;
    90     QAudioOutput*     audioOutput;
    91     QIODevice*        output;
    92     QTimer*           timer;
    93     QAudioFormat      settings;
     83private:
     84    void initializeWindow();
     85    void initializeAudio();
     86    void createAudioOutput();
    9487
    95     bool              pullMode;
    96     char*             buffer;
     88private:
     89    QTimer*          m_pullTimer;
    9790
    98     QPushButton*      button;
    99     QPushButton*      button2;
    100     QComboBox*     deviceBox;
     91    // Owned by layout
     92    QPushButton*     m_modeButton;
     93    QPushButton*     m_suspendResumeButton;
     94    QComboBox*       m_deviceBox;
     95
     96    QAudioDeviceInfo m_device;
     97    Generator*       m_generator;
     98    QAudioOutput*    m_audioOutput;
     99    QIODevice*       m_output; // not owned
     100    QAudioFormat     m_format;
     101
     102    bool             m_pullMode;
     103    QByteArray       m_buffer;
     104
     105    static const QString PushModeLabel;
     106    static const QString PullModeLabel;
     107    static const QString SuspendLabel;
     108    static const QString ResumeLabel;
    101109
    102110private slots:
    103     void status();
    104     void writeMore();
    105     void toggle();
    106     void togglePlay();
    107     void state(QAudio::State s);
    108     void deviceChanged(int idx);
     111    void notified();
     112    void pullTimerExpired();
     113    void toggleMode();
     114    void toggleSuspendResume();
     115    void stateChanged(QAudio::State state);
     116    void deviceChanged(int index);
    109117};
    110118
Note: See TracChangeset for help on using the changeset viewer.