Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-channel audio support #31

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

alaa-eddine
Copy link

Hi,
buzz library is by far the best HTML5 audio library I used, but it lack an important feature for HTML5 gaming : multi-channel audio.

I'm suggesting an unobstructive solution that add those two lines to original code :
this.src = src;
this.options = options;

plus a separate file buzz-pool.js

if you accept my pull it's up to you to integrate the code to buzz core or to keep it separate :)

Regards.

@jaysalvat
Copy link
Owner

Really great, thanks for your contribution.

Why no to add the multi-channel directly in buzz.js ?

var mySound = new buzz.sound( "music", {
    formats: [ "ogg", "mp3" ],
    channels: 4
});

@alaa-eddine
Copy link
Author

well this was my initial approach, but this will make some function to have different behaviours depending on the existance of multiple pools or not.

for example, if I call mySound.pause() , should it stop all souds or only the latest player one ?

I'm not sure of what's the better approach this is why I tried to make it as unobstructive as possible.

@alaa-eddine
Copy link
Author

Here is another version using the approach you suggested
I let you choose the one you find better :)

in this last version I added a control to check if channel parameter is greater than 2, if yes I create a pool and use it, if no I just use the default sound object.

this adds a control to sound object functions.

for example

        this.load = function() {

            if ( !supported) {
              return this;
            }

            this.sound.load();
            return this;
        };

becomes

        this.load = function() {

            if ( !supported || poolfn( 'load' )) {
              return this;
            }

            this.sound.load();
            return this;
        };

@SoftCreatR
Copy link

I can confirm, that this solution is working. It solved my problem very quickly. Ty :)

@jaysalvat
Copy link
Owner

Great ! And thanks to @alaa-eddine for his valuable patch.
I will deeply test it as soon as possible and surely merge it.

@jaysalvat
Copy link
Owner

Hi @alaa-eddine, thanks again for your contribution.

I've just tested it, multi-channels is great improvement, however, this is not fully functional.
There are some bugs when you work with events.

sound.bind( 'timeupdate', function() {
    console.log( sound.getTime() ) );
});

Returns

Uncaught TypeError: Cannot call method 'addEventListener' of undefined 

Could you please check ?
Thanks.

@alaa-eddine
Copy link
Author

I was passing an undefined parameter instead of "types" for methods bind(), unbind() and trigger().

fixed :)

@jaysalvat
Copy link
Owner

Thanks a lot, it works.

I have to run some tests before releasing it.

@jaysalvat
Copy link
Owner

It doesn't work properly yet.

When I pause a multi-channel sound and play it again. It stops after 1 sec.

Also, mySound.getTime() return empty after a second channel is played.

Any idea ?

Sorry I haven't time to deeply work on buzz currently.

@alaa-eddine
Copy link
Author

I cannot reproduce the bug with pause/replay, can you past a code sample please ?

also I don't understand the getTime() problem ? what value should be returned while playing a multi-channel sound ?

channels are handeled the same way as groups, my poolfn() method is almost a copy of fn() method used for groups, I only added a check to make sure we are handling a pool :) .

@alaa-eddine
Copy link
Author

here is a code example I tested it works just fine :)

var mySound = new buzz.sound( "sound", {
    formats: [ "mp3" ],
    channels: 4
});
mySound.play(); // start playing

setTimeout(function() {
    mySound.pause(); //pause sound after one second
    setTimeout(function() {
        mySound.play(); //resume playing after two seconds
    }, 2000);
}, 1000);

@jaysalvat
Copy link
Owner

Here is my test page.
https://gist.github.com/4250286

Returns Uncaught TypeError: Cannot read property 'currentTime' of undefined with channels. Nothing without channels.

Replace mySound.mp3 by a song track and play with all the demo features (on chrome) and you will see, there are lot of strange behaviors with multi-channels :)

Some function don't work anymore.
For example. Play + Pause + Play (sound is stopped after 2 sec)

For example. Play + Play (Timer is getting empty)

Your help is welcome. I have no time to dig in the code currently. Sorry.

@alaa-eddine
Copy link
Author

really strange ! I used your code and tested different functions with your scenarios (play + pause + play and play + play) and everything is working good :/ I tested with 3 different tracks.... I can't reproduce

now about currentTime first issue (undefined while using channels) I'll push a fix now :)

for timer value (when you click play then play), it's a "normal" behaviour, because we are using the same dummy object to handle all channels so the the dummy object will point to the latest played channel this is why the timer seems to be reinitialised.

I propose a modification of getTime function :
if called empty it'll return latest played channel time
if called with a parameter, and the parameter is a valid channel number, it'll return then specified channel current time : example getTime(0) will return the timer of sound played in channel 0
if called with a parameter but the parameter is not a valid channel number, or the currently played sound does not support channels, it'll just fallback to default behaviour and return current time.

…calling getTime

modified getTime to support getting time of multi-channel sounds : getTime can take a parameter (the channel index) in this case it'll return the channel current time, otherwise it'll return the latest played channel current time. in case of non multi-channel sound, getTime keep the default behaviour.
@arnuschky
Copy link

I am very interested in the multi-channel capability provided by this patch. Does it work/can I use it? Is someone using it successfully? Have the latest issues been resolved?

@SoftCreatR
Copy link

#31 (comment)

@alaa-eddine
Copy link
Author

@arnuschky I fixed all reported issues in the last commit and I'm using the forked version in my HTML5 games, it works just fine :)

maybe you can also try it and tell us if you encounter some problems. the forked version will not break your existing code btw

@arnuschky
Copy link

Thanks for the fast replies! I hand-merged your patch with the latest buzz version; everything works perfectly! Thanks for this.

I added a new pull request in case someone wants to use the updated work: #49

Please note that all the credit for the multi-channel patch goes to https://github.com/alaa-eddine

@jaysalvat
Copy link
Owner

Thanks a lot. I will try to merge it fast.

Last time I've tried, my app was broken. I think multi-channel is a good feature but we need to do more tests to bullet-proof the all thing.

@alaa-eddine
Copy link
Author

@jaysalvat I fixed remained issues in my last commit but since I didn't received more comment from you I thought it was ok :)
anyway if there is a need to fix something let me know.

please note that multi-chanel will not work on most mobile browsers, this is not due to buzzjs code but to the mobiles HTML5 current implementations.

@SyntaxStacks
Copy link

Has there been any progress on multi-channel support in buzz?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants