From f6d220c56cd7c75daefe53f60198b6fd827497b5 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Sat, 24 Aug 2019 09:16:18 -0400 Subject: [PATCH] 2019-08-24 Fred Gleason * Refactored rdalsaconfig(8) to use ALSA device IDs rather than ordinal numbers in asound.confO(5). --- ChangeLog | 3 + utils/rdalsaconfig/Makefile.am | 8 +- utils/rdalsaconfig/alsaitem.cpp | 27 ++- utils/rdalsaconfig/alsaitem.h | 13 +- utils/rdalsaconfig/rdalsa.cpp | 296 ---------------------------- utils/rdalsaconfig/rdalsa.h | 69 ------- utils/rdalsaconfig/rdalsacard.cpp | 114 +++++++++++ utils/rdalsaconfig/rdalsacard.h | 54 +++++ utils/rdalsaconfig/rdalsaconfig.cpp | 265 ++++++++++++------------- utils/rdalsaconfig/rdalsaconfig.h | 31 +-- utils/rdalsaconfig/rdalsamodel.cpp | 153 ++++++++++++++ utils/rdalsaconfig/rdalsamodel.h | 56 ++++++ 12 files changed, 541 insertions(+), 548 deletions(-) delete mode 100644 utils/rdalsaconfig/rdalsa.cpp delete mode 100644 utils/rdalsaconfig/rdalsa.h create mode 100644 utils/rdalsaconfig/rdalsacard.cpp create mode 100644 utils/rdalsaconfig/rdalsacard.h create mode 100644 utils/rdalsaconfig/rdalsamodel.cpp create mode 100644 utils/rdalsaconfig/rdalsamodel.h diff --git a/ChangeLog b/ChangeLog index 8be7e377..120facd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18947,3 +18947,6 @@ the target event was unplayable. 2019-08-21 Fred Gleason * Re-indented switch() statements in 'lib/rdlogplay.cpp'. +2019-08-24 Fred Gleason + * Refactored rdalsaconfig(8) to use ALSA device IDs rather than + ordinal numbers in asound.confO(5). diff --git a/utils/rdalsaconfig/Makefile.am b/utils/rdalsaconfig/Makefile.am index 47601e1d..e17a5310 100644 --- a/utils/rdalsaconfig/Makefile.am +++ b/utils/rdalsaconfig/Makefile.am @@ -1,6 +1,6 @@ ## Makefile.am ## -## (C) Copyright 2009,2016-2018 Fred Gleason +## (C) Copyright 2009-2019 Fred Gleason ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License version 2 as @@ -29,10 +29,12 @@ moc_%.cpp: %.h bin_PROGRAMS = rdalsaconfig dist_rdalsaconfig_SOURCES = alsaitem.cpp alsaitem.h\ - rdalsa.cpp rdalsa.h\ + rdalsacard.cpp rdalsacard.h\ + rdalsamodel.cpp rdalsamodel.h\ rdalsaconfig.cpp rdalsaconfig.h -nodist_rdalsaconfig_SOURCES = moc_rdalsaconfig.cpp +nodist_rdalsaconfig_SOURCES = moc_rdalsamodel.cpp\ + moc_rdalsaconfig.cpp rdalsaconfig_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @LIBALSA@ @QT4_LIBS@ -lQt3Support diff --git a/utils/rdalsaconfig/alsaitem.cpp b/utils/rdalsaconfig/alsaitem.cpp index e929b6be..17002e38 100644 --- a/utils/rdalsaconfig/alsaitem.cpp +++ b/utils/rdalsaconfig/alsaitem.cpp @@ -2,7 +2,7 @@ // // QListBoxItem for ALSA PCM devices. // -// (C) Copyright 2009-2018 Fred Gleason +// (C) Copyright 2009-2019 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -29,38 +29,37 @@ AlsaItem::AlsaItem(Q3ListBox *listbox,const QString &text) AlsaItem::AlsaItem(const QString &text) : Q3ListBoxText(text) { - alsa_card=-1; - alsa_device=-1; + alsa_card_number=-1; + alsa_pcm_number=-1; } AlsaItem::AlsaItem(const AlsaItem &item) { - setText(item.text()); - setCard(item.card()); - setDevice(item.device()); + setCardNumber(item.cardNumber()); + setPcmNumber(item.pcmNumber()); } -int AlsaItem::card() const +int AlsaItem::cardNumber() const { - return alsa_card; + return alsa_card_number; } -void AlsaItem::setCard(int card) +void AlsaItem::setCardNumber(int cardnum) { - alsa_card=card; + alsa_card_number=cardnum; } -int AlsaItem::device() const +int AlsaItem::pcmNumber() const { - return alsa_device; + return alsa_pcm_number; } -void AlsaItem::setDevice(int device) +void AlsaItem::setPcmNumber(int pcmnum) { - alsa_device=device; + alsa_pcm_number=pcmnum; } diff --git a/utils/rdalsaconfig/alsaitem.h b/utils/rdalsaconfig/alsaitem.h index b1feebb7..30cbb8d3 100644 --- a/utils/rdalsaconfig/alsaitem.h +++ b/utils/rdalsaconfig/alsaitem.h @@ -30,14 +30,13 @@ class AlsaItem : public Q3ListBoxText AlsaItem(Q3ListBox *listbox,const QString &text=QString::null); AlsaItem(const QString &text=QString::null); AlsaItem(const AlsaItem &item); - int card() const; - void setCard(int card); - int device() const; - void setDevice(int device); - + int cardNumber() const; + void setCardNumber(int cardnum); + int pcmNumber() const; + void setPcmNumber(int pcmnum); private: - int alsa_card; - int alsa_device; + int alsa_card_number; + int alsa_pcm_number; }; diff --git a/utils/rdalsaconfig/rdalsa.cpp b/utils/rdalsaconfig/rdalsa.cpp deleted file mode 100644 index 87cbbd99..00000000 --- a/utils/rdalsaconfig/rdalsa.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// rdalsa.cpp -// -// Abstract an ALSA configuration. -// -// (C) Copyright 2009-2018 Fred Gleason -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include -#include -#include - -#include - -#include - -RDAlsa::RDAlsa() -{ - clear(); -} - - -unsigned RDAlsa::cards() const -{ - return card_ids.size(); -} - - -QString RDAlsa::cardId(unsigned cardnum) const -{ - if(cardnum>=card_ids.size()) { - return QString("[invalid card]"); - } - return card_ids[cardnum]; -} - - -QString RDAlsa::cardDriver(unsigned cardnum) const -{ - if(cardnum>=card_drivers.size()) { - return QString("[invalid card]"); - } - return card_drivers[cardnum]; -} - - -QString RDAlsa::cardName(unsigned cardnum) const -{ - if(cardnum>=card_names.size()) { - return QString("[invalid card]"); - } - return card_names[cardnum]; -} - - -QString RDAlsa::cardLongName(unsigned cardnum) const -{ - if(cardnum>=card_long_names.size()) { - return QString("[invalid card]"); - } - return card_long_names[cardnum]; -} - - -QString RDAlsa::cardMixerName(unsigned cardnum) const -{ - if(cardnum>=card_mixer_names.size()) { - return QString("[invalid card]"); - } - return card_mixer_names[cardnum]; -} - - -int RDAlsa::pcmDevices(unsigned cardnum) const -{ - if(cardnum>=card_pcm_names.size()) { - return -1; - } - return card_pcm_names[cardnum].size(); -} - - -QString RDAlsa::pcmName(unsigned cardnum,unsigned pcm) const -{ - if(cardnum>=card_pcm_names.size()) { - return QString("[invalid pcm device]"); - } - if(pcm>=card_pcm_names[cardnum].size()) { - return QString("[invalid pcm device]"); - } - return card_pcm_names[cardnum][pcm]; -} - - -int RDAlsa::rivendellCard(int slot) const -{ - return card_rivendell_cards[slot]; -} - - -void RDAlsa::setRivendellCard(int slot,int cardnum) -{ - if(slot>=RD_MAX_CARDS) { - return; - } - card_rivendell_cards[slot]=cardnum; -} - - -int RDAlsa::rivendellDevice(int slot) const -{ - return card_rivendell_devices[slot]; -} - - -void RDAlsa::setRivendellDevice(int slot,int devnum) -{ - if(slot>=RD_MAX_CARDS) { - return; - } - card_rivendell_devices[slot]=devnum; -} - - -bool RDAlsa::load(const QString &filename) -{ - LoadSystemConfig(); - return LoadAsoundConfig(filename); -} - - -bool RDAlsa::save(const QString &filename) -{ - return SaveAsoundConfig(filename); -} - - -void RDAlsa::clear() -{ - card_ids.clear(); - card_drivers.clear(); - card_names.clear(); - card_long_names.clear(); - card_mixer_names.clear(); - card_pcm_names.clear(); - for(unsigned i=0;i=0) { - snd_ctl_card_info(snd_ctl,card_info); - card_ids.push_back(snd_ctl_card_info_get_id(card_info)); - card_drivers.push_back(snd_ctl_card_info_get_driver(card_info)); - card_names.push_back(snd_ctl_card_info_get_name(card_info)); - card_long_names.push_back(snd_ctl_card_info_get_longname(card_info)); - card_mixer_names.push_back(snd_ctl_card_info_get_mixername(card_info)); - std::vector pcms; - if(snd_ctl_pcm_info(snd_ctl,pcm_info)==0) { - pcm=0; - while(pcm>=0) { - pcms.push_back(QString().sprintf("%s [%02u]", - (const char *)snd_pcm_info_get_name(pcm_info),pcm+1)); - snd_ctl_pcm_next_device(snd_ctl,&pcm); - } - } - card_pcm_names.push_back(pcms); - snd_ctl_close(snd_ctl); - card++; - } -} - - -bool RDAlsa::LoadAsoundConfig(const QString &filename) -{ - FILE *f=NULL; - char line[1024]; - int istate=0; - int port=0; - int card=0; - int device=0; - QStringList list; - - if((f=fopen(filename,"r"))==NULL) { - return false; - } - while(fgets(line,1024,f)!=NULL) { - QString str=line; - str.replace("\n",""); - if((str!=START_MARKER)&&(str!=END_MARKER)) { - switch(istate) { - case 0: - if(str.left(6)=="pcm.rd") { - port=str.mid(6,1).toInt(); - istate=1; - } - else { - if(str.left(6)=="ctl.rd") { - istate=10; - } - else { - card_other_lines.push_back(str+"\n"); - } - } - break; - - case 1: - list=str.split(" "); - if(list[0]=="}") { - if((port>=0)&&(port=0)&&(card_rivendell_devices[i]>=0)) { - fprintf(f,"pcm.rd%d {\n",i); - fprintf(f," type hw\n"); - fprintf(f," card %d\n",card_rivendell_cards[i]); - fprintf(f," device %d\n",card_rivendell_devices[i]); - fprintf(f,"}\n"); - fprintf(f,"ctl.rd%d {\n",i); - fprintf(f," type hw\n"); - fprintf(f," card %d\n",card_rivendell_cards[i]); - fprintf(f,"}\n"); - } - } - fprintf(f,"%s\n",END_MARKER); - - fclose(f); - return true; -} diff --git a/utils/rdalsaconfig/rdalsa.h b/utils/rdalsaconfig/rdalsa.h deleted file mode 100644 index 399d50fb..00000000 --- a/utils/rdalsaconfig/rdalsa.h +++ /dev/null @@ -1,69 +0,0 @@ -// rdalsa.h -// -// Abstract an ALSA configuration. -// -// (C) Copyright 2009-2018 Fred Gleason -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License version 2 as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef RDALSA_H -#define RDALSA_H - -#include - -#include - -#include - -#define START_MARKER "# *** Start of Rivendell configuration generated by rdalsaconfig(1) ***" -#define END_MARKER "# *** End of Rivendell configuration generated by rdalsaconfig(1) ***" - -class RDAlsa -{ - public: - RDAlsa(); - unsigned cards() const; - QString cardId(unsigned cardnum) const; - QString cardDriver(unsigned cardnum) const; - QString cardName(unsigned cardnum) const; - QString cardLongName(unsigned cardnum) const; - QString cardMixerName(unsigned cardnum) const; - int pcmDevices(unsigned cardnum) const; - QString pcmName(unsigned cardnum,unsigned pcm) const; - int rivendellCard(int slot) const; - void setRivendellCard(int slot,int cardnum); - int rivendellDevice(int slot) const; - void setRivendellDevice(int slot,int devnum); - bool load(const QString &filename); - bool save(const QString &filename); - void clear(); - - private: - void LoadSystemConfig(); - bool LoadAsoundConfig(const QString &filename); - bool SaveAsoundConfig(const QString &filename); - std::vector card_ids; - std::vector card_drivers; - std::vector card_names; - std::vector card_long_names; - std::vector card_mixer_names; - std::vector > card_pcm_names; - int card_rivendell_cards[RD_MAX_CARDS]; - int card_rivendell_devices[RD_MAX_CARDS]; - QStringList card_other_lines; -}; - - -#endif // RDALSA_H diff --git a/utils/rdalsaconfig/rdalsacard.cpp b/utils/rdalsaconfig/rdalsacard.cpp new file mode 100644 index 00000000..da11295c --- /dev/null +++ b/utils/rdalsaconfig/rdalsacard.cpp @@ -0,0 +1,114 @@ +// rdalsacard.cpp +// +// Abstract ALSA 'card' information +// +// (C) Copyright 2019 Fred Gleason +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "rdalsacard.h" + +RDAlsaCard::RDAlsaCard(snd_ctl_t *ctl,int index) +{ + snd_ctl_card_info_t *card_info; + snd_pcm_info_t *pcm_info; + int pcm=0; + + card_index=index; + + snd_ctl_card_info_malloc(&card_info); + snd_pcm_info_malloc(&pcm_info); + + snd_ctl_card_info(ctl,card_info); + card_id=QString(snd_ctl_card_info_get_id(card_info)); + card_driver=QString(snd_ctl_card_info_get_driver(card_info)); + card_name=QString(snd_ctl_card_info_get_name(card_info)); + card_long_name=QString(snd_ctl_card_info_get_longname(card_info)); + card_mixer_name=QString(snd_ctl_card_info_get_mixername(card_info)); + if(snd_ctl_pcm_info(ctl,pcm_info)==0) { + pcm=0; + while(pcm>=0) { + card_pcm_names.push_back(snd_pcm_info_get_name(pcm_info)+ + QString().sprintf("[%02d]",pcm+1)); + snd_ctl_pcm_next_device(ctl,&pcm); + } + } + snd_pcm_info_free(pcm_info); + snd_ctl_card_info_free(card_info); +} + + +int RDAlsaCard::index() const +{ + return card_index; +} + + +QString RDAlsaCard::id() const +{ + return card_id; +} + + +QString RDAlsaCard::driver() const +{ + return card_driver; +} + + +QString RDAlsaCard::name() const +{ + return card_name; +} + + +QString RDAlsaCard::longName() const +{ + return card_long_name; +} + + +QString RDAlsaCard::mixerName() const +{ + return card_long_name; +} + + +QString RDAlsaCard::dump() const +{ + QString ret=QString().sprintf("Card %d\n",index()); + + ret+=" ID: "+id()+"\n"; + ret+=" Name: "+name()+"\n"; + ret+=" LongName: "+longName()+"\n"; + ret+=" MixerName: "+mixerName()+"\n"; + for(int i=0;i +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef RDALSACARD_H +#define RDALSACARD_H + +#include + +#include +#include + +class RDAlsaCard +{ + public: + RDAlsaCard(snd_ctl_t *ctl,int index); + int index() const; + QString id() const; + QString driver() const; + QString name() const; + QString longName() const; + QString mixerName() const; + int pcmQuantity() const; + QString pcmName(int n) const; + QString dump() const; + + private: + int card_index; + QString card_id; + QString card_driver; + QString card_name; + QString card_long_name; + QString card_mixer_name; + QStringList card_pcm_names; +}; + + +#endif // RDALSACARD_H diff --git a/utils/rdalsaconfig/rdalsaconfig.cpp b/utils/rdalsaconfig/rdalsaconfig.cpp index 5c9199fe..aa3b3d7c 100644 --- a/utils/rdalsaconfig/rdalsaconfig.cpp +++ b/utils/rdalsaconfig/rdalsaconfig.cpp @@ -2,7 +2,7 @@ // // A Qt-based application to display info about ALSA cards. // -// (C) Copyright 2009-2018 Fred Gleason +// (C) Copyright 2009-2019 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -87,36 +88,21 @@ MainWidget::MainWidget(QWidget *parent) label_font.setPixelSize(12); // - // Available Devices + // ALSA Sound Devices // - alsa_system_list=new Q3ListBox(this); + alsa_system_list=new QListView(this); alsa_system_list->setFont(font); + alsa_system_list->setSelectionMode(QAbstractItemView::MultiSelection); alsa_system_label= - new QLabel(alsa_system_list,tr("Available Sound Devices"),this); + new QLabel(alsa_system_list,tr("ALSA Sound Devices"),this); alsa_system_label->setFont(label_font); alsa_system_label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); - - // - // Up Button - // - alsa_up_button=new RDTransportButton(RDTransportButton::Up,this); - connect(alsa_up_button,SIGNAL(clicked()),this,SLOT(upData())); - - // - // Down Button - // - alsa_down_button= - new RDTransportButton(RDTransportButton::Down,this); - connect(alsa_down_button,SIGNAL(clicked()),this,SLOT(downData())); - - // - // Selected Devices - // - alsa_config_list=new Q3ListBox(this); - alsa_config_list->setFont(font); - alsa_config_label=new QLabel(alsa_config_list,tr("Active Sound Devices"),this); - alsa_config_label->setFont(label_font); - alsa_config_label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + alsa_description_label=new QLabel(this); + alsa_description_label-> + setText(tr("Select the audio devices to dedicate for use with Rivendell. (Devices so dedicated will be unavailable for use with other applications.)")); + alsa_description_label->setFont(font); + alsa_description_label->setAlignment(Qt::AlignLeft|Qt::AlignTop); + alsa_description_label->setWordWrap(true); // // Save Button @@ -135,9 +121,9 @@ MainWidget::MainWidget(QWidget *parent) // // Load Available Devices and Configuration // - alsa_alsa=new RDAlsa(); - alsa_alsa->load(alsa_filename); - LoadList(alsa_system_list,alsa_config_list); + alsa_system_model=new RDAlsaModel(); + alsa_system_list->setModel(alsa_system_model); + LoadConfig(); // // Daemon Management @@ -168,7 +154,7 @@ MainWidget::~MainWidget() QSize MainWidget::sizeHint() const { - return QSize(400,300); + return QSize(400,400); } @@ -178,33 +164,17 @@ QSizePolicy MainWidget::sizePolicy() const } -void MainWidget::upData() -{ - MoveItem(alsa_config_list,alsa_system_list); -} - - -void MainWidget::downData() -{ - if(alsa_config_list->count()>=RD_MAX_CARDS) { - return; - } - MoveItem(alsa_system_list,alsa_config_list); -} - - void MainWidget::saveData() { + /* AlsaItem *item=NULL; for(int i=0;iitem(i))==NULL) { alsa_alsa->setRivendellCard(i,-1); - alsa_alsa->setRivendellDevice(i,-1); } else { - alsa_alsa->setRivendellCard(i,item->card()); - alsa_alsa->setRivendellDevice(i,item->device()); + alsa_alsa->setRivendellCard(i,item->cardNumber()); } } if(!alsa_alsa->save(alsa_filename)) { @@ -214,6 +184,10 @@ void MainWidget::saveData() return; } StartDaemons(); + */ + + SaveConfig(); + qApp->quit(); } @@ -227,14 +201,10 @@ void MainWidget::cancelData() void MainWidget::resizeEvent(QResizeEvent *e) { - alsa_system_label->setGeometry(20,5,size().width()-20,20); + alsa_system_label->setGeometry(10,5,size().width()-20,20); + alsa_description_label->setGeometry(10,25,size().width()-20,50); alsa_system_list-> - setGeometry(10,25,size().width()-20,(size().height()-120)/2); - alsa_up_button->setGeometry(size().width()-120,size().height()/2-28,50,30); - alsa_down_button->setGeometry(size().width()-60,size().height()/2-28,50,30); - alsa_config_label->setGeometry(20,size().height()/2-10,size().width()/2,20); - alsa_config_list->setGeometry(10,size().height()/2+10, - size().width()-20,(size().height()-120)/2); + setGeometry(10,75,size().width()-20,size().height()-130); alsa_save_button-> setGeometry(size().width()-120,size().height()-40,50,30); alsa_cancel_button-> @@ -263,93 +233,123 @@ void MainWidget::closeEvent(QCloseEvent *e) } -void MainWidget::LoadList(Q3ListBox *system,Q3ListBox *config) +void MainWidget::LoadConfig() { - for(unsigned i=0;icards();i++) { - for(int j=0;jpcmDevices(i);j++) { - if(PcmUnused(i,j)) { - AlsaItem *item= - new AlsaItem(alsa_alsa->cardLongName(i)+" - "+ - alsa_alsa->pcmName(i,j)); - item->setCard(i); - item->setDevice(j); - system->insertItem(item); + FILE *f=NULL; + char line[1024]; + int istate=0; + int port=0; + QString card_id=0; + int device=0; + QStringList list; + bool active_line=false; + QModelIndex index; + + if((f=fopen(RD_ASOUNDRC_FILE,"r"))==NULL) { + return; + } + while(fgets(line,1024,f)!=NULL) { + QString str=line; + str.replace("\n",""); + if(str==START_MARKER) { + active_line=true; + } + if(str==END_MARKER) { + active_line=false; + } + if((str!=START_MARKER)&&(str!=END_MARKER)) { + if(active_line) { + switch(istate) { + case 0: + if(str.left(6)=="pcm.rd") { + port=str.mid(6,1).toInt(); + istate=1; + } + else { + if(str.left(6)=="ctl.rd") { + istate=10; + } + else { + alsa_other_lines.push_back(str+"\n"); + } + } + break; + + case 1: + list=str.split(" ",QString::SkipEmptyParts); + if(list[0]=="}") { + if((port>=0)&&(portindexOf(card_id,device); + if(index.isValid()) { + alsa_system_list->selectionModel()-> + select(index,QItemSelectionModel::Select); + } + } + card_id=""; + device=0; + istate=0; + } + else { + if(list.size()==2) { + if(list[0]=="card") { + card_id=list[1].trimmed(); + } + if(list[0]=="device") { + device=list[1].toInt(); + } + } + } + break; + + case 10: + if(str.left(1)=="}") { + istate=0; + } + break; + } + } + else { + alsa_other_lines.push_back(str+"\n"); } } } - system->sort(); - - for(int i=0;irivendellCard(i)>=0) { - AlsaItem *item= - new AlsaItem(alsa_alsa->cardLongName(alsa_alsa->rivendellCard(i))+" - "+ - alsa_alsa->pcmName(alsa_alsa->rivendellCard(i), - alsa_alsa->rivendellDevice(i))); - item->setCard(alsa_alsa->rivendellCard(i)); - item->setDevice(alsa_alsa->rivendellDevice(i)); - config->insertItem(item); - } - } - config->sort(); + fclose(f); } -bool MainWidget::PcmUnused(int card,int device) +void MainWidget::SaveConfig() const { - for(int i=0;irivendellCard(i))&& - (device==alsa_alsa->rivendellDevice(i))) { - return false; - } - } - return true; -} + QString tempfile=QString(RD_ASOUNDRC_FILE)+"-temp"; + FILE *f=NULL; - -void MainWidget::MoveItem(Q3ListBox *src,Q3ListBox *dest) -{ - AlsaItem *item=(AlsaItem *)src->selectedItem(); - if(item==NULL) { + if((f=fopen(tempfile.toUtf8(),"w"))==NULL) { return; } - dest->insertItem(new AlsaItem(*item)); // Force a deep copy - dest->sort(); - delete item; -} - - -Autogen::Autogen(QObject *parent) -{ - StopDaemons(); - - // - // Load Available Devices - // - RDAlsa *alsa=new RDAlsa(); - alsa->load(alsa_filename); - - // - // Build Configuration - // - int slot=0; - for(unsigned i=0;icards();i++) { - for(int j=0;jpcmDevices(i);j++) { - alsa->setRivendellCard(slot,i); - alsa->setRivendellDevice(slot,j); - slot++; + for(int i=0;iselectionModel()->selectedIndexes(); + for(int i=0;icard(indexes.at(i))->id().toUtf8()); + fprintf(f," device %d\n",alsa_system_model->pcmNumber(indexes.at(i))); + if(alsa_system_model->card(indexes.at(i))->id()=="Axia") { + fprintf(f," channels 2\n"); } + fprintf(f,"}\n"); + fprintf(f,"ctl.rd%d {\n",i); + fprintf(f," type hw\n"); + fprintf(f," card %s\n", + (const char *)alsa_system_model->card(indexes.at(i))->id().toUtf8()); + fprintf(f,"}\n"); } + fprintf(f,"%s\n",END_MARKER); - // - // Save Configuration - // - if(!alsa->save(alsa_filename)) { - exit(256); - } - - StartDaemons(); - - exit(0); + fclose(f); + rename(tempfile.toUtf8(),RD_ASOUNDRC_FILE); } @@ -373,15 +373,6 @@ int main(int argc,char *argv[]) } } - // - // Autogenerate a full configuration - // - if(alsa_autogen) { - QApplication a(argc,argv,false); - new Autogen(); - return a.exec(); - } - // // Start GUI // diff --git a/utils/rdalsaconfig/rdalsaconfig.h b/utils/rdalsaconfig/rdalsaconfig.h index 213070b8..84e21bcb 100644 --- a/utils/rdalsaconfig/rdalsaconfig.h +++ b/utils/rdalsaconfig/rdalsaconfig.h @@ -2,7 +2,7 @@ // // A Qt-based application to display info about ALSA cards. // -// (C) Copyright 2009-2018 Fred Gleason +// (C) Copyright 2009-2019 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -22,13 +22,13 @@ #define RDALSACONFIG_H #include -#include +#include #include #include #include -#include +#include "rdalsamodel.h" #define RDALSACONFIG_USAGE "[--asoundrc-file=] [--autogen] [--manage-daemons]\n\nGenerate an ALSA sound card configuration for Rivendell.\n\nThe following options are available:\n\n --asoundrc-file=\n Read and write configuration from (default value \n \"/etc/asound.conf\").\n\n --autogen\n Generate and save a configuration containing all available PCM devices\n and then exit.\n\n --manage-daemons\n Restart the Rivendell daemons as necessary to make configuration\n changes active (requires root permission).\n\n" @@ -45,8 +45,6 @@ class MainWidget : public QWidget QSizePolicy sizePolicy() const; private slots: - void upData(); - void downData(); void saveData(); void cancelData(); @@ -55,26 +53,15 @@ class MainWidget : public QWidget void closeEvent(QCloseEvent *e); private: - void LoadList(Q3ListBox *system,Q3ListBox *config); - bool PcmUnused(int card,int device); - void MoveItem(Q3ListBox *src,Q3ListBox *dest); + void LoadConfig(); + void SaveConfig() const; QLabel *alsa_system_label; - Q3ListBox *alsa_system_list; - QLabel *alsa_config_label; - Q3ListBox *alsa_config_list; - RDTransportButton *alsa_up_button; - RDTransportButton *alsa_down_button; + QLabel *alsa_description_label; + QListView *alsa_system_list; + RDAlsaModel *alsa_system_model; + QStringList alsa_other_lines; QPushButton *alsa_save_button; QPushButton *alsa_cancel_button; - RDAlsa *alsa_alsa; -}; - - -class Autogen : public QObject -{ - Q_OBJECT - public: - Autogen(QObject *parent=0); }; diff --git a/utils/rdalsaconfig/rdalsamodel.cpp b/utils/rdalsaconfig/rdalsamodel.cpp new file mode 100644 index 00000000..497e6b25 --- /dev/null +++ b/utils/rdalsaconfig/rdalsamodel.cpp @@ -0,0 +1,153 @@ +// rdalsamodel.cpp +// +// Abstract an ALSA configuration. +// +// (C) Copyright 2009-2019 Fred Gleason +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include +#include +#include + +#include + +#include + +RDAlsaModel::RDAlsaModel(QObject *parent) + : QAbstractListModel(parent) +{ + LoadSystemConfig(); +} + + +int RDAlsaModel::rowCount(const QModelIndex &parent) const +{ + int rows=0; + + for(int i=0;ipcmQuantity(); + } + + return rows; +} + + +QVariant RDAlsaModel::data(const QModelIndex &index,int role) const +{ + int row=index.row(); + + switch((Qt::ItemDataRole)role) { + case Qt::DisplayRole: + return QVariant(model_alsa_cards.at(model_card_index.at(row))->name()+" - "+ + model_alsa_cards.at(model_card_index.at(row))-> + pcmName(model_pcm_index.at(row))); + break; + + case Qt::DecorationRole: + case Qt::EditRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + case Qt::WhatsThisRole: + case Qt::SizeHintRole: + case Qt::FontRole: + case Qt::TextAlignmentRole: + case Qt::BackgroundColorRole: + case Qt::TextColorRole: + case Qt::CheckStateRole: + case Qt::AccessibleTextRole: + case Qt::AccessibleDescriptionRole: + case Qt::InitialSortOrderRole: + case Qt::DisplayPropertyRole: + case Qt::DecorationPropertyRole: + case Qt::ToolTipPropertyRole: + case Qt::StatusTipPropertyRole: + case Qt::WhatsThisPropertyRole: + case Qt::UserRole: + break; + } + + return QVariant(); +} + + +QVariant RDAlsaModel::headerData(int section,Qt::Orientation orient, + int role) const +{ + switch(orient) { + case Qt::Horizontal: + return QVariant(tr("ALSA Devices")); + + case Qt::Vertical: + break; + } + + return QVariant(); +} + + +QModelIndex RDAlsaModel::indexOf(const QString &card_id,int pcm_num) const +{ + bool ok=false; + int cardnum=card_id.toUInt(&ok); + + if(ok) { + for(int i=0;iid()==card_id)&& + (model_pcm_index.at(i)==pcm_num)) { + return createIndex(i,0); + } + } + } + + return QModelIndex(); +} + + +RDAlsaCard *RDAlsaModel::card(const QModelIndex &index) const +{ + return model_alsa_cards.at(model_card_index.at(index.row())); +} + + +int RDAlsaModel::pcmNumber(const QModelIndex &index) const +{ + return model_pcm_index.at(index.row()); +} + + +void RDAlsaModel::LoadSystemConfig() +{ + snd_ctl_t *snd_ctl=NULL; + int index=0; + + while(snd_ctl_open(&snd_ctl,QString().sprintf("hw:%d",index),0)>=0) { + model_alsa_cards.push_back(new RDAlsaCard(snd_ctl,index)); + for(int i=0;ipcmQuantity();i++) { + model_card_index.push_back(index); + model_pcm_index.push_back(i); + } + snd_ctl_close(snd_ctl); + index++; + } +} diff --git a/utils/rdalsaconfig/rdalsamodel.h b/utils/rdalsaconfig/rdalsamodel.h new file mode 100644 index 00000000..bd4e9148 --- /dev/null +++ b/utils/rdalsaconfig/rdalsamodel.h @@ -0,0 +1,56 @@ +// rdalsamodel.h +// +// Abstract an ALSA configuration. +// +// (C) Copyright 2009-2018 Fred Gleason +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#ifndef RDALSAMODEL_H +#define RDALSAMODEL_H + +#include +#include +#include + +#include + +#include "rdalsacard.h" + +#define START_MARKER "# *** Start of Rivendell configuration generated by rdalsaconfig(1) ***" +#define END_MARKER "# *** End of Rivendell configuration generated by rdalsaconfig(1) ***" + +class RDAlsaModel : public QAbstractListModel +{ + Q_OBJECT; + public: + RDAlsaModel(QObject *parent=0); + int rowCount(const QModelIndex &parent=QModelIndex()) const; + QVariant data(const QModelIndex &index,int role=Qt::DisplayRole) const; + QVariant headerData(int section,Qt::Orientation orient, + int role=Qt::DisplayRole) const; + QModelIndex indexOf(const QString &card_id,int pcm_num) const; + RDAlsaCard *card(const QModelIndex &index) const; + int pcmNumber(const QModelIndex &index) const; + + private: + void LoadSystemConfig(); + QList model_alsa_cards; + QList model_card_index; + QList model_pcm_index; +}; + + +#endif // RDALSAMODEL_H