Skip to main content

News

Topic: neoSphere 5.9.2 (Read 523253 times) previous topic - next topic

0 Members and 20 Guests are viewing this topic.
  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1575
I think I see the problem: You're looking at Galileo as a direct alternative to the classic primitives when that's not what it is at all.

Here's the thing, the Sphere v2 API is deliberately designed to be low-level.  So essentially what Galileo does is to expose how things already work internally to give you more control when you need it.  If you don't need that kind of control, the normal primitives are still just as serviceable as ever (so don't worry here, the "prim" module is NOT a second-class citizen, but just at a higher level of abstraction).  If that's not flexible enough--or performs poorly--*then* you have the option to step down a level and use Galileo to communicate directly with the engine on its own terms.

Let me put it this way: The entirety of the Sphere v1 API could have been built on top of Sphere v2.  The other way around, not so much.  You have strictly more options than before, not less. :D
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1576
I guess the best way I can illustrate the point above is this: When you blit() an image for example, the engine literally does this every time:
https://github.com/fatcerberus/minisphere/blob/master/assets/system/modules/prim.js#L23-L38

What Sphere v2 gives you the option is to do most of those steps in advance.  It's up to you to decide when it's appropriate to do so, just don't make the mistake of thinking calling a bunch of blit() calls every frame is going to be magically faster than creating all those textured quads manually on the fly.  It won't be--because that's exactly what the engine is going to do on your behalf.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.5.11
Reply #1577

What Sphere v2 gives you the option is to do most of those steps in advance.  It's up to you to decide when it's appropriate to do so, just don't make the mistake of thinking calling a bunch of blit() calls every frame is going to be magically faster than creating all those textured quads manually on the fly.  It won't be--because that's exactly what the engine is going to do on your behalf.
I guess I'd think that having those low level steps done in the compiled engine rather than with extra calls from a script may be slightly faster?

I was specifically looking at this from the point of view of trying to see how reworking my graphics handling to use Galileo functionality could optimise/improve it - and couldn't see that - I see what you mean about lower level control though.

PS: I've got my setup running in miniSphere now thanks to using template spritesets instead of CreateSpriteset and writing my own spriteset saving function: http://forums.spheredev.org/index.php/topic,1440.msg8805.html
  • Last Edit: May 20, 2017, 05:53:50 pm by Rhuan

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1578

I guess I'd think that having those low level steps done in the compiled engine rather than with extra calls from a script may be slightly faster?


Maybe, but probably not enough to matter in most cases.  In practice you only need to draw 60 frames per second; even with an interpreted JS engine like Duktape the extra overhead of bytecode execution isn't a huge issue.  As long as you can get all your rendering done in under 16.66ms (this is an eternity to the CPU), you're good.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.5.11
Reply #1579
Got another question for you on unsupported functions...

LoadSoundEffect - you said here http://forums.spheredev.org/index.php/topic,1434.0.html that it was 1.6 only; however it's actually in 1.5, I just tested it using 1.5 from the downloads drive.

It does largely overlap with LoadSound with one key difference the ability to play the effect multiple times overlapping each other, 1.5 actually had two ways of letting you do this easily either with LoadSoundEffect or with sound_object.clone().play() - neither of which you support.

I also tried to simulate this by creating new Mixers with your 2.0 api but I couldn't get any sound out at all either using just var sound = new Sound("sounds/file.ogg"); then sound.play(); or creating a Mixer and specifying it as a parameter, Sphere didn't crash but I didn't hear anything (and yes my volume was on, replacing new Sound with LoadSound meant I'd hear at least the first time it was meant to play).

Assuming audalis can be made to output somehting I'm happy to find a 2.0 way of doing this... (Though the api doesn't give me one thing I'd want to have - a way to either a) check if Mixer is producing sound or b) clone a sound object; either of these methods would allow me to do sound effects the way I want by either doing:

Code: [Select]
if(is_making_sound(mixers[mixers.length-1]))
{
  mixers.push(newMixer(blah,bla));
}

sound.play(mixers[mixers.length-1]);


OR

Code: [Select]
sound.clone().play()


(I note that at the moment as the v2 functions produce no output neither would work for me, but assuming they did produce output then it would just be down to having one of the above two features...)

(Alternatively LoadSoundEffect with it's SE_MULTIPLE parameter would do the job).

Or.... I guess you can just use LoadSound every time you want to play a sound effect to avoid the issue.
  • Last Edit: May 21, 2017, 06:53:23 pm by Rhuan

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.5.11
Reply #1580
As an alternative answer to the above problem I tried making a sound effect object with a queue so only the number of instances needed are loaded:

Code: [Select]
function SoundEffect(filename)
{
  this.queue = [LoadSound(filename)];
  this.name = filename;
}

SoundEffect.prototype.play = function()
{
  if(this.queue[this.queue.length-1].isPlaying()==false)
  {
    this.queue.unshift(this.queue.pop());
  //  this.queue[0].stop();
  }
  else
  {
    this.queue.unshift(LoadSound(this.name));
  }
  this.queue[0].play();
}


The version there works on Sphere 1.5, to make it work on miniSphere required the the line I've commented out above - it seems that on miniSphere .play() does not work on a sound object twice without .stop() in between even if .isPlaying() is returning false.
  • Last Edit: May 21, 2017, 07:55:03 pm by Rhuan

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1581
Hm, you're right, LoadSoundEffect() is listed in the API documentation included with Sphere 1.5.  I guess I just didn't implement it because I never found a v1 game that used it.  Good to know, I'll add it to my to-do list.

As for Audialis: Mixers not having an "isPlaying" function is by design.  The mixer is never "not producing sound" - in effect, it's like a pipeline.  It's just that sometimes it's "producing" silence (when you haven't fed it any sounds to play lately).  So there's no way to determine whether it's currently active or not because it's always active.

As for why you're not getting any sound, sound.play() (without any parameters) doesn't do what you think it does (admittedly, the wording here is somewhat ambiguous, I'll see if I can improve it):
Code: [Select]

Sound#play([mixer]);

    Begins or resumes sound playback.  When called with no `mixer` argument,
    Sound#play() will resume playback for a paused sound.  Otherwise, the sound
    is started from the beginning on the specified mixer.


If you don't provide a mixer, it's just a command to "unpause" - and if you've never played it before, the engine doesn't know what mixer to play it on.  You must explicitly specify a mixer.  Note that a default CD-quality mixer is provided for your convenience, so you don't always have to create one manually:
Code: (javascript) [Select]

var sound = new Sound('sounds/test.wav');
sound.play(Mixer.Default);
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.5.11
Reply #1582
Hmm - using Mixer.default works, but when I tried creating a Mixer it didn't work it just gave no output.

Any thoughts on the other point about v1 (requiring the .stop() command)

Also is there a way to have the same sound playing multiple times with v2 without something like the sound queue I showed above?

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1583

Hmm - using Mixer.default works, but when I tried creating a Mixer it didn't work it just gave no output.


Not surprising - Sphere v1 Sound#play() does exactly that.  Not sure why custom mixers don't work, something to figure out later I guess.

Quote

Any thoughts on the other point about v1 (requiring the .stop() command)


This is kind of odd, but I know there are bugs (seemingly related to Allegro's handling of streams) where the same sound fired off in rapid succession won't play every time.  .stop() forcibly drains the stream, so that's why it "fixes" the problem--but you might find it introduces little mini-stutters if you do that too much.  I've been trying to look into this bug for the past couple months, but I still have no leads as to what causes it or how to fix it. :(

Quote

Also is there a way to have the same sound playing multiple times with v2 without something like the sound queue I showed above?


Not currently, but I'm glad you brought this up - it reminds me that I wanted to introduce a "Sample" API that would serve the same purpose as Sphere v1 SoundEffect.  It's actually not good to use the Sound class for sound effects, because the sound is always streamed from disk.  That introduces undesirable latency that would be avoided if there were a way to load sounds into memory.  So yeah, there's no native way to do this now, but there should be soon. :)
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1584
@Rhuan: I'm working now on implementing both the Sphere v1 SoundEffect API as well as an enhanced Sphere v2 version that allows using Mixers.  Now that I know Sphere 1.5 supports SoundEffects, I pretty much have no choice but to implement it.  I'm sure you're not the only one that's used it in the past :)

As for why creating a mixer didn't work for you, are you sure you got the frequency right?  The frequency argument is in Hz (e.g. 44100), NOT kHz (e.g. 44), so I'm wondering if that's what the issue was.  The default mixer, for example is:
Code: (javascript) [Select]

// 44.1kHz, 16-bit, stereo, i.e. CD quality
Mixer.Default = new Mixer(44100, 16, 2);


Now that I look at the documentation again, it seems that I didn't specify frequency was in Hz.  Shame on me!
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Rhuan
  • [*][*][*][*]
Re: miniSphere 4.5.11
Reply #1585
I was using 44.1 as my input rather than 44100 so that's probably it, will test later.

A sound effect interface with Mixers is something I'm looking forward to seeing - would like to be able to have an in game volume control menu with sound effects and music separate - which I assume this will enable.

One other query at the same time:

Sphere v1 var sound = LoadSound("blah.ogg");

Sphere v2 var sound = new Sound("sounds/blah.ogg")

Why does v2 not default to the sounds folder?

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1586

One other query at the same time:

Sphere v1 var sound = LoadSound("blah.ogg");

Sphere v2 var sound = new Sound("sounds/blah.ogg")

Why does v2 not default to the sounds folder?


That's by design and is part of the SphereFS standard:
https://github.com/fatcerberus/minisphere/blob/master/docs/sphere2-api.txt#L89-L91

In short, paths are now standardized so that any given filename always refers to the same file regardless of which function you pass it to (except for v1 functions which maintain the backward-compatible behavior).  It's part of my initiative of making Sphere v2 more low-level and generalized, I didn't want to enforce a specific folder layout.

Quote

would like to be able to have an in game volume control menu with sound effects and music separate - which I assume this will enable.


Yep - that's the exact use case that mixers were designed for.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1587
I'm doing some prototyping for the new Sample API, it's not ready for primetime yet (memory leaks galore!) but so far I can do this:

Code: (javascript) [Select]

let sample = new Sample('sounds/munch.wav');
while (Sphere.run()) {
key = Keyboard.Default.getKey();
if (key == Key.Space)
sample.play(Mixer.Default);
}


new Sample(...) loads the sound into memory, avoiding the overhead and latency of streaming.  And each sample.play() plays a new instance of the sound.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: miniSphere 4.5.11
Reply #1588
Does this address the issue I brought up about polyphony?

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: miniSphere 4.5.11
Reply #1589
If by polyphony you mean playing the same sound multiple times simultaneously, then yes.  This feature is honestly long overdue and I don't know why I didn't implement it before.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub