summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse/ChangeLog7
-rw-r--r--muse/muse/conf.cpp7
-rw-r--r--muse/muse/driver/alsamidi.cpp6
-rw-r--r--muse/muse/driver/jackmidi.cpp6
-rw-r--r--muse/muse/node.cpp72
-rw-r--r--muse/muse/route.cpp6
-rw-r--r--muse/muse/song.cpp43
7 files changed, 137 insertions, 10 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index 88bfdbf8..44125d7b 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,10 @@
+22.06.2010
+ * Fixed: Crashes loading a song while another is loaded. Or worse, it loads but saving corrupts the file! (T356)
+ - Song::clear(): Clear all midi port devices. Delete Jack midi devices, and remove all ALSA midi device routes.
+ - Route::read() Ignore bogus midi routes in med file if the device they refer to is not in use by the song (port is -1).
+ - MidiJackDevice::writeRouting(), MidiAlsaDevice::writeRouting(): Ignore and do not write midi routes if the device
+ they refer to is not in use by the song (port is -1). This prevents bogus midi routes writing to med file.
+ - Fifo::~Fifo(): Free the buffers! Fifo::getWriteBuffer(), Fifo::put(): Verify allocation. Fifo::get(): Verify buffers.
15.06.2010
* Fixed: Jack midi output: Sent pitch bend and program values were incorrect, if coming from midi keyboard. (T356)
- Reported by Pieter while using Hurdy Gurdy vst under fst. Tests OK now, here.
diff --git a/muse/muse/conf.cpp b/muse/muse/conf.cpp
index 8af9994b..daf74126 100644
--- a/muse/muse/conf.cpp
+++ b/muse/muse/conf.cpp
@@ -269,8 +269,8 @@ static void readConfigMidiPort(Xml& xml)
MidiDevice* dev = midiDevices.find(device);
- if(debugMsg && !dev)
- fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.latin1());
+ //if(debugMsg && !dev)
+ // fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.latin1());
if(!dev && type == MidiDevice::JACK_MIDI)
{
@@ -279,6 +279,9 @@ static void readConfigMidiPort(Xml& xml)
dev = MidiJackDevice::createJackMidiDevice(device, openFlags);
}
+ if(debugMsg && !dev)
+ fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.latin1());
+
MidiPort* mp = &midiPorts[idx];
mp->syncInfo().copyParams(tmpSi);
if (dev) {
diff --git a/muse/muse/driver/alsamidi.cpp b/muse/muse/driver/alsamidi.cpp
index de39d48f..5a057104 100644
--- a/muse/muse/driver/alsamidi.cpp
+++ b/muse/muse/driver/alsamidi.cpp
@@ -176,6 +176,12 @@ void MidiAlsaDevice::close()
void MidiAlsaDevice::writeRouting(int level, Xml& xml) const
{
+ // p3.3.45
+ // If this device is not actually in use by the song, do not write any routes.
+ // This prevents bogus routes from being saved and propogated in the med file.
+ if(midiPort() == -1)
+ return;
+
QString s;
/*
//if(rwFlags() & 2) // Readable
diff --git a/muse/muse/driver/jackmidi.cpp b/muse/muse/driver/jackmidi.cpp
index 0cdc1393..09b39f68 100644
--- a/muse/muse/driver/jackmidi.cpp
+++ b/muse/muse/driver/jackmidi.cpp
@@ -511,6 +511,12 @@ void MidiJackDevice::close()
void MidiJackDevice::writeRouting(int level, Xml& xml) const
{
+ // p3.3.45
+ // If this device is not actually in use by the song, do not write any routes.
+ // This prevents bogus routes from being saved and propogated in the med file.
+ if(midiPort() == -1)
+ return;
+
QString s;
if(rwFlags() & 2) // Readable
{
diff --git a/muse/muse/node.cpp b/muse/muse/node.cpp
index ab075b01..47fbf1f2 100644
--- a/muse/muse/node.cpp
+++ b/muse/muse/node.cpp
@@ -1666,7 +1666,17 @@ Fifo::Fifo()
Fifo::~Fifo()
{
for (int i = 0; i < nbuffer; ++i)
- delete buffer[i];
+ {
+ // p3.3.45
+ if(buffer[i]->buffer)
+ {
+ //printf("Fifo::~Fifo freeing buffer\n");
+ free(buffer[i]->buffer);
+ }
+
+ delete buffer[i];
+ }
+
delete[] buffer;
muse_atomic_destroy(&count);
}
@@ -1691,14 +1701,32 @@ bool Fifo::put(int segs, unsigned long samples, float** src, unsigned pos)
int n = segs * samples;
if (b->maxSize < n) {
if (b->buffer)
- // Changed by Tim. p3.3.15
- //delete[] b->buffer;
- free(b->buffer);
+ {
+ // Changed by Tim. p3.3.15
+ //delete[] b->buffer;
+ free(b->buffer);
+ // p3.3.45
+ b->buffer = 0;
+ }
// Changed by Tim. p3.3.15
//b->buffer = new float[n];
posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
+ // p3.3.45
+ if(!b->buffer)
+ {
+ printf("Fifo::put could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos);
+ return true;
+ }
+
b->maxSize = n;
}
+ // p3.3.45
+ if(!b->buffer)
+ {
+ printf("Fifo::put no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos);
+ return true;
+ }
+
b->size = samples;
b->segs = segs;
b->pos = pos;
@@ -1726,9 +1754,16 @@ bool Fifo::get(int segs, unsigned long samples, float** dst, unsigned* pos)
return true;
}
FifoBuffer* b = buffer[ridx];
-
+ // p3.3.45
+ if(!b->buffer)
+ {
+ printf("Fifo::get no buffer! segs:%d samples:%lu b->pos:%u\n", segs, samples, b->pos);
+ return true;
+ }
+
if (pos)
*pos = b->pos;
+
for (int i = 0; i < segs; ++i)
dst[i] = b->buffer + samples * (i % b->segs);
remove();
@@ -1766,16 +1801,37 @@ bool Fifo::getWriteBuffer(int segs, unsigned long samples, float** buf, unsigned
int n = segs * samples;
if (b->maxSize < n) {
if (b->buffer)
- // Changed by Tim. p3.3.15
- //delete[] b->buffer;
- free(b->buffer);
+ {
+ // Changed by Tim. p3.3.15
+ //delete[] b->buffer;
+ free(b->buffer);
+ // p3.3.45
+ b->buffer = 0;
+ }
+
// Changed by Tim. p3.3.15
//b->buffer = new float[n];
posix_memalign((void**)&(b->buffer), 16, sizeof(float) * n);
+ // p3.3.45
+ if(!b->buffer)
+ {
+ printf("Fifo::getWriteBuffer could not allocate buffer segs:%d samples:%lu pos:%u\n", segs, samples, pos);
+ return true;
+ }
+
b->maxSize = n;
}
+
+ // p3.3.45
+ if(!b->buffer)
+ {
+ printf("Fifo::getWriteBuffer no buffer! segs:%d samples:%lu pos:%u\n", segs, samples, pos);
+ return true;
+ }
+
for (int i = 0; i < segs; ++i)
buf[i] = b->buffer + i * samples;
+
b->size = samples;
b->segs = segs;
b->pos = pos;
diff --git a/muse/muse/route.cpp b/muse/muse/route.cpp
index 0b45fdf2..81838344 100644
--- a/muse/muse/route.cpp
+++ b/muse/muse/route.cpp
@@ -1163,6 +1163,12 @@ void Route::read(Xml& xml)
//if(md->name() == s)
if(md->name() == s && md->deviceType() == dtype)
{
+ // p3.3.45
+ // We found a device, but if it is not in use by the song (port is -1), ignore it.
+ // This prevents loading and propogation of bogus routes in the med file.
+ if(md->midiPort() == -1)
+ break;
+
device = md;
break;
}
diff --git a/muse/muse/song.cpp b/muse/muse/song.cpp
index bccb3f72..bba86eb3 100644
--- a/muse/muse/song.cpp
+++ b/muse/muse/song.cpp
@@ -18,6 +18,8 @@
#include <qbutton.h>
#include "app.h"
+#include "driver/jackmidi.h"
+#include "driver/alsamidi.h"
#include "song.h"
#include "track.h"
#include "undo.h"
@@ -1947,8 +1949,49 @@ void Song::clear(bool signal)
_outputs.clearDelete(); // audio output ports
_groups.clearDelete(); // mixer groups
_auxs.clearDelete(); // aux sends
+
+ // p3.3.45 Clear all midi port devices.
+ for(int i = 0; i < MIDI_PORTS; ++i)
+ // This will also close the device.
+ midiPorts[i].setMidiDevice(0);
+
_synthIs.clearDelete();
+ // p3.3.45 Make sure to delete Jack midi devices, and remove all ALSA midi device routes...
+ // Otherwise really nasty things happen when loading another song when one is already loaded.
+ // The loop is a safe way to delete while iterating.
+ bool loop;
+ do
+ {
+ loop = false;
+ for(iMidiDevice imd = midiDevices.begin(); imd != midiDevices.end(); ++imd)
+ {
+ //if((*imd)->deviceType() == MidiDevice::JACK_MIDI)
+ if(dynamic_cast< MidiJackDevice* >(*imd))
+ {
+ // Remove the device from the list.
+ midiDevices.erase(imd);
+ // Since Jack midi devices are created dynamically, we must delete them.
+ // The destructor unregisters the device from Jack, which also disconnects all device-to-jack routes.
+ // This will also delete all midi-track-to-device routes, they point to non-existant midi tracks
+ // which were all deleted above
+ delete (*imd);
+ loop = true;
+ break;
+ }
+ else
+ //if((*imd)->deviceType() == MidiDevice::ALSA_MIDI)
+ if(dynamic_cast< MidiAlsaDevice* >(*imd))
+ {
+ // With alsa devices, we must not delete them (they're always in the list). But we must
+ // clear all routes. They point to non-existant midi tracks, which were all deleted above.
+ (*imd)->inRoutes()->clear();
+ (*imd)->outRoutes()->clear();
+ }
+ }
+ }
+ while (loop);
+
tempomap.clear();
sigmap.clear();
undoList->clearDelete();