From 62c3f7e5b7a637238c5d99936a54e994e50e5baf Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Sat, 13 Sep 2025 18:46:08 -0400 Subject: [PATCH] 2025-09-13 Fred Gleason * Fixed a bug in rdalsaconfig(8) that caused multiple card entries to appear for sound devices with more than one PCM. Signed-off-by: Fred Gleason --- ChangeLog | 3 + utils/rdalsaconfig/alsaitem.cpp | 16 +--- utils/rdalsaconfig/alsaitem.h | 5 +- utils/rdalsaconfig/rdalsacard.cpp | 39 +++------ utils/rdalsaconfig/rdalsacard.h | 11 +-- utils/rdalsaconfig/rdalsaconfig.cpp | 120 +--------------------------- utils/rdalsaconfig/rdalsamodel.cpp | 93 +++++++-------------- utils/rdalsaconfig/rdalsamodel.h | 8 +- 8 files changed, 50 insertions(+), 245 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab3a5393..7be935ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25045,3 +25045,6 @@ 2025-09-13 Fred Gleason * Fixed a bug in 'RDConfig' that caused a false 'invalid dropbox ID' warning to be generated when parsing rd.conf(5). +2025-09-13 Fred Gleason + * Fixed a bug in rdalsaconfig(8) that caused multiple card entries + to appear for sound devices with more than one PCM. diff --git a/utils/rdalsaconfig/alsaitem.cpp b/utils/rdalsaconfig/alsaitem.cpp index d4e79771..e61ff63e 100644 --- a/utils/rdalsaconfig/alsaitem.cpp +++ b/utils/rdalsaconfig/alsaitem.cpp @@ -2,7 +2,7 @@ // // QListBoxItem for ALSA PCM devices. // -// (C) Copyright 2009-2021 Fred Gleason +// (C) Copyright 2009-2025 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 @@ -24,14 +24,12 @@ AlsaItem::AlsaItem(const QString &text) : QListWidgetItem(text) { alsa_card_number=-1; - alsa_pcm_number=-1; } AlsaItem::AlsaItem(const AlsaItem &item) { setCardNumber(item.cardNumber()); - setPcmNumber(item.pcmNumber()); } @@ -45,15 +43,3 @@ void AlsaItem::setCardNumber(int cardnum) { alsa_card_number=cardnum; } - - -int AlsaItem::pcmNumber() const -{ - return alsa_pcm_number; -} - - -void AlsaItem::setPcmNumber(int pcmnum) -{ - alsa_pcm_number=pcmnum; -} diff --git a/utils/rdalsaconfig/alsaitem.h b/utils/rdalsaconfig/alsaitem.h index 5b30c168..5cc763b6 100644 --- a/utils/rdalsaconfig/alsaitem.h +++ b/utils/rdalsaconfig/alsaitem.h @@ -2,7 +2,7 @@ // // QListBoxItem for ALSA PCM devices. // -// (C) Copyright 2009-2021 Fred Gleason +// (C) Copyright 2009-2025 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 @@ -30,12 +30,9 @@ class AlsaItem : public QListWidgetItem AlsaItem(const AlsaItem &item); int cardNumber() const; void setCardNumber(int cardnum); - int pcmNumber() const; - void setPcmNumber(int pcmnum); private: int alsa_card_number; - int alsa_pcm_number; }; diff --git a/utils/rdalsaconfig/rdalsacard.cpp b/utils/rdalsaconfig/rdalsacard.cpp index 7cbaf70f..06fa6d19 100644 --- a/utils/rdalsaconfig/rdalsacard.cpp +++ b/utils/rdalsaconfig/rdalsacard.cpp @@ -2,7 +2,7 @@ // // Abstract ALSA 'card' information // -// (C) Copyright 2019-2021 Fred Gleason +// (C) Copyright 2019-2025 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 @@ -24,7 +24,6 @@ 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; @@ -37,15 +36,12 @@ RDAlsaCard::RDAlsaCard(snd_ctl_t *ctl,int index) 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::asprintf("[%02d]",pcm+1)); - snd_ctl_pcm_next_device(ctl,&pcm); - card_enableds.push_back(false); - } + if(card_name=="Loopback") { // Fix the opaque name assigned by Wheatstone + card_name.replace("Loopback","WheatNet"); + card_long_name.replace("Loopback","WheatNet"); + card_mixer_name.replace("Loopback","WheatNet"); } + card_enabled=false; snd_pcm_info_free(pcm_info); snd_ctl_card_info_free(card_info); } @@ -87,15 +83,15 @@ QString RDAlsaCard::mixerName() const } -bool RDAlsaCard::isEnabled(int pcm_num) const +bool RDAlsaCard::isEnabled() const { - return card_enableds.at(pcm_num); + return card_enabled; } -void RDAlsaCard::setEnabled(int pcm_num,bool state) +void RDAlsaCard::setEnabled(bool state) { - card_enableds[pcm_num]=state; + card_enabled=state; } @@ -107,21 +103,6 @@ QString RDAlsaCard::dump() const ret+=" Name: "+name()+"\n"; ret+=" LongName: "+longName()+"\n"; ret+=" MixerName: "+mixerName()+"\n"; - for(int i=0;i +// (C) Copyright 2019-2025 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 @@ -36,10 +36,8 @@ class RDAlsaCard QString name() const; QString longName() const; QString mixerName() const; - int pcmQuantity() const; - QString pcmName(int n) const; - bool isEnabled(int pcm_num) const; - void setEnabled(int pcm_num,bool state); + bool isEnabled() const; + void setEnabled(bool state); QString dump() const; private: @@ -49,8 +47,7 @@ class RDAlsaCard QString card_name; QString card_long_name; QString card_mixer_name; - QStringList card_pcm_names; - QList card_enableds; + bool card_enabled; }; diff --git a/utils/rdalsaconfig/rdalsaconfig.cpp b/utils/rdalsaconfig/rdalsaconfig.cpp index a0339424..d30e1ec1 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-2021 Fred Gleason +// (C) Copyright 2009-2025 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 @@ -224,88 +224,6 @@ void MainWidget::LoadConfig(const QString &filename) select(alsa_system_model->index(i,0),QItemSelectionModel::Deselect); } } - - /* - 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(filename.toUtf8(),"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"); - } - } - } - fclose(f); - */ } @@ -316,42 +234,6 @@ void MainWidget::SaveConfig(const QString &filename) const alsa_system_model->setEnabled(i,sel->isRowSelected(i,QModelIndex())); } alsa_system_model->saveConfig(filename); - - - /* - QString tempfile=filename+"-temp"; - FILE *f=NULL; - - if((f=fopen(tempfile.toUtf8(),"w"))==NULL) { - return; - } - 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))); - fprintf(f," rate %u\n",rda->system()->sampleRate()); - 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); - - fclose(f); - rename(tempfile.toUtf8(),filename.toUtf8()); - */ } diff --git a/utils/rdalsaconfig/rdalsamodel.cpp b/utils/rdalsaconfig/rdalsamodel.cpp index 34b6aab1..119cc614 100644 --- a/utils/rdalsaconfig/rdalsamodel.cpp +++ b/utils/rdalsaconfig/rdalsamodel.cpp @@ -2,7 +2,7 @@ // // Abstract an ALSA configuration. // -// (C) Copyright 2009-2021 Fred Gleason +// (C) Copyright 2009-2025 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 @@ -32,13 +32,7 @@ RDAlsaModel::RDAlsaModel(unsigned samprate,QObject *parent) int RDAlsaModel::rowCount(const QModelIndex &parent) const { - int rows=0; - - for(int i=0;ipcmQuantity(); - } - - return rows; + return model_alsa_cards.size(); } @@ -46,7 +40,7 @@ Qt::ItemFlags RDAlsaModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags=QAbstractListModel::flags(index); - if((model_alsa_cards.at(model_card_index.at(index.row()))->id()=="Axia")&& + if((model_alsa_cards.at(index.row())->id()=="Axia")&& (model_sample_rate!=48000)) { flags=flags&Qt::ItemIsEnabled; } @@ -61,9 +55,7 @@ QVariant RDAlsaModel::data(const QModelIndex &index,int role) const 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))); + return QVariant(model_alsa_cards.at(row)->longName()); break; case Qt::DecorationRole: @@ -108,23 +100,13 @@ QVariant RDAlsaModel::headerData(int section,Qt::Orientation orient, } -QModelIndex RDAlsaModel::indexOf(const QString &card_id,int pcm_num) const +QModelIndex RDAlsaModel::indexOf(const QString &card_id) 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)) { + for(int i=0;iid()==card_id) { return createIndex(i,0); } } @@ -134,29 +116,15 @@ QModelIndex RDAlsaModel::indexOf(const QString &card_id,int pcm_num) const } -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()); -} - - bool RDAlsaModel::isEnabled(int row) const { - return model_alsa_cards.at(model_card_index.at(row))-> - isEnabled(model_pcm_index.at(row)); + return model_alsa_cards.at(row)->isEnabled(); } void RDAlsaModel::setEnabled(int row,bool state) { - return model_alsa_cards.at(model_card_index.at(row))-> - setEnabled(model_pcm_index.at(row),state); + return model_alsa_cards.at(row)->setEnabled(state); } @@ -213,15 +181,15 @@ bool RDAlsaModel::loadConfig(const QString &filename) card_num=card_id.toUInt(&ok); if(ok) { if(card_num==card->index()) { - if((device>=0)&&(devicepcmQuantity())) { - card->setEnabled(device,true); + if(device>=0) { + card->setEnabled(true); } } } else { if(card_id==card->id()) { - if((device>=0)&&(devicepcmQuantity())) { - card->setEnabled(device,true); + if(device>=0) { + card->setEnabled(true); } } } @@ -276,23 +244,21 @@ bool RDAlsaModel::saveConfig(const QString &filename) fprintf(f,"%s\n",START_MARKER); for(int i=0;ipcmQuantity();j++) { - if(card->isEnabled(j)) { - fprintf(f,"pcm.rd%d {\n",index); - fprintf(f," type hw\n"); - fprintf(f," card %s\n",(const char *)card->id().toUtf8()); - fprintf(f," device %d\n",j); - fprintf(f," rate %u\n",rda->system()->sampleRate()); - if(card->id()=="Axia") { - fprintf(f," channels 2\n"); - } - fprintf(f,"}\n"); - fprintf(f,"ctl.rd%d {\n",index); - fprintf(f," type hw\n"); - fprintf(f," card %s\n",(const char *)card->id().toUtf8()); - fprintf(f,"}\n"); - index++; + if(card->isEnabled()) { + fprintf(f,"pcm.rd%d {\n",index); + fprintf(f," type hw\n"); + fprintf(f," card %s\n",(const char *)card->id().toUtf8()); + fprintf(f," device 0\n"); + fprintf(f," rate %u\n",rda->system()->sampleRate()); + if(card->id()=="Axia") { + fprintf(f," channels 2\n"); } + fprintf(f,"}\n"); + fprintf(f,"ctl.rd%d {\n",index); + fprintf(f," type hw\n"); + fprintf(f," card %s\n",(const char *)card->id().toUtf8()); + fprintf(f,"}\n"); + index++; } } fprintf(f,"%s\n",END_MARKER); @@ -311,10 +277,7 @@ void RDAlsaModel::LoadSystemConfig() while(snd_ctl_open(&snd_ctl,QString::asprintf("hw:%d",index).toUtf8(),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); - } + printf("[%d]: %s\n\n",index,model_alsa_cards.back()->dump().toUtf8().constData()); snd_ctl_close(snd_ctl); index++; } diff --git a/utils/rdalsaconfig/rdalsamodel.h b/utils/rdalsaconfig/rdalsamodel.h index e53c745d..222b09ab 100644 --- a/utils/rdalsaconfig/rdalsamodel.h +++ b/utils/rdalsaconfig/rdalsamodel.h @@ -2,7 +2,7 @@ // // Abstract an ALSA configuration. // -// (C) Copyright 2009-2018 Fred Gleason +// (C) Copyright 2009-2025 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 @@ -42,9 +42,7 @@ class RDAlsaModel : public QAbstractListModel 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; + QModelIndex indexOf(const QString &card_id) const; bool isEnabled(int row) const; void setEnabled(int row,bool state); bool loadConfig(const QString &filename); @@ -53,8 +51,6 @@ class RDAlsaModel : public QAbstractListModel private: void LoadSystemConfig(); QList model_alsa_cards; - QList model_card_index; - QList model_pcm_index; unsigned model_sample_rate; QStringList model_other_lines; };