Author Topic: Bassmidi CC93/Chorus on Drum channels in GM/GS mode  (Read 167 times)

Falcosoft

  • Posts: 214
Hi Ian,
A user of mine reported that he cannot use chorus controllers in GM/GS mode anymore in case of drum channels. I replied that it still works in XG mode but then he realized that he cannot use other (non zero) Drum banks in XG mode.
I remember the similar problem in case of CC94/UserFx so I would like to ask a similar solution.
(http://www.un4seen.com/forum/?topic=20320.msg142234#msg142234)
Namely a new flag (e.g BASS_MIDI_NODRUMPARAMCHORUS). That is a flag that still preserves the default reverb settings but allow the chorus effects to be applied to drum channels (independently).

PS:
I know about MIDI_EVENT_DRUM_CHORUS but it has the same problems as MIDI_EVENT_DRUM_USERFX. Namely you have to intercept all system reset and bank/pogram change messages etc.

Thanks in advance.
   

Ian @ un4seen

  • Administrator
  • Posts: 26254
I remember the similar problem in case of CC94/UserFx so I would like to ask a similar solution.
(http://www.un4seen.com/forum/?topic=20320.msg142234#msg142234)
Namely a new flag (e.g BASS_MIDI_NODRUMPARAMCHORUS). That is a flag that still preserves the default reverb settings but allow the chorus effects to be applied to drum channels (independently).

I'm not sure there are any more free flag bits for that, so an option may need to be added some other way. I'll have to think about it. Let me know if you have any suggestions.

Regarding the intercepting events solution, the per-drum params get reset by MIDI_EVENT_SYSTEM(EX), MIDI_EVENT_PROGRAM and MIDI_EVENT_DRUMS changes. So those are the ones you would need to catch and then override with your chorus level(s) via MIDI_EVENT_DRUM_CHORUS (note you can use key=255 to set all keys in a single event). If you're using BASS_MIDI_StreamEvent to play events then you can do the "intercepting" there, otherwise BASS_MIDI_StreamSetFilter could be used.

Falcosoft

  • Posts: 214
I remember the similar problem in case of CC94/UserFx so I would like to ask a similar solution.
(http://www.un4seen.com/forum/?topic=20320.msg142234#msg142234)
Namely a new flag (e.g BASS_MIDI_NODRUMPARAMCHORUS). That is a flag that still preserves the default reverb settings but allow the chorus effects to be applied to drum channels (independently).

I'm not sure there are any more free flag bits for that, so an option may need to be added some other way. I'll have to think about it. Let me know if you have any suggestions.

Regarding the intercepting events solution, the per-drum params get reset by MIDI_EVENT_SYSTEM(EX), MIDI_EVENT_PROGRAM and MIDI_EVENT_DRUMS changes. So those are the ones you would need to catch and then override with your chorus level(s) via MIDI_EVENT_DRUM_CHORUS (note you can use key=255 to set all keys in a single event). If you're using BASS_MIDI_StreamEvent to play events then you can do the "intercepting" there, otherwise BASS_MIDI_StreamSetFilter could be used.

Thanks,
I have tested setting MIDI_EVENT_DRUM_CHORUS in a SyncProc installed by BASS_MIDI_StreamSetFilter and I have noticed that MIDI_EVENT_DRUMS events are only triggered by GS style SysEx based drum channel messages.
E.g. in GM2 mode setting Bank MSB to 120 (drum) and back to 121 (melodic) together with a program change does not trigger an MIDI_EVENT_DRUMS event in the syncproc.
Can you confirm this not so consistent behavior? 
Also it seems that calling BASS_MIDI_StreamEvent() from the triggered syncproc directly does not work. I have to use PostMessage() Win32 API from the syncproc that calls BASS_MIDI_StreamEvent() when processed in the main loop.   

BTW, for me it seems there are still spaces for new flags. In case of BASS_MIDI_StreamCreate() the list of flags is:
Code: [Select]
// Additional BASS_MIDI_StreamCreateFile/etc flags
#define BASS_MIDI_NODRUMPARAMUSER 0x200
#define BASS_MIDI_NODRUMPARAM 0x400
#define BASS_MIDI_NOSYSRESET 0x800
#define BASS_MIDI_DECAYEND 0x1000
#define BASS_MIDI_NOFX 0x2000
#define BASS_MIDI_DECAYSEEK 0x4000
#define BASS_MIDI_NOCROP 0x8000
#define BASS_MIDI_NOTEOFF1 0x10000
#define BASS_MIDI_ASYNC 0x400000
#define BASS_MIDI_SINCINTER 0x800000

Acording to this e.g. 0x100 is free.
And even 0x20000, 0x40000 etc. are free in the upper region (between  BASS_MIDI_NOTEOFF1 and BASS_MIDI_ASYNC) .

« Last Edit: 13 Jan '25 - 22:00 by Falcosoft »

Ian @ un4seen

  • Administrator
  • Posts: 26254
I have tested setting MIDI_EVENT_DRUM_CHORUS in a SyncProc installed by BASS_MIDI_StreamSetFilter and I have noticed that MIDI_EVENT_DRUMS events are only triggered by GS style SysEx based drum channel messages.
E.g. in GM2 mode setting Bank MSB to 120 (drum) and back to 121 (melodic) together with a program change does not trigger an MIDI_EVENT_DRUMS event in the syncproc.
Can you confirm this not so consistent behavior? 
Also it seems that calling BASS_MIDI_StreamEvent() from the triggered syncproc directly does not work. I have to use PostMessage() Win32 API from the syncproc that calls BASS_MIDI_StreamEvent() when processed in the main loop.   

A bank change doesn't take effect until the next MIDI_EVENT_PROGRAM, so I don't think you would need to check them too, ie. you can just check the channel's MIDI_EVENT_DRUMS value at the time of the MIDI_EVENT_PROGRAM. Something like this:

Code: [Select]
BOOL CALLBACK MidiFilterProc(HSTREAM handle, int track, BASS_MIDI_EVENT *event, BOOL seeking, void *user)
{
if (event->event == MIDI_EVENT_PROGRAM) {
BASS_MIDI_StreamEvent(handle, event->chan, event->event,  event->param); // process the MIDI_EVENT_PROGRAM
if (BASS_MIDI_StreamGetEvent(handle, event->chan, MIDI_EVENT_DRUMS)) // if it's a drum channel...
BASS_MIDI_StreamEvent(handle, event->chan, MIDI_EVENT_DRUM_CHORUS, MAKEWORD(255, 127)); // set chorus=127 for all keys
return FALSE; // don't process the event (already did)
}
return TRUE; // process the event
}

BTW, for me it seems there are still spaces for new flags. In case of BASS_MIDI_StreamCreate() the list of flags is:
...
Acording to this e.g. 0x100 is free.
And even 0x20000, 0x40000 etc. are free in the upper region (between  BASS_MIDI_NOTEOFF1 and BASS_MIDI_ASYNC) .

Those other bits are used by common BASS flags that apply to all streams, eg. 0x100 = BASS_SAMPLE_FLOAT.

Falcosoft

  • Posts: 214
Thanks Ian,
unfortunately the equivalent of your code does not work for me.
I use a real-time Midi stream created by BASS_MIDI_StreamCreate() and I send most known events to the stream by BASS_MIDI_StreamEvent() for faster processing. This way syncs are not triggered by Program Change, Bank Select, Note on etc. messages as documented. Most likely that's why MIDI_EVENT_DRUMS does not worked for me either.
MIDI_EVENT_SYSTEM messages worked because they are sent by BASS_MIDI_StreamEvents() with BASS_MIDI_EVENTS_RAW and BASS_MIDI_EVENTS_FILTER flags set.

BTW, you have to intercept MIDI_EVENT_DRUMS events also since sending a GS SysEx message to switch drum channel status on/off does not trigger a sync that is set on Program Change but it works and it sets the proper drum channel status even without sending a Program Change message.

But to tell you the truth I do not like this intercepting/overriding events idea anyway at all to get chorus effects on drums...

Can you tell me that using BASS_MIDI_NODRUMPARAM is equivalent to the behavior of Bassmidi versions before the breaking change (e.g. Bassmidi.dll 2.4.12.1 from 2018) ?

« Last Edit: 14 Jan '25 - 19:04 by Falcosoft »

Ian @ un4seen

  • Administrator
  • Posts: 26254
unfortunately the equivalent of your code does not work for me.
I use a real-time Midi stream created by BASS_MIDI_StreamCreate() and I send most known events to the stream by BASS_MIDI_StreamEvent() for faster processing. This way syncs are not triggered by Program Change, Bank Select, Note on etc. messages as documented. Most likely that's why MIDI_EVENT_DRUMS does not worked for me either.

Indeed, BASS_MIDI_StreamEvent doesn't trigger a MIDIFILTERPROC callback because you already have access to the event and control over its processing then, ie. you can already filter it. The code in my last post could be used like this in that case:

Code: [Select]
BASS_MIDI_StreamEvent(handle, event->chan, event->event,  event->param); // process an event
if (event->event == MIDI_EVENT_PROGRAM) { // if it's MIDI_EVENT_PROGRAM...
if (BASS_MIDI_StreamGetEvent(handle, event->chan, MIDI_EVENT_DRUMS)) // and it's a drum channel...
BASS_MIDI_StreamEvent(handle, event->chan, MIDI_EVENT_DRUM_CHORUS, MAKEWORD(255, 127)); // set chorus=127 for all keys
}

Can you tell me that using BASS_MIDI_NODRUMPARAM is equivalent to the behavior of Bassmidi versions before the breaking change (e.g. Bassmidi.dll 2.4.12.1 from 2018) ?

BASSMIDI 2.4.12 was applying the XG default chorus (and reverb) levels in GS/GM modes too, some of which aren't 127. BASS_MIDI_NODRUMPARAM sets chorus/reverb/userfx=127 on all keys, so it isn't the same. BASSMIDI 2.4.12 did set chorus/reverb/userfx=127 in the MIDI_SYSTEM_DEFAULT mode though, so BASS_MIDI_NODRUMPARAM would achieve the same in that mode.

Falcosoft

  • Posts: 214
Thanks,
Am I right if I suppose that BASS_MIDI_NODRUMPARAM applied is the setting that resembles most the working of SB hardware SF2 synths regarding reverb/chorus effects on drum channels?

Ian @ un4seen

  • Administrator
  • Posts: 26254
Yeah, I think so, as it doesn't look like SB hardware supports setting per-drum levels via MIDI (only in the soundfont).