Maptool: Add playClip function to play clips

Created on 18 Oct 2019  Â·  25Comments  Â·  Source: RPTools/maptool

Is your feature request related to a problem? Please describe.
playStream is ill-suited to playing small clips that must be played quickly (see here for an example)

Describe the solution you'd like
A "playClip" function to play clips instead of streams.

feature macro changes tested

Most helpful comment

If there’s doing to be a “music” subdir then perhaps the scheme should be “maptool://“ instead? It could refer to the top level ~/.maptool directory...?

All 25 comments

PR #811 implements this.

Can't say I'm too keen on having 3 additional macro functions that are just for playing short sounds where short is defined as ???.

Couldn't the playStream function first figure out if the requested audio file is short or long and then take the appropriate action? Basically hide the difference to the users and handle it all underneath.

Maybe we can consolidate stopStream & stopClip, and getClipProperty & getClipProperty?

Certainly that would be an improvement.

I haven't looked yet at what is being done differently but couldn't playStream() look at the audio source before it starts playing and make the call to do it as a "stream" or a "clip"?

If there is a better way to execute smaller audio files it should just be put in to the playStream, imo. Also, I think the 1 second interval could be limiting when slicing out audio from a larger stream, like for an mp3 with a bunch of sound bytes. It would be nice if the value could be a float.

Keep in mind features of playStream are not available for playClip. For example it's not possible to have fadeout, start time / end time, etc.

@aliasmask, I'm not sure what you mean with "1 second interval".

The start and stop options of playStream are in seconds. You know, I didn't try putting in a decimal, so it probably works with values like 1.5 for a start value based on the props output showing decimal values.

@aliasmask You can use floating point. Internally all the times are in milliseconds.

You can't currently use playStream() to play multiple segments from a single source. I don't know if the playClip() would have worked differently.

So I'm thinking we should change the audio functions to:

  • playStream
  • playClip
  • stopSound
  • getSoundProperties
  • editStream

It's certainly better to change macro names now rather than later when more users have macros that will break with the changes.

This still has the issue of what is the criteria that a user will apply to decide whether to use playClip or playStream? _Short_ isn't sufficient. Is it that playStream should only be used for ambient, soundtrack like audio that loops continuously? Any usage involving start/stop points with repeats should use playClip?

Referring to @aliasmask 's comment above, will playClip be usable to to play multiple segments out of a single source simultaneously? A lot of canned sound FX come as longer audio files holding multiple variations of the same sound or different sounds.

This goes back to the original discussion for #667, where I suggested that a defineStream would make it easier on users. For _clips_, where a user wants to play multiple segments out of one source, Perhaps instead of a _stream_, it would be defineAudioSource and would allow the user to do something like:

[h: uri = "c:/sfx/some_long_audio_file.mp3"]
[h: preload = 1]
[h: defineAudioSource("heartbeat", URI, preload, 0.5, 2.0, 2.25)]
[h: defineAudioSource("scream", URI, preload, 1.0, 12.0, 13.0)]
[h: defineAudioSource("evil laugh", URI, preload, 0.7, 71.0, 74.5)]

Those could then be called with playClip like:

[h: playClip("heartbeat", 100)] <!-- 100 counts -->
[h: playClip("scream"] <!-- plays while heartbeat is looping -->
[h: playClip("evil laugh")] <!-- plays while heartbeat is looping -->

This still has the issue of what is the criteria that a user will apply to decide whether to use playClip or playStream? _Short_ isn't sufficient. Is it that playStream should only be used for ambient, soundtrack like audio that loops continuously? Any usage involving start/stop points with repeats should use playClip?

I'm afraid javaFX doesn't give us much guidance either. There is this entry for AudioClip and that's pretty much it.

I see that the Audio Clips do allow for multiple playbacks simultaneously so that answers that question but it also means that long, hi-fidelity SFX files will take up a lot of memory.

Going to need sufficient warnings and cautions in the various wiki pages so that folks are aware of the limitations.

For defineAudioSource the last two parameters can only be used if using a stream. So maybe the user can select the type (stream or clip) at this stage?

Yeah. When I suggested that I hadn't looked at the JavaDocs on clips. I find it amazing that they would have limited clips like that.

So that pretty much forces the decision on the user. At this point, unless you've already made progress on defineAudioSource and associated changes, we can just go with your suggestion above.

  • playStream
  • playClip
  • stopSound
  • getSoundProperties
  • editStream

New commit implements the requested changes and add the function defineAudioSource.

What we could use is someway to have local files on all the clients be referenced in a common way like audio:/music/musicFile.mp3. This would then look in the maptool directory under music for that file.

If there’s doing to be a “music” subdir then perhaps the scheme should be “maptool://“ instead? It could refer to the top level ~/.maptool directory...?

Wiki pages added/modified:

  • defineAudioSource - new page, only a skeleton
  • getSoundProperties - old getStreamProperties moved and basic updates
  • playClip - new page, needs more work
  • stopSound - old stopStream moved and basic updates. more needed.

Existing pages needing updates:

  • playStream - needs updating
  • editStream - needs updating

Tested:

  • playClip
  • stopSound
  • getSoundProperties
  • defineAudioSource

Working as described.

getSoundProperties - should include the nickname(s), if any, for each audio clip or stream.

Alternatively defineAudioSource could return an array of nickname->URI mappings. [{"nick":"blahblah","uri":"someURI"}...] if called with/without parameters.

defineAudioSource - could use a parameter to just go ahead and preload the clip/stream.

defineAudioSource - could use a parameter to just go ahead and preload the clip/stream.

Maybe it could be a third parameter preload that can be either stream, clip, or none, to either preload as stream, preload as clip or not preload.

That would work.

PR #826 implements this.

For example, you can use

[defineAudioSource("no_sorrow", "http://erinmcnamee.com.hostbaby.com/files/07_No_Sorrow__Banish_Misfortune.mp3", "stream", cycleCount, volume, start, stop)]

The stream will be preloaded. In addition, in you use playStream("no_sorrow"), the cycleCount/volume/start/stop will be those used in defineAudioSource.

So, does this mean I can create multiple definitions of the same source with different parameters and play them simultaneously?

Not currently. There would have to be a MediaPlayerAdapter per pre-configured stream and the nickname would have to be the primary "key" used to access streams/clips. Note that only streams can have a start/stop. Audio clips only have volume and cycle count.

Updates to defineStream tested.
Nicknames now show in result from getSoundProperties.

Closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Phergus picture Phergus  Â·  9Comments

Merudo picture Merudo  Â·  7Comments

cwisniew picture cwisniew  Â·  6Comments

mrkwnzl picture mrkwnzl  Â·  9Comments

Merudo picture Merudo  Â·  4Comments