prefportaudio.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #include <QtGui>
  2. #include "prefportaudio.h"
  3. PrefPortaudio::PrefPortaudio(Ui::PrefDialog *ui, QObject *parent) :
  4. QObject(parent),
  5. _ui(ui)
  6. {
  7. connect(_ui->PaRingFileBtn, SIGNAL(clicked()), this, SLOT(ringFileChoose()));
  8. connect(_ui->PaHoldFileBtn, SIGNAL(clicked()), this, SLOT(holdFileChoose()));
  9. connect(_ui->PaIndevCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(indevChangeDev(int)));
  10. connect(_ui->PaOutdevCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(outdevChangeDev(int)));
  11. connect(_ui->PaRingdevCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(ringdevChangeDev(int)));
  12. connect(_ui->PaRingdevTestBtn, SIGNAL(clicked()), this, SLOT(ringdevTest()));
  13. connect(_ui->PaLoopTestBtn, SIGNAL(clicked()), this, SLOT(loopTest()));
  14. connect(_ui->PaRefreshDevListBtn, SIGNAL(clicked()), this, SLOT(refreshDevList()));
  15. connect(_ui->btnApplyPreprocessor, SIGNAL(toggled(bool)), this, SLOT(applyPreprocessors(bool)));
  16. }
  17. void PrefPortaudio::applyPreprocessors(bool state)
  18. {
  19. QStringList cmds;
  20. if (!state)
  21. {
  22. cmds.append("stop");
  23. }
  24. else
  25. {
  26. if (_ui->checkAECRead->isChecked()) cmds.append(QString("recho_cancel=%1").arg(_ui->spinAECTail->value()));
  27. if (_ui->checkAECWrite->isChecked()) cmds.append(QString("wecho_cancel=%1").arg(_ui->spinAECTail->value()));
  28. if (_ui->checkESRead->isChecked()) cmds.append(QString("recho_suppress=%1").arg(_ui->spinESDb->value()));
  29. if (_ui->checkESWrite->isChecked()) cmds.append(QString("wecho_suppress=%1").arg(_ui->spinESDb->value()));
  30. if (_ui->checkNSRead->isChecked()) cmds.append(QString("rnoise_suppress=%1").arg(_ui->spinNSDb->value()));
  31. if (_ui->checkNSWrite->isChecked()) cmds.append(QString("wnoise_suppress=%1").arg(_ui->spinNSDb->value()));
  32. if (_ui->checkAGCRead->isChecked()) cmds.append(QString("ragc=%1").arg(_ui->spinAGC->value()));
  33. if (_ui->checkAGCWrite->isChecked()) cmds.append(QString("wagc=%1").arg(_ui->spinAGC->value()));
  34. }
  35. emit preprocessorsApplied(cmds);
  36. }
  37. void PrefPortaudio::ringdevTest()
  38. {
  39. QString result;
  40. if (g_FSHost->sendCmd("pa", QString("play %1/.fscomm/sounds/test.wav 0").arg(QDir::homePath()).toAscii().constData(), &result) != SWITCH_STATUS_SUCCESS)
  41. {
  42. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error testing ringdev on mod_portaudio! %s\n",
  43. result.toAscii().constData());
  44. }
  45. }
  46. void PrefPortaudio::loopTest()
  47. {
  48. QString result;
  49. _ui->PaLoopTestBtn->setEnabled(false);
  50. if (g_FSHost->sendCmd("pa", "looptest", &result) != SWITCH_STATUS_SUCCESS)
  51. {
  52. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error running looptest on mod_portaudio! %s\n",
  53. result.toAscii().constData());
  54. }
  55. _ui->PaLoopTestBtn->setEnabled(true);
  56. }
  57. void PrefPortaudio::refreshDevList()
  58. {
  59. QString result;
  60. if (g_FSHost->sendCmd("pa", "rescan", &result) != SWITCH_STATUS_SUCCESS)
  61. {
  62. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error rescaning sound device on mod_portaudio! %s\n",
  63. result.toAscii().constData());
  64. }
  65. //clear combox
  66. _ui->PaIndevCombo->clear();
  67. _ui->PaOutdevCombo->clear();
  68. _ui->PaRingdevCombo->clear();
  69. getPaDevlist();
  70. }
  71. void PrefPortaudio::indevChangeDev(int index)
  72. {
  73. QString result;
  74. int dev = _ui->PaIndevCombo->itemData(index, Qt::UserRole).toInt();
  75. if (g_FSHost->sendCmd("pa", QString("indev #%1").arg(dev).toAscii().constData(), &result) != SWITCH_STATUS_SUCCESS)
  76. {
  77. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting ringdev to #%d on mod_portaudio!\n", dev);
  78. QMessageBox::critical(0, tr("Unable to change device."),
  79. tr("There was an error changing the ringdev.\nPlease report this bug."),
  80. QMessageBox::Ok);
  81. }
  82. }
  83. void PrefPortaudio::ringdevChangeDev(int index)
  84. {
  85. QString result;
  86. int dev = _ui->PaRingdevCombo->itemData(index, Qt::UserRole).toInt();
  87. if (g_FSHost->sendCmd("pa", QString("ringdev #%1").arg(dev).toAscii().constData(), &result) != SWITCH_STATUS_SUCCESS)
  88. {
  89. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting ringdev to #%d on mod_portaudio!\n", dev);
  90. QMessageBox::critical(0, tr("Unable to change device."),
  91. tr("There was an error changing the ringdev.\nPlease report this bug."),
  92. QMessageBox::Ok);
  93. }
  94. }
  95. void PrefPortaudio::outdevChangeDev(int index)
  96. {
  97. QString result;
  98. int dev = _ui->PaRingdevCombo->itemData(index, Qt::UserRole).toInt();
  99. if (g_FSHost->sendCmd("pa", QString("outdev #%1").arg(dev).toAscii().constData(), &result) != SWITCH_STATUS_SUCCESS)
  100. {
  101. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error setting outdev to #%d on mod_portaudio!\n", dev);
  102. QMessageBox::critical(0, tr("Unable to change device."),
  103. tr("There was an error changing the outdev.\nPlease report this bug."),
  104. QMessageBox::Ok);
  105. }
  106. }
  107. void PrefPortaudio::holdFileChoose()
  108. {
  109. QString fileName = QFileDialog::getOpenFileName(0,
  110. tr("Select file"),
  111. QDir::homePath(),
  112. NULL);
  113. if (!fileName.isNull())
  114. _ui->PaHoldFileEdit->setText(fileName);
  115. }
  116. void PrefPortaudio::ringFileChoose()
  117. {
  118. QString fileName = QFileDialog::getOpenFileName(0,
  119. tr("Select file"),
  120. QDir::homePath(),
  121. NULL);
  122. if (!fileName.isNull())
  123. _ui->PaRingFileEdit->setText(fileName);
  124. }
  125. void PrefPortaudio::writeConfig()
  126. {
  127. /* We can do better error control here, can't we? */
  128. ISettings *_settings = new ISettings();
  129. QDomElement cfg = _settings->getConfigNode("portaudio.conf");
  130. QDomNodeList nl = cfg.elementsByTagName("param");
  131. for (int i = 0; i < nl.count(); i++) {
  132. QDomAttr var = nl.at(i).toElement().attributeNode("name");
  133. QDomAttr val = nl.at(i).toElement().attributeNode("value");
  134. if (var.value() == "indev") {
  135. val.setValue(QString::number(_ui->PaIndevCombo->itemData(_ui->PaIndevCombo->currentIndex(), Qt::UserRole).toInt()));
  136. }
  137. if (var.value() == "outdev") {
  138. val.setValue(QString::number(_ui->PaOutdevCombo->itemData(_ui->PaOutdevCombo->currentIndex(), Qt::UserRole).toInt()));
  139. }
  140. if (var.value() == "ringdev") {
  141. val.setValue(QString::number(_ui->PaRingdevCombo->itemData(_ui->PaRingdevCombo->currentIndex(), Qt::UserRole).toInt()));
  142. }
  143. if (var.value() == "ring-file") {
  144. val.setValue(_ui->PaRingFileEdit->text());
  145. }
  146. if (var.value() == "ring-interval") {
  147. val.setValue(QString::number(_ui->PaRingIntervalSpin->value()));
  148. }
  149. if (var.value() == "hold-file") {
  150. val.setValue(_ui->PaHoldFileEdit->text());
  151. }
  152. if (var.value() == "cid-name") {
  153. val.setValue(_ui->PaCallerIdNameEdit->text());
  154. }
  155. if (var.value() == "cid-num") {
  156. val.setValue(_ui->PaCallerIdNumEdit->text());
  157. }
  158. if (var.value() == "sample-rate") {
  159. val.setValue(_ui->PaSampleRateEdit->text());
  160. }
  161. if (var.value() == "codec-ms") {
  162. val.setValue(_ui->PaCodecMSEdit->text());
  163. }
  164. /* Not used currently
  165. if (var.value() == "dialplan") {
  166. val.setValue();
  167. }
  168. if (var.value() == "timer-name") {
  169. val.setValue();
  170. }*/
  171. }
  172. /* Save the config to the file */
  173. _settings->setConfigNode(cfg, "portaudio.conf");
  174. }
  175. void PrefPortaudio::postWriteConfig() {
  176. QString result;
  177. if (g_FSHost->sendCmd("reload", "mod_portaudio", &result) != SWITCH_STATUS_SUCCESS)
  178. {
  179. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while issuing reload command to mod_portaudio!\n");
  180. QMessageBox::critical(0, tr("Unable to save settings"),
  181. tr("There was an error saving your settings.\nPlease report this bug."),
  182. QMessageBox::Ok);
  183. }
  184. }
  185. void PrefPortaudio::readConfig()
  186. {
  187. getPaDevlist(); /* To populate the combo */
  188. ISettings *_settings = new ISettings();
  189. QDomElement cfg = _settings->getConfigNode("portaudio.conf");
  190. QDomNodeList nl = cfg.elementsByTagName("param");
  191. for (int i = 0; i < nl.count(); i++) {
  192. QDomAttr var = nl.at(i).toElement().attributeNode("name");
  193. QDomAttr val = nl.at(i).toElement().attributeNode("value");
  194. /* Set when getting the device list */
  195. if (var.value() == "indev") {
  196. }
  197. if (var.value() == "outdev") {
  198. }
  199. if (var.value() == "ringdev") {
  200. }
  201. if (var.value() == "ring-file") {
  202. _ui->PaRingFileEdit->setText(val.value());
  203. }
  204. if (var.value() == "ring-interval") {
  205. _ui->PaRingIntervalSpin->setValue(val.value().toInt());
  206. }
  207. if (var.value() == "hold-file") {
  208. _ui->PaHoldFileEdit->setText(val.value());
  209. }
  210. /* Not yet used.
  211. if (var.value() == "dialplan") {
  212. }
  213. if (var.value() == "timer-name") {
  214. }
  215. */
  216. if (var.value() == "cid-name") {
  217. _ui->PaCallerIdNameEdit->setText(val.value());
  218. }
  219. if (var.value() == "cid-num") {
  220. _ui->PaCallerIdNumEdit->setText(val.value());
  221. }
  222. if (var.value() == "sample-rate") {
  223. _ui->PaSampleRateEdit->setText(val.value());
  224. }
  225. if (var.value() == "codec-ms") {
  226. _ui->PaCodecMSEdit->setText(val.value());
  227. }
  228. }
  229. }
  230. void PrefPortaudio::getPaDevlist()
  231. {
  232. QString result;
  233. int errorLine, errorColumn;
  234. QString errorMsg;
  235. if (g_FSHost->sendCmd("pa", "devlist xml", &result) != SWITCH_STATUS_SUCCESS)
  236. {
  237. QMessageBox::critical(0, tr("PortAudio error" ),
  238. tr("Error querying audio devices."),
  239. QMessageBox::Ok);
  240. return;
  241. }
  242. _ui->PaOutdevCombo->clear();
  243. _ui->PaIndevCombo->clear();
  244. _ui->PaRingdevCombo->clear();
  245. if (!_xmlPaDevList.setContent(result, &errorMsg, &errorLine, &errorColumn))
  246. {
  247. QMessageBox::critical(0, tr("PortAudio error" ),
  248. tr("Error parsing output xml from pa devlist.\n%1 (Line:%2, Col:%3).").arg(errorMsg,
  249. errorLine,
  250. errorColumn),
  251. QMessageBox::Ok);
  252. return;
  253. }
  254. QDomElement root = _xmlPaDevList.documentElement();
  255. if (root.tagName() != "xml")
  256. {
  257. QMessageBox::critical(0, tr("PortAudio error" ),
  258. tr("Error parsing output xml from pa devlist. Root tag is not <xml>."),
  259. QMessageBox::Ok);
  260. return;
  261. }
  262. QDomElement devices = root.firstChildElement("devices");
  263. if (devices.isNull())
  264. {
  265. QMessageBox::critical(0, tr("PortAudio error" ),
  266. tr("Error parsing output xml from pa devlist. There is no <devices> tag."),
  267. QMessageBox::Ok);
  268. return;
  269. }
  270. QDomElement child = devices.firstChildElement();
  271. if (child.isNull())
  272. {
  273. QMessageBox::critical(0, tr("PortAudio error" ),
  274. tr("Error parsing output xml from pa devlist. There is no <device> tag."),
  275. QMessageBox::Ok);
  276. return;
  277. }
  278. while (!child.isNull())
  279. {
  280. if (child.tagName() == "device")
  281. {
  282. QString id, name, inputs, outputs;
  283. id = child.attribute("id","-1");
  284. name = child.attribute("name","Null");
  285. inputs = child.attribute("inputs","0");
  286. outputs = child.attribute("outputs","0");
  287. if (inputs.toInt() != 0)
  288. _ui->PaIndevCombo->addItem(name,id.toInt());
  289. if (outputs.toInt() != 0)
  290. {
  291. _ui->PaOutdevCombo->addItem(name,id.toInt());
  292. _ui->PaRingdevCombo->addItem(name,id.toInt());
  293. }
  294. }
  295. child = child.nextSiblingElement();
  296. }
  297. QDomElement bindings = root.firstChildElement("bindings");
  298. if (bindings.isNull())
  299. {
  300. QMessageBox::critical(0, tr("PortAudio error" ),
  301. tr("Error parsing output xml from pa devlist. There is no <bindings> tag."),
  302. QMessageBox::Ok);
  303. return;
  304. }
  305. child = bindings.firstChildElement();
  306. if (child.isNull())
  307. {
  308. QMessageBox::critical(0, tr("PortAudio error" ),
  309. tr("Error parsing output xml from pa devlist. There are no bindings."),
  310. QMessageBox::Ok);
  311. return;
  312. }
  313. while (!child.isNull())
  314. {
  315. QString id = child.attribute("device","-1");
  316. if (child.tagName() == "ring")
  317. {
  318. for(int itemId=0; itemId<_ui->PaRingdevCombo->count(); itemId++)
  319. {
  320. if (id == _ui->PaRingdevCombo->itemData(itemId,Qt::UserRole))
  321. {
  322. //setCurrentIndex triggers currentIndexChanged signal, hmmm...
  323. _ui->PaRingdevCombo->setCurrentIndex(itemId);
  324. break;
  325. }
  326. }
  327. }
  328. else if (child.tagName() == "input")
  329. {
  330. for(int itemId=0; itemId<_ui->PaRingdevCombo->count(); itemId++)
  331. {
  332. if (id == _ui->PaIndevCombo->itemData(itemId,Qt::UserRole))
  333. {
  334. _ui->PaIndevCombo->setCurrentIndex(itemId);
  335. break;
  336. }
  337. }
  338. }
  339. else if (child.tagName() == "output")
  340. for(int itemId=0; itemId<_ui->PaOutdevCombo->count(); itemId++)
  341. {
  342. if (id == _ui->PaOutdevCombo->itemData(itemId,Qt::UserRole))
  343. {
  344. _ui->PaOutdevCombo->setCurrentIndex(itemId);
  345. break;
  346. }
  347. }
  348. child = child.nextSiblingElement();
  349. }
  350. }