diff options
-rw-r--r-- | muse/ChangeLog | 7 | ||||
-rw-r--r-- | muse/muse/conf.cpp | 7 | ||||
-rw-r--r-- | muse/muse/driver/alsamidi.cpp | 6 | ||||
-rw-r--r-- | muse/muse/driver/jackmidi.cpp | 6 | ||||
-rw-r--r-- | muse/muse/node.cpp | 72 | ||||
-rw-r--r-- | muse/muse/route.cpp | 6 | ||||
-rw-r--r-- | muse/muse/song.cpp | 43 |
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(); |