From: Pedro Lopez-C. <pl...@te...> - 2004-06-27 18:09:02
Attachments:
multiport_recording.txt
|
Hi, Attached is a document detailing the design and implementation for the feature, as I proposed days ago. Should I commit the document to the CVS repository, too ? Please comment. Branch creation and first goal is scheduled by the end of Monday 28. Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-06-28 10:37:44
|
On Sunday 27 Jun 2004 7:09 pm, Pedro Lopez-Cabanillas wrote: > Attached is a document detailing the design and implementation for > the feature, as I proposed days ago. Should I commit the document > to the CVS repository, too ? Feel free, no harm in it. > Please comment. I've read it, and it makes sense to me. Good stuff. Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-06-28 18:17:39
|
On Monday 28 June 2004 12:59, Chris Cannam wrote: > I've read it, and it makes sense to me. Good stuff. Thanks. Branch created, and first step committed now (design document too). The branch name is 'multiport_recording'. I have detected an early problem. You can record from several input sources, but (of course) all the inputs are merged on a single output port. They are also merged in a single segment. The note duration detection is based on a single map (m_noteOnMap, member of SoundDriver). The map handles a event for each noteon received, and it's updated with the note length when a noteoff is received. When you record from several input sources, two musicians can collide in the same note, and one is lost (and the other note may have a wrong length). How to solve this? One map for each subscription to the input port? Where? Move the m_noteOnMap(s) to the driver level? (ArtsDriver uses this trick, too). Any idea is welcome. Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-06-28 19:39:10
|
On Monday 28 Jun 2004 7:16 pm, Pedro Lopez-Cabanillas wrote: > The note duration detection is based on a single map (m_noteOnMap, > member of SoundDriver). The map handles a event for each noteon > received, and it's updated with the note length when a noteoff is > received. When you record from several input sources, two musicians > can collide in the same note, and one is lost (and the other note > may have a wrong length). > > How to solve this? One map for each subscription to the input port? > Where? Move the m_noteOnMap(s) to the driver level? (ArtsDriver > uses this trick, too). Any idea is welcome. I'm not sure about "solving" this, as in fact it seems like rather a fundamental problem with the whole idea (that admittedly I should have thought of but didn't). So long as these events are ultimately destined for the same channel on the same MIDI device, which if they're stored in the same segment they must be, then note on/off events on the same pitch originating from separate performers will always end up being bungled, and there's nothing you can do about it. The only options are (1) to always automatically split into multiple tracks when recording like this -- which is the multi-track recording goal, but we were presumably trying to avoid having to go the whole hog with that at the outset; (2) to permit a single track to contain notes that play to more than one channel or instrument, with the associated GUI confusion; (3) to live with the note on/off bungling on playback, on the assumption that if you know enough to be doing this and you care about the problem, you can just split the track yourself. (1) would be fine but is really a bigger project than we should probably be doing now. (2) is IMHO a bad idea all round, and (3) is fairly unsatisfactory from a user perspective, although it might be tolerable if the feature wasn't widely advertised anyway. To answer the question you were actually asking: m_noteOnMap is a SoundDriver data member but it's not referred to in any SoundDriver code and there are no public SoundDriver methods using it. Ergo, there's no compelling reason it should be a member of SoundDriver rather than the subclasses. And it's a bit of a hack anyway; conceptually it's really a map<ChannelNo, map<Pitch, MappedEvent *> > but the channel number and pitch have been rolled into a single int for brevity. I would see no problem with unrolling them, giving a more complex definition but probably simpler usage, and making it obvious how to include another level of indirection (say to map from origin port to channel number to pitch to mapped event). The problem is more that I don't see how this would help, since the events would then all be sent off to the same channel on the same MIDI device anyway. Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-06-28 21:19:51
|
On Monday 28 June 2004 22:01, Chris Cannam wrote: > On Monday 28 Jun 2004 7:16 pm, Pedro Lopez-Cabanillas wrote: > > When you record from several input sources, two musicians > > can collide in the same note, and one is lost (and the other note > > may have a wrong length). [...] > The only options are (1) to always automatically split into multiple > tracks when recording like this -- which is the multi-track recording > goal, but we were presumably trying to avoid having to go the whole > hog with that at the outset; (2) to permit a single track to contain > notes that play to more than one channel or instrument, with the > associated GUI confusion; (3) to live with the note on/off bungling > on playback, on the assumption that if you know enough to be doing > this and you care about the problem, you can just split the track > yourself. > > (1) would be fine but is really a bigger project than we should > probably be doing now. (2) is IMHO a bad idea all round, and (3) is > fairly unsatisfactory from a user perspective, although it might be > tolerable if the feature wasn't widely advertised anyway. Well, (3) is really what we have when a bug is known, but a fix isn't available yet. What about to think a bit about it during some time, and wait for somebody having a good idea to fix the issue, or to arrive to (1). We don't need to implement the whole feature before release 1.0, only before sf.net blacklist my ISP again ;-) > The problem > is more that I don't see how this would help, since the events would > then all be sent off to the same channel on the same MIDI device > anyway. When you play the same note twice, there are MIDI instruments that ignore the second note, but other instruments can do something with it. There is nothing about it on the MIDI specification. For instance, see: http://www.borg.com/~jglatt/tech/midispec/noteon.htm If a device receives a Note On for a note (number) that is already playing (ie, hasn't been turned off yet), it the device's decision whether to layer another "voice" playing the same pitch, or cut off the voice playing the preceding note of that same pitch in order to "retrigger" that note. I have two Roland synthesizers, both accepting a second note-on message for an already active note. The problem about what to do with doubled notes should not be fixed by the sequencer software, IMO. Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-06-29 11:54:32
|
On Monday 28 Jun 2004 10:19 pm, Pedro Lopez-Cabanillas wrote: > When you play the same note twice, there are MIDI instruments that > ignore the second note, but other instruments can do something with > it. There is nothing about it on the MIDI specification. True, but neither option will ever be wholly satisfactory because an instrument has no way to decide which of the NOTE ONs to switch off when the first NOTE OFF is received. Playing polyphony to a single channel is just a dangerous thing to do. Anyway, you're right that that's hardly an overwhelming argument against making the sequencer layer capable of recording from two separate sources at once. It just means we have a more open question of how best to deal with it once recorded, but then we always would have that question really. So no, go ahead -- bring the note on map down into the AlsaDriver (and ArtsDriver), make it a nested map channel -> pitch -> event, and add an extra layer of nesting for the input port or whatever. I'm considering some changes to the note off queue as well (the one used during playback). We actually currently handle note offs in two different ways at once -- we enqueue a SEQ_EVENT_NOTE type event for each note of which we know the duration, but then we also have our own note-off queue which is used for these events as well, resulting in confusion and multiple note-offs, which fortunately don't actually matter in practice (usually). Also our note-off queue is an ordered set (std::multiset) in an attempt (I presume) to ensure they're delivered in order: that won't work in practice, because the NOTE OFF for a note can be queued and scavenged to the ALSA queue by processNotesOff before a later-starting note that ends earlier has even been enqueued. Again that doesn't matter when we're only delivering to the ALSA sequencer queue, but it's causing me problems now because I'm trying to deliver these events to hosted soft-synths for which they need to be known to be in order. The upshot of all this is just that you should probably be aware of any changes to the playback code in AlsaDriver.cpp while you're working on recording in the branch. Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-03 17:59:58
|
Hi, Another batch of changes is now committed to the 'multiport_recording' branch, and the second phase should be now completed. At this point, we can connect several record inputs in the Studio window, and disconnect them. The port connection state will be saved in the resource settings file (rosegardenrc), and restored again in the next program run. External programs like aconnect or kaconnect can also be used to manage the input port subscriptions. There is a funny behavior, though. If you connect another input device using a external program, like "aconnect", the connection is shown in the Studio window, but it is not saved to the configuration file, so it won't be restored the next time rosegarden is run. Also, externally made connections take less precedence over persistent connections, so if you unsubscribe a saved (in "rosegardenrc") connection with an external program, it will be restored by rosegarden as soon as the change is detected, obstinately. On Tuesday 29 June 2004 14:17, Chris Cannam wrote: > On Monday 28 Jun 2004 10:19 pm, Pedro Lopez-Cabanillas wrote: > > When you play the same note twice, there are MIDI instruments that > > ignore the second note, but other instruments can do something with > > it. There is nothing about it on the MIDI specification. > > True, but neither option will ever be wholly satisfactory because an > instrument has no way to decide which of the NOTE ONs to switch off > when the first NOTE OFF is received. Playing polyphony to a single > channel is just a dangerous thing to do. Some expanders I own use a simple FIFO algorithm, the first NOTE OFF received stops the older playing note. I have to say that this is not an issue with multiport recording only. You can already draw several overlapping notes with the matrix editor, now. RG plays these notes correctly, AFAICS. > So no, go ahead -- bring the note on map down into the AlsaDriver (and > ArtsDriver), make it a nested map channel -> pitch -> event, and add > an extra layer of nesting for the input port or whatever. OK, I will try it as the next task in this branch. > I'm considering some changes to the note off queue as well [...] > The upshot of all this is just that you should probably be aware of > any changes to the playback code in AlsaDriver.cpp while you're > working on recording in the branch. OK, I will be watching on it. Regards, Pedro |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-04 23:35:18
|
On Saturday 03 July 2004 20:00, Pedro Lopez-Cabanillas wrote: > I have to say that this is not an issue with multiport recording only. You > can already draw several overlapping notes with the matrix editor, now. RG > plays these notes correctly, AFAICS. No. It doesn't. Excess of noteoff messages, but it's a known issue IIRC. BTW, I've finished the refactoring of note-on-maps, in Alsa/Arts/Sound-Driver and also another one in RosegardenGUIDoc (see rosegardenguidoc.h, look for m_noteOnEvents). Are there two of everything in Rosegarden ? ;-) If I can finish the third phase, the final commit for the 'multiport_recording' branch will be Monday night. Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-07-05 08:07:38
|
On Monday 05 Jul 2004 12:33 am, Pedro Lopez-Cabanillas wrote: > No. It doesn't. Excess of noteoff messages, but it's a known issue And I think one that should now be fixed in HEAD. > BTW, I've finished the refactoring of note-on-maps, in > Alsa/Arts/Sound-Driver and also another one in RosegardenGUIDoc > (see rosegardenguidoc.h, look for m_noteOnEvents). Are there two of > everything in Rosegarden ? ;-) There are usually at least three of everything -- are you sure you haven't missed one? Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-05 18:46:10
|
Hi, Third and last batch of changes are committed now. We can record from several ports and channels at once, and notes are recorded properly. The recorded channels and ports are stored as non-persistent properties for each recorded event (you won't see it in the advanced event editor dialog, but they are. Believe me). Some more testing is needed before a merge with HEAD. Chris: how should we manage the merge? On Monday 05 July 2004 10:31, Chris Cannam wrote: > On Monday 05 Jul 2004 12:33 am, Pedro Lopez-Cabanillas wrote: > > Are there two of everything in Rosegarden ? ;-) > > There are usually at least three of everything -- are you sure you > haven't missed one? You are pulling my leg! Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-07-06 15:58:26
|
On Monday 05 Jul 2004 7:46 pm, Pedro Lopez-Cabanillas wrote: > The recorded channels and ports are stored as > non-persistent properties for each recorded event (you won't see > it in the advanced event editor dialog, but they are. Believe me). Why are you so confident that they are? The advanced event editor should be showing you all the persistent and non-persistent properties. Also despite being called non-persistent, the non-persistent properties are also saved to file (as <nproperty ...> instead of <property ...>) -- I just had a crack at recording something on this branch and saving it, and I couldn't see any of these recording properties in the resulting .rg file. I don't have any alternative suggestion for what's happened to the properties, you understand. It is supposed to be that they persist until an event is copied (with copy constructor etc) and then they are lost. > Some more testing is needed before a merge with HEAD. One thing that struck me just now is that you can now select multiple record inputs on the MIDI device dialog, but you can't unselect them -- this is because we were previously hacking the behaviour of the checkbox table item to make it behave like a radio button (there being no native radio button table item), and some of that behaviour is apparently still in there. > Chris: how should we manage the merge? Um, we agree when it's ready and then one of us merges it? Should be straightforward I think. > On Monday 05 July 2004 10:31, Chris Cannam wrote: > > On Monday 05 Jul 2004 12:33 am, Pedro Lopez-Cabanillas wrote: > > > Are there two of everything in Rosegarden ? ;-) > > > > There are usually at least three of everything -- are you sure > > you haven't missed one? > > You are pulling my leg! Yes, but only just. Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-06 18:32:36
|
On Tuesday 06 July 2004 18:22, Chris Cannam wrote: > On Monday 05 Jul 2004 7:46 pm, Pedro Lopez-Cabanillas wrote: > > The recorded channels and ports are stored as > > non-persistent properties for each recorded event (you won't see > > it in the advanced event editor dialog, but they are. Believe me). > > Why are you so confident that they are? The advanced event editor > should be showing you all the persistent and non-persistent > properties. Also despite being called non-persistent, the > non-persistent properties are also saved to file (as <nproperty ...> > instead of <property ...>) -- I just had a crack at recording > something on this branch and saving it, and I couldn't see any of > these recording properties in the resulting .rg file. I was confident because when i change one of the new lines at rosegardenguidoc.cpp from this: rEvent->set<Int>(RECORDED_CHANNEL, channel, false); to this: rEvent->set<Int>(RECORDED_CHANNEL, channel); The "recordedchannel" property shows up in the advanced event editor, and also is properly stored on a file. Looking to the code, Event::toXmlString() seems to do what you say, so I must assume that a persistent=false argument makes the property to be discarded very soon, at some point before reaching the advanced event editor and the save function. I can't reproduce a crash while saving. Can you point me to some clue or procedure to trigger the crash? > I don't have any alternative suggestion for what's happened to the > properties, you understand. It is supposed to be that they persist > until an event is copied (with copy constructor etc) and then they > are lost. OK, So I assume that a copy of these events is made very soon, and the new properties are lost. What do you prefer: to set the properties as persistent, or to search for the point where the copy is made and set the properties again in the copy? > One thing that struck me just now is that you can now select multiple > record inputs on the MIDI device dialog, but you can't unselect them > -- this is because we were previously hacking the behaviour of the > checkbox table item to make it behave like a radio button (there > being no native radio button table item), and some of that behaviour > is apparently still in there. It's possible to unselect them, but the behavior is very ugly, yes. When you click over a selected checkbox, it seems to do nothing until the dialog receives a refresh event. Then it shows the right state. I'm going to look for the gremlins, and kill them before midnight. Regards, Pedro |
From: William <ros...@li...> - 2004-07-06 19:01:29
|
Pedro Lopez-Cabanillas wrote: > > I can't reproduce a crash while saving. Can you point me to some clue or > procedure to trigger the crash? I think Chris' colloquialism "I just had a crack at [something]" was intended to mean "I just tried something" rather than "I had a crash in something". Your multi-port recording functionality looks very interesting. I look forward to using it. William |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-06 21:30:24
|
On Tuesday 06 July 2004 21:07, William wrote: > Pedro Lopez-Cabanillas wrote: > > I can't reproduce a crash while saving. Can you point me to some clue or > > procedure to trigger the crash? > > I think Chris' colloquialism "I just had a crack at [something]" was > intended to mean "I just tried something" rather than "I had a crash in > something". Oh. Thanks for the info, I was a bit worried. Despite the opinion that Michael has about my English, it is not very good. I don't understand a lot of idioms, and this word in Spanish (grieta, estallido, crujido, romper, partir) is often used to describe a program crash. Now I see that my "Cambridge Klett Compact dictionary" says that "crack" is also the sound of a breaking branch. Very suitable word, Chris ;-) > Your multi-port recording functionality looks very interesting. > I look forward to using it. Thanks. To have the feature merged we need two things: first, more testing and fixes for the bugs that may be introduced into the branch. And second: a little push for an agreement on the merge. BTW, I have committed a fix for the checkboxes in the Studio window. Regards, Pedro |
From: Silvan <dmm...@us...> - 2004-07-06 23:01:35
|
On Tuesday 06 July 2004 05:31 pm, Pedro Lopez-Cabanillas wrote: > Oh. Thanks for the info, I was a bit worried. Despite the opinion that > Michael has about my English, it is not very good. I don't understand a lot All I've said is that your English is better than my Spanish. That still gives you PLENTY of room to have trouble understanding idioms! :) > "Cambridge Klett Compact dictionary" says that "crack" is also the sound of > a breaking branch. Very suitable word, Chris ;-) To "have a crack at" something could be expressed in various other ways. To attempt, to try out, to take a stab at... I'd imagine (imagine, mind you) historically it has its roots in cracking a whip. I'd say furthermore it's more of a British expression, though it's not incomprehensible on this side of the water. -- Michael McIntyre ---- Silvan <dmm...@us...> Linux fanatic, and certified Geek; registered Linux user #243621 http://www.geocities.com/Paris/Rue/5407/ |
From: Chris C. <ca...@al...> - 2004-07-07 09:43:39
|
On Tuesday 06 Jul 2004 7:33 pm, Pedro Lopez-Cabanillas wrote: > OK, So I assume that a copy of these events is made very soon, and > the new properties are lost. What do you prefer: to set the > properties as persistent, or to search for the point where the copy > is made and set the properties again in the copy? Ideally, to find the point where the copy is made, and then decide what to do about it. [other email] > BTW, I have committed a fix for the checkboxes in the Studio window. Seems to work. One other thing -- this branch no longer seems to pick up new record devices that appear after RG is started. e.g. start RG, look at the device dialog, see that there is one record device (my soundcard), close the device dialog, switch on my USB MIDI keyboard, wait twenty seconds just to be sure, pop up the device dialog -- still only one record device. This does work on HEAD currently. Chris |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-07 15:58:48
|
On Wednesday 07 July 2004 12:08, Chris Cannam wrote: > One other thing -- this branch no longer seems to pick up new record > devices that appear after RG is started. e.g. start RG, look at the > device dialog, see that there is one record device (my soundcard), > close the device dialog, switch on my USB MIDI keyboard, wait twenty > seconds just to be sure, pop up the device dialog -- still only one > record device. This does work on HEAD currently. Fixed now. It happened only when RG had zero record devices selected. The AlsaDriver's data member m_midiInputPortConnected is meaningless in this branch, because the input port is ever connected to the system:announce port. I'm thinking to remove the data member. Regards, Pedro |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-07 18:20:37
|
On Wednesday 07 July 2004 12:08, Chris Cannam wrote: > On Tuesday 06 Jul 2004 7:33 pm, Pedro Lopez-Cabanillas wrote: > > OK, So I assume that a copy of these events is made very soon, and > > the new properties are lost. What do you prefer: to set the > > properties as persistent, or to search for the point where the copy > > is made and set the properties again in the copy? > > Ideally, to find the point where the copy is made, and then decide > what to do about it. Using some breakpoints, i think that Quantizer::setToTarget() seems to be guilty. I have this backtrace: 13 Rosegarden::Quantizer::setToTarget() at Quantizer.C:381 12 Rosegarden::NotationQuantizer::Impl::quantizeRange() at Quantizer.C:1914 11 Rosegarden::NotationQuantizer::quantizeRange() at Quantizer.C:1748 10 Rosegarden::Quantizer::quantize() at Quantizer.C:90 9 EventQuantizeCommand::modifySegment() at editcommands.cpp:876 8 BasicCommand::execute() at basiccommand.cpp:82 7 KMacroCommand::execute() 6 RosegardenGUIDoc::stopRecordingMidi() at rosegardenguidoc.cpp:1599 5 Rosegarden::SequenceManager::stop() at sequencemanager.cpp:416 4 Rosegarden::SequenceManager::stopping() at sequencemanager.cpp:360 3 RosegardenGUIApp::slotStop() at rosegardengui.cpp:4320 2 RosegardenGUIApp::qt_invoke() at rosegardengui.moc.cpp:718 1 QObject::activate_signal() It is well argued in the code why it is necessary a copy, but I don't see any harm to keep our new properties at this point. Another question is how to do that. Regards, Pedro |
From: Chris C. <ca...@al...> - 2004-07-07 19:12:49
|
On Wednesday 07 Jul 2004 18:21, Pedro Lopez-Cabanillas wrote: > Using some breakpoints, i think that Quantizer::setToTarget() seems to be > guilty. Ah... yes, of course. > It is well argued in the code why it is necessary a copy, but I don't see > any harm to keep our new properties at this point. Another question is how > to do that. I would say in this case we should probably take the easy route and just make them persistent properties. It isn't the end of the world if the original recorded channel remains in an event even when it's edited (moved to another track or wherever). Is it? Chris |
From: Silvan <dmm...@us...> - 2004-07-07 19:24:42
|
On Wednesday 07 July 2004 04:03 pm, Chris Cannam wrote: > I would say in this case we should probably take the easy route and just > make them persistent properties. It isn't the end of the world if the > original recorded channel remains in an event even when it's edited (moved > to another track or wherever). Is it? Not if events are only allowed to play on whatever channel the track they're sitting on is assigned to. It doesn't seem like it would really matter. -- Michael McIntyre ---- Silvan <dmm...@us...> Linux fanatic, and certified Geek; registered Linux user #243621 http://www.geocities.com/Paris/Rue/5407/ |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-07 20:28:32
|
On Wednesday 07 July 2004 21:24, Silvan wrote: > On Wednesday 07 July 2004 04:03 pm, Chris Cannam wrote: > > I would say in this case we should probably take the easy route and just > > make them persistent properties. It isn't the end of the world if the > > original recorded channel remains in an event even when it's edited > > (moved to another track or wherever). Is it? > > Not if events are only allowed to play on whatever channel the track > they're sitting on is assigned to. It doesn't seem like it would really > matter. The new properties aren't used yet for any functionality, so it doesn't matter if the properties are persistent, or even if they aren't at all. My first thought was to make it non-persistent to avoid to waste space storing them to disk. But then, Chris pointed me to the fact that even if they aren't persistent, the properties would be stored anyway. Regards, Pedro |
From: Pedro Lopez-C. <pl...@te...> - 2004-07-07 20:19:49
|
On Wednesday 07 July 2004 22:03, Chris Cannam wrote: > I would say in this case we should probably take the easy route and just > make them persistent properties. It isn't the end of the world if the > original recorded channel remains in an event even when it's edited (moved > to another track or wherever). Is it? No, you are right. I have committed the change. Regards, Pedro |