Author Topic: ฺQuestion about Bassmidi when using flag BASS_MIDI_DECAYEND and BASS_SAMPLE_LOOP  (Read 5614 times)

Gamo

  • Posts: 97
It seems that BASS_MIDI_DECAYEND does not work with this flag when BASS_SAMPLE_LOOP is applied.

Does anyone know how to get it work?

I use bass 2.4.2.1, bassmidi 2.4.1

JM-DG

  • Posts: 112
What do you want to do exactly?? :)

Gamo

  • Posts: 97
Just want the sound end completely.

JM-DG

  • Posts: 112
Solution #1
« Reply #3 on: 4 Oct '08 - 15:45 »
Hi!!! :)

Correct me if I'm wrong but in short you want to be able to repeat(or not) a song when it reaches the end of the file.

I'll send you a solution covering both midis and steams files at this link:
http://www.turboupload.com/files/get/s0F2MK7-WF/repeat-exemple.zip

Tell me if I'm off track, I'll try to help you again.
___________
JM-DG

Ian @ un4seen

  • Administrator
  • Posts: 20389
It seems that BASS_MIDI_DECAYEND does not work with this flag when BASS_SAMPLE_LOOP is applied.

Yep. The BASS_MIDI_DECAYEND flag tells BASSMIDI to let the last sound decay before ending the stream, but if the BASS_SAMPLE_LOOP flag is in effect, then the stream will just keep looping, and there will be no end for it to let decay.

Gamo

  • Posts: 97

Yep. The BASS_MIDI_DECAYEND flag tells BASSMIDI to let the last sound decay before ending the stream, but if the BASS_SAMPLE_LOOP flag is in effect, then the stream will just keep looping, and there will be no end for it to let decay.

This means the last note of with BASS_SAMPLE_LOOP and without this flag does difference behavior. Without BASS_SAMPLE_LOOP the BASS_MIDI_DECAYEND flag play note until the sound is completed but with BASS_SAMPLE_LOOP flag it may not play completed last note.

Same thing if I continuous play the song I get same behavior when I use following this command to check before play next song.

if BASS_ChannelIsActive(chan) = BASS_ACTIVE_STOPPED then
    Call PlayNextSong
endif

What's the best way to play next song if I prefer that it will play until the song is completed?

JM-DG

  • Posts: 112
Answer #2
« Reply #6 on: 7 Oct '08 - 02:20 »
Have you downloaded my exemple??? :)
If so, then you only have to add your "Call to PlayNextSong" in the timer procedure.

(Because you make this check)

Code: [Select]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
// This will check if it is the end of the song!!!
if (BASS_ChannelGetPosition(chan,0)<BASS_ChannelGetLength(chan,0)-2) then exit;

  if btnRepeat.Tag = 1 then
    begin
    BASS_ChannelPlay(chan, True) // This will make the Repeat !!!
    end else
    PlayNextSong(); // Else this will play the next song!!!
end;
« Last Edit: 7 Oct '08 - 02:37 by JM-DG »

Ian @ un4seen

  • Administrator
  • Posts: 20389
This means the last note of with BASS_SAMPLE_LOOP and without this flag does difference behavior. Without BASS_SAMPLE_LOOP the BASS_MIDI_DECAYEND flag play note until the sound is completed but with BASS_SAMPLE_LOOP flag it may not play completed last note.

Yep, it was done like that in case the MIDI file is intended to be looped without a gap (decaying the last sounds is likely to introduce a gap). But if you want to have both decaying and looping, you can achieve that with a BASS_SYNC_END sync (instead of the BASS_SAMPLE_LOOP flag), something like this...

Code: [Select]
BASS_ChannelSetSync(midi, BASS_SYNC_END|BASS_SYNC_MIXTIME, 0, LoopSyncProc, 0); // set mix-time END sync

...

void CALLBACK LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
BASS_ChannelSetPosition(channel, 0, BASS_POS_BYTE); // loop
}

if BASS_ChannelIsActive(chan) = BASS_ACTIVE_STOPPED then
    Call PlayNextSong
endif

What's the best way to play next song if I prefer that it will play until the song is completed?

That should work fine.

Instead of polling BASS_ChannelIsActive, you could also set a BASS_SYNC_END sync to be notified of the end, something like this..

Code: [Select]
BASS_ChannelSetSync(midi, BASS_SYNC_END, 0, EndSyncProc, 0); // set END sync

...

void CALLBACK EndSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
if (!BASS_ChannelIsActive(channel)) // not still playing (looping)
PlayNextSong();
}

Code: [Select]
// This will check if it is the end of the song!!!
if (BASS_ChannelGetPosition(chan,0)<BASS_ChannelGetLength(chan,0)-2) then exit;

It's generally not a good idea to detect the end like that, as the BASS_ChannelGetLength value can be inexact with some file formats; in this case, it won't include any time taken to decay (due to the BASS_MIDI_DECAYEND flag). It's better to use BASS_ChannelIsActive and/or a BASS_SYNC_END sync :)

JM-DG

  • Posts: 112
Ok Thank you!!!
Finally it will help me too :)

Respect,
___________
JM-DG

Wayne McHugh

  • Posts: 30
I realise this is an ancient post, but it helped me realise what I was missing in order to get songs to decay properly at the end - which is, of course, BASS_MIDI_DECAYEND in the BASS_MIDI_StreamCreateFile call.  Ian, TESTMIDI doesn't decay the end of a song, which is why my player wasn't.  Is it worth adding that flag in TESTMIDI?  I imagine everyone would want it there.  Anyway, my reason for posting here was really just to to say how helpful all the years of chatter are in finding answers.  :)

Ian @ un4seen

  • Administrator
  • Posts: 20389
The BASS_MIDI_DECAYEND flag wouldn't actually have any effect in the MIDITEST example because it loops the MIDI file, and uses the BASS_MIDI_DECAYSEEK flag when doing so :)

Wayne McHugh

  • Posts: 30
My misunderstanding, Ian.  But brought on by MIDITEST not decaying the final sounds before looping back, though what you have written here suggests it should.

Ian @ un4seen

  • Administrator
  • Posts: 20389
The end notes should indeed decay when looping due to the BASS_MIDI_DECAYSEEK flag. If that's not happening, please upload a most noticeably affected MIDI file to try here...

   ftp.un4seen.com/incoming/

Wayne McHugh

  • Posts: 30
I have uploaded a clear example using FileZilla. It only appeared for a moment on your ftp server - I hope that is normal.

Ian @ un4seen

  • Administrator
  • Posts: 20389
Your file was received fine, thanks. The reason the sound stops when looping that particular file is that it starts with a GM reset sysex (F0 7E 7F 09 01 F7), which kills the notes that were playing at the end. I guess it could be nice to have a way to skip the reset message after looping. I'll try think of some way that that could be done; perhaps a flag that results in system messages (MIDI_EVENT_SYSTEM) releasing rather than killing the notes if the system mode (GM/GM2/GS/XG) is unchanged.