Changeset 769 for trunk/examples/multimedia
- Timestamp:
- Aug 2, 2010, 9:27:30 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.6.3 (added) merged: 768 /branches/vendor/nokia/qt/current merged: 767 /branches/vendor/nokia/qt/4.6.2 removed
- Property svn:mergeinfo changed
-
trunk/examples/multimedia/audiodevices/audiodevices.cpp
r651 r769 44 44 45 45 #include "audiodevices.h" 46 47 // Utility functions for converting QAudioFormat fields into text 48 49 QString 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 66 QString 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 46 80 47 81 AudioDevicesBase::AudioDevicesBase(QWidget *parent, Qt::WFlags f) … … 68 102 connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int))); 69 103 connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int))); 104 connect(populateTableButton, SIGNAL(clicked()), SLOT(populateTable())); 70 105 71 106 modeBox->setCurrentIndex(0); … … 82 117 { 83 118 // 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(); 86 120 87 121 if (!deviceInfo.isNull()) { 88 122 if (deviceInfo.isFormatSupported(settings)) { 89 logOutput->append(tr("Success"));123 testResult->setText(tr("Success")); 90 124 nearestFreq->setText(""); 91 125 nearestChannel->setText(""); … … 96 130 } else { 97 131 QAudioFormat nearest = deviceInfo.nearestFormat(settings); 98 logOutput->append(tr("Failed"));132 testResult->setText(tr("Failed")); 99 133 nearestFreq->setText(QString("%1").arg(nearest.frequency())); 100 134 nearestChannel->setText(QString("%1").arg(nearest.channels())); 101 135 nearestCodec->setText(nearest.codec()); 102 136 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())); 124 139 } 125 140 } 126 141 else 127 logOutput->append(tr("No Device"));142 testResult->setText(tr("No Device")); 128 143 } 129 144 130 145 void AudioTest::modeChanged(int idx) 131 146 { 147 testResult->clear(); 148 132 149 // mode has changed 133 150 if (idx == 0) … … 139 156 foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode)) 140 157 deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo)); 158 159 deviceBox->setCurrentIndex(0); 160 deviceChanged(0); 141 161 } 142 162 143 163 void AudioTest::deviceChanged(int idx) 144 164 { 165 testResult->clear(); 166 145 167 if (deviceBox->count() == 0) 146 168 return; … … 181 203 sampleTypesBox->clear(); 182 204 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)); 200 210 201 211 endianBox->clear(); 202 212 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))); 213 215 if (endianz.size()) 214 216 settings.setByteOrder(endianz.at(0)); 217 218 allFormatsTable->clearContents(); 219 } 220 221 void 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 } 215 267 } 216 268 -
trunk/examples/multimedia/audiodevices/audiodevices.h
r651 r769 75 75 void endianChanged(int idx); 76 76 void test(); 77 void populateTable(); 78 77 79 }; 78 80 -
trunk/examples/multimedia/audiodevices/audiodevicesbase.ui
r561 r769 7 7 <x>0</x> 8 8 <y>0</y> 9 <width> 504</width>10 <height> 702</height>9 <width>679</width> 10 <height>598</height> 11 11 </rect> 12 12 </property> … … 17 17 <layout class="QVBoxLayout" name="verticalLayout"> 18 18 <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><i>Actual Settings</i></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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 123 <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 124 p, li { white-space: pre-wrap; } 125 </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> 126 <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Nearest Settings</span></p></body></html></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> 49 388 </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> 254 392 </item> 255 393 </layout> -
trunk/examples/multimedia/audiodevices/main.cpp
r651 r769 50 50 51 51 AudioTest audio; 52 #ifdef Q_OS_SYMBIAN 53 audio.showMaximized(); 54 #else 52 55 audio.show(); 56 #endif 53 57 54 58 return app.exec(); -
trunk/examples/multimedia/audioinput/audioinput.cpp
r651 r769 49 49 #include <QAudioDeviceInfo> 50 50 #include <QAudioInput> 51 52 #include <QtCore/qendian.h> 53 51 54 #include "audioinput.h" 52 55 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; 56 const QString InputTest::PushModeLabel(tr("Enable push mode")); 57 const QString InputTest::PullModeLabel(tr("Enable pull mode")); 58 const QString InputTest::SuspendLabel(tr("Suspend recording")); 59 const QString InputTest::ResumeLabel(tr("Resume recording")); 60 61 const int BufferSize = 4096; 62 63 AudioInfo::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 } 61 94 } 62 95 … … 85 118 qint64 AudioInfo::writeData(const char *data, qint64 len) 86 119 { 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 } 111 158 112 159 emit update(); 113 114 160 return len; 115 }116 117 int AudioInfo::LinearMax()118 {119 return m_maxValue;120 161 } 121 162 … … 126 167 setAutoFillBackground(true); 127 168 128 level = 0;169 m_level = 0; 129 170 setMinimumHeight(30); 130 171 setMinimumWidth(200); … … 140 181 painter.viewport().right()-20, 141 182 painter.viewport().bottom()-20)); 142 if ( level ==0)183 if (m_level == 0.0) 143 184 return; 144 185 145 186 painter.setPen(Qt::red); 146 187 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; 148 189 for (int i = 0; i < 10; ++i) { 149 190 int x1 = painter.viewport().left()+11; … … 158 199 } 159 200 160 void RenderArea::setLevel( intvalue)161 { 162 level = value;201 void RenderArea::setLevel(qreal value) 202 { 203 m_level = value; 163 204 repaint(); 164 205 } … … 166 207 167 208 InputTest::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 224 InputTest::~InputTest() {} 225 226 void 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); 176 235 QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); 177 236 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 260 void 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"); 207 270 208 271 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 283 void 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 292 void InputTest::notified() 293 { 294 qWarning() << "bytesReady = " << m_audioInput->bytesReady() 295 << ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs() 296 << ", " << "processedUSecs = "<<m_audioInput->processedUSecs(); 297 } 298 299 void InputTest::readMore() 300 { 301 if(!m_audioInput) 219 302 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(); 243 304 if(len > 4096) 244 305 len = 4096; 245 qint64 l = input->read(buffer,len);306 qint64 l = m_input->read(m_buffer.data(), len); 246 307 if(l > 0) { 247 audioinfo->write(buffer,l);308 m_audioInfo->write(m_buffer.constData(), l); 248 309 } 249 310 } … … 252 313 { 253 314 // 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; 261 322 } 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); 266 329 } 267 330 … … 269 332 { 270 333 // toggle suspend/resume 271 if( audioInput->state() == QAudio::SuspendedState) {334 if(m_audioInput->state() == QAudio::SuspendedState) { 272 335 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) { 276 339 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) { 280 343 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) { 284 347 qWarning() << "status: IdleState"; 285 348 } 286 349 } 287 350 288 void InputTest::state (QAudio::State state)289 { 290 qWarning() << " state=" << state;351 void InputTest::stateChanged(QAudio::State state) 352 { 353 qWarning() << "state = " << state; 291 354 } 292 355 293 356 void InputTest::refreshDisplay() 294 357 { 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 362 void 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 46 46 #include <QPushButton> 47 47 #include <QComboBox> 48 #include <QByteArray> 48 49 49 50 #include <qaudioinput.h> … … 53 54 Q_OBJECT 54 55 public: 55 AudioInfo( QObject *parent, QAudioInput *device);56 AudioInfo(const QAudioFormat &format, QObject *parent); 56 57 ~AudioInfo(); 57 58 … … 59 60 void stop(); 60 61 61 int LinearMax();62 qreal level() const { return m_level; } 62 63 63 64 qint64 readData(char *data, qint64 maxlen); 64 65 qint64 writeData(const char *data, qint64 len); 65 66 66 QAudioInput *input;67 68 67 private: 69 int m_maxValue; 68 const QAudioFormat m_format; 69 quint16 m_maxAmplitude; 70 qreal m_level; // 0.0 <= m_level <= 1.0 70 71 71 72 signals: … … 81 82 RenderArea(QWidget *parent = 0); 82 83 83 void setLevel( intvalue);84 void setLevel(qreal value); 84 85 85 86 protected: … … 87 88 88 89 private: 89 intlevel;90 QPixmap pixmap;90 qreal m_level; 91 QPixmap m_pixmap; 91 92 }; 92 93 … … 98 99 ~InputTest(); 99 100 101 private: 102 void initializeWindow(); 103 void initializeAudio(); 104 void createAudioInput(); 105 100 106 private slots: 101 107 void refreshDisplay(); 102 void status();108 void notified(); 103 109 void readMore(); 104 110 void toggleMode(); 105 111 void toggleSuspend(); 106 void state (QAudio::State s);107 void deviceChanged(int i dx);112 void stateChanged(QAudio::State state); 113 void deviceChanged(int index); 108 114 109 115 private: 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; 116 121 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; 118 129 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; 124 134 }; 125 135 -
trunk/examples/multimedia/audioinput/audioinput.pro
r561 r769 13 13 symbian { 14 14 TARGET.UID3 = 0xA000D7BF 15 TARGET.CAPABILITY += UserEnvironment 15 16 include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) 16 17 } -
trunk/examples/multimedia/audiooutput/audiooutput.cpp
r651 r769 45 45 #include <QAudioOutput> 46 46 #include <QAudioDeviceInfo> 47 #include <QtCore/qmath.h> 48 #include <QtCore/qendian.h> 47 49 #include "audiooutput.h" 48 50 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; 51 const QString AudioTest::PushModeLabel(tr("Enable push mode")); 52 const QString AudioTest::PullModeLabel(tr("Enable pull mode")); 53 const QString AudioTest::SuspendLabel(tr("Suspend playback")); 54 const QString AudioTest::ResumeLabel(tr("Resume playback")); 55 56 const int DurationSeconds = 1; 57 const int ToneFrequencyHz = 600; 58 const int DataFrequencyHz = 44100; 59 const int BufferSize = 32768; 60 61 62 Generator::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); 66 70 } 67 71 68 72 Generator::~Generator() 69 73 { 70 delete [] buffer; 74 71 75 } 72 76 … … 78 82 void Generator::stop() 79 83 { 84 m_pos = 0; 80 85 close(); 81 86 } 82 87 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 } 88 void 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 133 qint64 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; 121 143 } 122 144 … … 129 151 } 130 152 153 qint64 Generator::bytesAvailable() const 154 { 155 return m_buffer.size() + QIODevice::bytesAvailable(); 156 } 157 131 158 AudioTest::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 173 void AudioTest::initializeWindow() 174 { 175 QScopedPointer<QWidget> window(new QWidget); 176 QScopedPointer<QVBoxLayout> layout(new QVBoxLayout); 177 178 m_deviceBox = new QComboBox(this); 137 179 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 202 void 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); 173 214 174 215 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 226 void 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); 193 235 } 194 236 195 237 AudioTest::~AudioTest() 196 238 { 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 242 void 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 252 void AudioTest::notified() 253 { 254 qWarning() << "bytesFree = " << m_audioOutput->bytesFree() 255 << ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs() 256 << ", " << "processedUSecs = " << m_audioOutput->processedUSecs(); 257 } 258 259 void 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 274 void 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); 255 284 } 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 293 void AudioTest::toggleSuspendResume() 294 { 295 if (m_audioOutput->state() == QAudio::SuspendedState) { 266 296 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) { 270 300 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) { 274 304 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) { 278 308 qWarning() << "status: IdleState"; 279 309 } 280 310 } 281 311 282 void AudioTest::state (QAudio::State state)283 { 284 qWarning() << " state=" << state;285 } 312 void AudioTest::stateChanged(QAudio::State state) 313 { 314 qWarning() << "state = " << state; 315 } -
trunk/examples/multimedia/audiooutput/audiooutput.h
r651 r769 42 42 #include <math.h> 43 43 44 #define BUFFER_SIZE 3276845 46 44 #include <QObject> 47 45 #include <QMainWindow> … … 50 48 #include <QPushButton> 51 49 #include <QComboBox> 50 #include <QByteArray> 52 51 53 52 #include <QAudioOutput> … … 57 56 Q_OBJECT 58 57 public: 59 Generator( QObject *parent);58 Generator(const QAudioFormat &format, qint64 durationUs, int frequency, QObject *parent); 60 59 ~Generator(); 61 60 … … 63 62 void stop(); 64 63 65 char *t;66 int len;67 int pos;68 int total;69 char *buffer;70 bool finished;71 int chunk_size;72 73 64 qint64 readData(char *data, qint64 maxlen); 74 65 qint64 writeData(const char *data, qint64 len); 66 qint64 bytesAvailable() const; 75 67 76 68 private: 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 71 private: 72 qint64 m_pos; 73 QByteArray m_buffer; 79 74 }; 80 75 … … 86 81 ~AudioTest(); 87 82 88 QAudioDeviceInfo device; 89 Generator* gen; 90 QAudioOutput* audioOutput; 91 QIODevice* output; 92 QTimer* timer; 93 QAudioFormat settings; 83 private: 84 void initializeWindow(); 85 void initializeAudio(); 86 void createAudioOutput(); 94 87 95 bool pullMode; 96 char* buffer;88 private: 89 QTimer* m_pullTimer; 97 90 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; 101 109 102 110 private slots: 103 void status();104 void writeMore();105 void toggle ();106 void toggle Play();107 void state (QAudio::State s);108 void deviceChanged(int i dx);111 void notified(); 112 void pullTimerExpired(); 113 void toggleMode(); 114 void toggleSuspendResume(); 115 void stateChanged(QAudio::State state); 116 void deviceChanged(int index); 109 117 }; 110 118
Note:
See TracChangeset
for help on using the changeset viewer.