Blob Blame History Raw
--- MuseScore-3.6.2/audio/drivers/alsa.cpp.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/audio/drivers/alsa.cpp	2022-11-30 10:08:06.384582516 -0700
@@ -615,7 +615,10 @@ int AlsaAudio::sampleRate() const
 AlsaAudio::~AlsaAudio()
       {
       stop();
-      delete alsa;
+      if (alsa != nullptr)
+            delete alsa;
+      if (midiDriver != nullptr)
+            delete midiDriver;
       }
 
 //---------------------------------------------------------
--- MuseScore-3.6.2/audio/drivers/alsamidi.h.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/audio/drivers/alsamidi.h	2022-11-29 15:52:51.398045780 -0700
@@ -39,15 +39,17 @@ struct PortName {
 
 class AlsaMidiDriver : public MidiDriver {
       snd_seq_t* alsaSeq;
+      QList<QSocketNotifier*> notifiers;
 
       bool putEvent(snd_seq_event_t* event);
       QList<PortName> outputPorts();
       QList<PortName> inputPorts();
       bool connect(Port src, Port dst);
+      bool disconnect(Port src, Port dst);
 
    public:
       AlsaMidiDriver(Seq* s);
-      virtual ~AlsaMidiDriver() {}
+      virtual ~AlsaMidiDriver();
       virtual bool init();
       virtual Port registerOutPort(const QString& name);
       virtual Port registerInPort(const QString& name);
--- MuseScore-3.6.2/audio/drivers/mididriver.cpp.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/audio/drivers/mididriver.cpp	2022-11-29 16:32:47.008159978 -0700
@@ -116,6 +116,25 @@ AlsaMidiDriver::AlsaMidiDriver(Seq* s)
       {
       }
 
+AlsaMidiDriver::~AlsaMidiDriver()
+      {
+      // disconnect all midi sources from mscore
+      QList<PortName> il = inputPorts();
+      foreach(PortName pn, il) {
+            if (MScore::debugMode)
+                  qDebug("connect to midi input <%s>", qPrintable(pn.name));
+            disconnect(pn.port, midiInPort);
+            }
+
+      // deallocate the notifiers
+      foreach(QSocketNotifier *s, notifiers) {
+            delete s;
+            }
+
+      // Close the ALSA sequencer
+      snd_seq_close(alsaSeq);
+      }
+
 //---------------------------------------------------------
 //   init
 //    return false on error
@@ -173,6 +192,7 @@ bool AlsaMidiDriver::init()
             if (fd != -1) {
                   QSocketNotifier* s = new QSocketNotifier(fd, QSocketNotifier::Read,  mscore);
                   s->connect(s, SIGNAL(activated(int)), seq, SLOT(midiInputReady()));
+		  notifiers.append(s);
                   }
             }
 #if 0
@@ -286,6 +306,35 @@ bool AlsaMidiDriver::connect(Port src, P
                src.alsaClient(), src.alsaPort(),
                dst.alsaClient(), dst.alsaPort(),
                snd_strerror(rv));
+            return false;
+            }
+      return true;
+      }
+
+//---------------------------------------------------------
+//   disconnect
+//    return false if disconnect fails
+//---------------------------------------------------------
+
+bool AlsaMidiDriver::disconnect(Port src, Port dst)
+      {
+      snd_seq_port_subscribe_t* sub;
+      snd_seq_port_subscribe_alloca(&sub);
+
+      snd_seq_addr_t s, d;
+      s.port   = src.alsaPort();
+      s.client = src.alsaClient();
+      d.port   = dst.alsaPort();
+      d.client = dst.alsaClient();
+      snd_seq_port_subscribe_set_sender(sub, &s);
+      snd_seq_port_subscribe_set_dest(sub, &d);
+
+      int rv = snd_seq_unsubscribe_port(alsaSeq, sub);
+      if (rv < 0) {
+            qDebug("AlsaMidi::disconnect(%d:%d, %d:%d) failed: %s",
+               src.alsaClient(), src.alsaPort(),
+               dst.alsaClient(), dst.alsaPort(),
+               snd_strerror(rv));
             return false;
             }
       return true;
--- MuseScore-3.6.2/audio/drivers/pm.cpp.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/audio/drivers/pm.cpp	2022-11-30 10:15:47.520402385 -0700
@@ -55,6 +55,9 @@ PortMidiDriver::~PortMidiDriver()
             Pt_Stop();
             Pm_Close(inputStream);
             }
+      if (outputStream) {
+            Pm_Close(outputStream);
+            }
       }
 
 //---------------------------------------------------------
--- MuseScore-3.6.2/audio/drivers/pulseaudio.cpp.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/audio/drivers/pulseaudio.cpp	2022-11-30 10:21:39.688303296 -0700
@@ -33,6 +33,8 @@ class PulseAudio : public Driver {
       int _sampleRate;
       pa_sample_spec ss;
       pa_mainloop* pa_ml;
+      pa_context* pa_ctx;
+      pa_stream *playstream;
       pa_buffer_attr bufattr;
       float buffer[FRAMES * 2];
       pthread_t thread;
@@ -87,6 +89,10 @@ PulseAudio::PulseAudio(Seq* s)
 PulseAudio::~PulseAudio()
       {
       stop();
+      pa_stream_unref(playstream);
+      pa_context_disconnect(pa_ctx);
+      pa_context_unref(pa_ctx);
+      pa_mainloop_free(pa_ml);
       }
 
 //---------------------------------------------------------
@@ -123,7 +129,7 @@ bool PulseAudio::init(bool)
       {
       pa_ml                     = pa_mainloop_new();
       pa_mainloop_api* pa_mlapi = pa_mainloop_get_api(pa_ml);
-      pa_context* pa_ctx        = pa_context_new(pa_mlapi, "MuseScore");
+      pa_ctx                    = pa_context_new(pa_mlapi, "MuseScore");
       if (pa_context_connect(pa_ctx, NULL, pa_context_flags_t(0), NULL) != 0) {
             qDebug("PulseAudio Context Connect Failed with Error: %s", pa_strerror(pa_context_errno(pa_ctx)));
             return false;
@@ -141,7 +147,7 @@ bool PulseAudio::init(bool)
       ss.channels = 2;
       ss.format   = PA_SAMPLE_FLOAT32LE;
 
-      pa_stream* playstream = pa_stream_new(pa_ctx, "Playback", &ss, NULL);
+      playstream = pa_stream_new(pa_ctx, "Playback", &ss, NULL);
       if (!playstream) {
             qDebug("pa_stream_new failed: %s", pa_strerror(pa_context_errno(pa_ctx)));
             return false;
--- MuseScore-3.6.2/mscore/seq.h.orig	2021-02-08 05:16:37.000000000 -0700
+++ MuseScore-3.6.2/mscore/seq.h	2022-11-30 10:10:11.632514412 -0700
@@ -270,7 +270,7 @@ class Seq : public QObject, public Seque
       void initInstruments(bool realTime = false);
 
       Driver* driver()                                 { return _driver; }
-      void setDriver(Driver* d)                        { _driver = d;    }
+      void setDriver(Driver* d)                        { if (_driver != nullptr) delete _driver; _driver = d;    }
       MasterSynthesizer* synti() const                 { return _synti;  }
       void setMasterSynthesizer(MasterSynthesizer* ms) { _synti = ms;    }