0

i am making a drawing app which allow users to draw freely on the canvas, there will be sound coming out on certain range of coordinates x,y. my goal is to allow users to record and playback the whole actions later on and watch it like a video. I am able to make the drawing strokes working though, but i have problems regarding the recording and playback part, especially recording of the internal audio. i have searched around for very long and i found this very similar to my concept

this is one of the great example that i have found which is done by ronnie http://ronnieswietek.com/piano/piano_example.swf the source: http://ronnieswietek.com/piano/piano_example.fla

is there any way for me to replace the piano keys as drawing strokes which generate sounds based on coordinates and record and playback the strokes and sounds just like the example?

I am stuck and confused trying to figure out a way to do it..

  • I'm telling you in advance so it won't come as a surprise later: when fast forwarding, slow forwarding (or rewinding) you will have to mute the sound. – oxygen Jan 30 '13 at 05:47

1 Answers1

0

If you can execute code to do your draw strokes, then all you need to do is timestamp the execution of those stroke commands. There are a number of ways you could approach this. I've written an example (just for you).

You can paste this into a new Flash document and run it.

/* First we'll create some variables */

var recording:Array = new Array(); // This is where we'll store all the instances of user action.
var playStart:Number = 0; // Playback will depend on whether this variable is greater than 0.
stage.addEventListener(Event.ENTER_FRAME, tic); // This will run once every frame update.

/* Next we'll create some helper functions */

function createButton(name:String, hue:uint):MovieClip {
    // We'll use this to make some fancy buttons.
    var box:MovieClip = new MovieClip();
    var shape:Sprite = new Sprite();
    shape.graphics.beginFill(hue);
    shape.graphics.drawRect(0, 0, 100, 25);
    box.addChild(shape);

    var txt:TextField = new TextField();
    txt.text = name;
    txt.x = 10;
    txt.y = 3;
    txt.mouseEnabled = false;
    box.addChild(txt);

    return box;
}

function drawCircle(X:Number, Y:Number, Hue:uint = 0x000000):void {
    // This creates circles on stage.
    var circle:Shape = new Shape();
    circle.graphics.beginFill(Hue);
    circle.graphics.drawCircle(0, 0, 10);
    circle.graphics.endFill();
    circle.x = X;
    circle.y = Y;
    addChild(circle);
}


/* Now lets create some buttons; Record, Stop, and Play. And rig'em up to some actions. */

var recordBtn:MovieClip = createButton("Record", 0x10ab00);
addChild(recordBtn);
recordBtn.addEventListener("mouseUp", startRecording);

var stopRecordBtn:MovieClip = createButton("Stop", 0xe90000);
stopRecordBtn.x = 101;
addChild(stopRecordBtn);
stopRecordBtn.addEventListener("mouseUp", stopRecording);

var playBtn:MovieClip = createButton("Play", 0x0069ab);
playBtn.x = 202;
addChild(playBtn);
playBtn.addEventListener("mouseUp", playRecording);


/* In the same order, we'll create those functions */

function startRecording(e:Event):void {
    // Here we'll store a timestampe of when the recording started.
    recording[0] = flash.utils.getTimer();
    // Register for mouseclicks on the stage; we need some kind of input to track.
    stage.addEventListener("mouseUp", recordAction);
}

function stopRecording(e:Event):void {
    // Conversely, we stop recording by not listening anymore.
    stage.removeEventListener("mouseUp", recordAction);
}

function playRecording(e:Event):void {
    // Just like recording, we keep track of when we started.
    playStart = flash.utils.getTimer();
}


function recordAction(e:Event):void {
    if (recording.length >= 1) {
        // First, we create the timestamp, and other relavent info.
        var tick:Object = {
            "time":flash.utils.getTimer(),
            "x":e["stageX"],
            "y":e["stageY"]
        }

        // And store it in our numerical index
        recording.push(tick);
        trace("Time: " + (tick.time - recording[0]) + " Coords: " + tick.x + "," + tick.y);

        // Then we do whatever action we were supposed to do (draw line, play sound, etc.).  Here, we'll draw a circle at the mouse coordinates.
        drawCircle(tick.x, tick.y);
    }
}

function tic(e:Event):void {
    if (playStart > 0) { // Assuming we've indexed a start time...
        if (recording.length > 1) { // and we actually have actions to playback.
            // We'll first normalize those bizzare numbers to a zero starting number.
            var nextAction:Number = recording[1].time - recording[0];
            var playHead:Number = flash.utils.getTimer() - playStart;
            if (playHead > nextAction) {
                // Now that we've matched the time, we execute the same action we did before.
                drawCircle(recording[1].x, recording[1].y, 0xFFFFFF);
                // ... and in this example, I'm removing that instance since we no longer need it.
                recording.splice(1, 1);
            }
        } else {
            // If the length of the recording reaches zero, we'll automatically stop playback too.
            playStart = 0;
        }
    }

}
Atriace
  • 2,572
  • 1
  • 14
  • 27
  • if the it is recording drawing strokes based on MOUSE_MOVE and also the sounds generated based on coordinates, which will generate lots of data, will this set of codes be able to handle it? basically my app will be very similar to the popular app: Draw Something, just that it can play sounds. – Si Han Auditore Jan 29 '13 at 13:08
  • This is an example of the basic steps you might take in writing your app. While a good starting point, the efficacy of this code to do what you want is wholely dependent on your ability to write efficient code. In all likelyhood, you don't need to store the recorded sound, but rather the actions that played back the sounds (think "saving music sheets" rather than a "tape-recording"). Again, if the mouse events are driving all of that, then you only need to store those mouse events. – Atriace Jan 29 '13 at 15:19