javascriptsoundjs

How do I toggle play/pause with SoundJS?


Im using SoundJS to build a psuedo MPC. I have the sound kit buttons programmed the way I want, but I cannot get the loops to work the way I want.

How could I master this problem. Warning, I'm a UI/UX designer at heart and still learning Javascript, so if you could give me a bit more detail when explaining, that would be great. Thanks!

Here's some of my code below, but to see it in action, check here: http://nowthatsgenius.com/clients/beatbox/

<body onload="init();">
    <section class="player-container">
        <article class="player-controls">
            <ul class="player-controls">
                <li class="player-controls-button" id="loop1" onclick="playSound(this)">Loop 1</li>
                <li class="player-controls-button" id="loop2" onclick="playSound(this)">Loop 2</li>
            </ul>
        </article>
    </section>
    <section class="mpc-container">
        <article class="mpc-title mpc-col">
            <span class="text">V1</span>
        </article>
        <article class="mpc-controls mpc-col">
            <ul class="mpc-controls-wrap">
                <li class="mpc-controls-row">
                    <ul>
                        <li class="mpc-controls-button" id="a1" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a2" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a3" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a4" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a5" onclick="playSound(this)"></li>
                    </ul>
                    <ul>
                        <li class="mpc-controls-button" id="a6" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a7" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a8" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a9" onclick="playSound(this)"></li>
                        <li class="mpc-controls-button" id="a10" onclick="playSound(this)"></li>
                    </ul>
                </li>
            </ul>
        </article>
    </section>

    <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
    <script src="http://code.createjs.com/soundjs-0.6.0.min.js"></script>
    <script>
        var preload;

        function init() {
            if (!createjs.Sound.initializeDefaultPlugins()) {
                document.getElementById("error").style.display = "block";
                document.getElementById("content").style.display = "none";
                return;
            }

            var assetsPath = "assets/";
        var sounds = [
                {id:"loop1", src:"loop1.mp3"},
                {id:"loop2", src:"loop2.mp3"},

            {id:"a1", src:"snare.wav"},
            {id:"a2", src:"kick1.wav"},
            {id:"a3", src:"clap1.wav"},
            {id:"a4", src:"closedhat.wav"},
            {id:"a5", src:"cymbal.wav"},
            {id:"a6", src:"kick2.wav"},
            {id:"a7", src:"clap2.wav"},
            {id:"a8", src:"openhat.wav"},
            {id:"a9", src:"voice1.wav"},
            {id:"a10", src:"voice2.wav"},
        ];

        $('.player-controls-button').attr("disabled",true);

        createjs.Sound.alternateExtensions = ["mp3"];   
        createjs.Sound.addEventListener("fileload", createjs.proxy(handleLoadComplete, this));
        createjs.Sound.registerSounds(sounds, assetsPath);
      }


        function playSound(target) {

            var instance = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);

            $(".player-controls-button").click(function(event) {
                if (instance.playState == createjs.Sound.PLAY_SUCCEEDED) {
                    instance.stop();
                } 
                else {
                    instance.play(target.id, createjs.Sound.INTERRUPT_NONE);
                }
            });

            console.log(instance.playState);
        }


    </script>

</body>

Solution

  • You can modify sounds after you've started playing them by assigning them to a variable. In this case, I've created variables loop1 and loop2.

    // Creating variables outside playSound() so they exist in the global scope.
    var loop1 = null;
    var loop2 = null;
    
    function playSound(target) {
        if(loop1){  // If loop1 exists, stop it.
            loop1.stop();
        }
        if(loop2){  // If loop2 exists, stop it.
            loop2.stop();
        }
    
    
        if(target.id == "loop1"){
            // Assign value to var loop1
            loop1 = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);
        }
        else if(target.id == "loop2"){
            // Assign value to var loop2
            loop2 = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);
        }
        else{
            // Otherwise, create generic sound
            var instance = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);
        }
    
        $(".player-controls-button").click(function(event) {
            if (instance.playState == createjs.Sound.PLAY_SUCCEEDED) {
                instance.stop();
            }else {
                instance.play(target.id, createjs.Sound.INTERRUPT_NONE);
            }
        });
    
        console.log(instance.playState);
    }
    

    I recommend you separate your playSound(target) function for sound effects, and create a new one named playLoop(target) for your music loops, just to make it easier to read. But that's up to you.

    Version 2

    var loop1 = null;
    var loop2 = null;
    function playLoop(target){
    
        // If loop1 exists, stop it and delete it
        if(loop1){
            loop1.stop();
            loop1 = null;
        }else if(target.id == "loop1"){
            loop1 = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);
        }
    
        // If loop2 exists, stop it and delete it
        if(loop2){
            loop2.stop();
            loop2 = null;
        }else if(target.id == "loop2"){
            loop2 = createjs.Sound.play(target.id, createjs.Sound.INTERRUPT_NONE);
        }
    }
    

    When you assign createjs.Sound.play() to a variable, the variable becomes an AbstractSoundInstance object. You can modify it in many cool ways, here's the documentation if you want to learn what more you can do with these variables.