Author Topic: Stop MIDI playing but keep sounding all last MIDI-notes  (Read 87 times)

Oleg

  • Posts: 2
I have the standard code:
Code: [Select]
    Stream = BASS_MIDI_StreamCreate(17, 0, 1)   
    BASS_ChannelPlay Stream, 0
    BASS_MIDI_StreamEvents Stream, BASS_MIDI_EVENTS_STRUCT Or BASS_MIDI_EVENTS_TIME, VarPtr(MidiEvents(0)), MidiEventsCount   ' MidiEvents() is array of BASS_MIDI_EVENT
Then I need stop playing the channel, but all sounding MIDI-notes must keep sounding, as occurs when we press pause in any MIDI-player – all the last notes keep sounding, but new notes arrival are froze.

Commands “Bass_ChannelPause Stream” or “BASS_ChannelPlay Stream, restart:=BASSTRUE” make instant absolute silence, but I want only to stop sending new MIDI-messages added by “BASS_MIDI_StreamEvents”,  like a human that stopped playing piano, but keeps all the last notes and pedal pressed. I must not to play and pause the ready sound buffer, but  make sound buffer on the fly, using ready MIDI messages. I think I must open stream another way ("push"? "dummy"? I didn't understand what is it) or so on.

The only way  that I see is to send fake messages by “BASS_MIDI_StreamEvents” in order to run sync function with exact time period specified in MidiEvents(), and then send real sound from this sync function by instant “BASS_MIDI_StreamEvent”. But it is double work for computer and, as I think, will eat resources.
Is there any way to direct stop playing but not to mute the last notes?
Ideally is to remove all the next messages from buffer (keeping old notes on) and add new messages to continue playing on the same pedal, saving sounding of all previously pressed notes that weren't released yet!


(I write VB6 but understand C++ sources too)
« Last Edit: 6 Jun '18 - 12:49 by Oleg »

Ian @ un4seen

  • Administrator
  • Posts: 20845
When using BASS_MIDI_StreamEvents to queue events, it is possible to clear the pending events by calling it with the BASS_MIDI_EVENTS_CANCEL flag. For example, like this:

Code: [Select]
BASS_MIDI_StreamEvents(handle, BASS_MIDI_EVENTS_CANCEL, NULL, 0);

You can use BASS_ChannelGetPosition (with BASS_POS_DECODE and perhaps BASS_POS_MIDI_TICK) to get the current position when doing that, so you know where to resume from.

Oleg

  • Posts: 2
I just tested BASS_MIDI_EVENTS_CANCEL...
Exactly what I need!!!! The Universe of thanks!