Is there a reliable way to tell if a PCM sound is currently playing?

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
Post Reply
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Is there a reliable way to tell if a PCM sound is currently playing?

Post by Artcfox »

In some cases I would like a TriggerNote() call with a PCM sound to interrupt another PCM sound that is currently playing, but in some cases I need the currently playing sound to continue and the one that would normally interrupt to be silent.

Is there a reliable way to check to see if a PCM sound is currently playing?

This is what I have so far in my main run loop in order to figure out the looping byte for each PCM sound:

Code: Select all

#define LO8(x) ((uint8_t)((x) & 0xFF))
#define HI8(x) ((uint8_t)(((x) >> 8) & 0xFF))
    UZEMH = HI8((uint16_t)mixer.channels.type.pcm.position);
    UZEMH = LO8((uint16_t)mixer.channels.type.pcm.position);
    UZEMC = '\n';
It uses the whisper console ports to output the current position of the PCM sound. Since all of my PCM patches loop on their last byte, I can make a note of what the loop byte of each sound is by playing them and looking at the console.

Then when I want to play a sound without interrupting another sound, I can first check to see if the PCM sound position is on one of my known looping bytes before starting a new sound:

Code: Select all

void TriggerNoteNoInterrupt(unsigned char channel,unsigned char patch,unsigned char note,unsigned char volume)
{
  if ((uint16_t)mixer.channels.type.pcm.position == 0x3737 ||
      (uint16_t)mixer.channels.type.pcm.position == 0x3c51 ||
      (uint16_t)mixer.channels.type.pcm.position == 0x3a50)
    TriggerNote(channel, patch, note, volume);
}
but there is a small chance that I could read the mixer position exactly when the current position of a longer running sound happens to match the end byte of one of my known sounds, and then it would interrupt when it shouldn't. Also, there is a chance of me reading that 16-bit integer in the middle of it updating because of an interrupt.

Is there a more reliable way of detecting when a PCM sound has finished playing?
User avatar
Jubatian
Posts: 1560
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Is there a reliable way to tell if a PCM sound is currently playing?

Post by Jubatian »

The positions you are checking against are actually C pointers, at low level, absolute addresses.

Unless you used some wizardry to overlap different samples, the end of sample pointer is unique, so checking it that way is fine.

However to keep it nice, you shouldn't compare to absolute addresses written as literals. If you have pointers to the samples or arrays holding the samples (you should probably have), then specify the address as &sampleptr[samplelen - 1U], assuming you have a loop length of 1 (which is the only case this would work anyway).

I don't think there is any better way since in the kernel I don't see any state, the low level mixer doesn't need such state, it just keeps running infinitely. That the PCM appears to be not playing is a result of it looping over silence (so it doesn't "know" that it is "stopped" or that the sample ended, it just keeps playing silence).
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Is there a reliable way to tell if a PCM sound is currently playing?

Post by Artcfox »

Good call with using the array itself in case the locations change.

I think this method might be all together too restrictive, as I have been contemplating adding a PCM sound that actually loops, in which case this is useless.

CunningFellow had another suggestion (again as long as I don't have looping sounds) to wrap the TriggerNote function with my own that uses the frame counter in my main loop to know when the most recent sound that has played will stop (since each sound would be of a known length), and gate the playing of new sounds based on whether the previous has finished via the main loop's frame counter.
Post Reply