Recording internal audio with Flash/AS3 - actionscript-3

After searching the net high and low, I just cannot for the life of me figure this out. I'm definitely a newbie with all things Flash, but I'm teaching myself where I can. I've gotten a simple Flash piano working, and would like to add record & play back functions. This is where the problem comes in- I can find any multitude of answers for recording from the microphone and saving/playing it back with Flash, but the only things I can find relating to internal audio (or Flash-based pianos) at all are questions like this one with either really vague answers or just no answers at all.
I have some sort of idea that I should be creating an array that tracks the clicks? (It's a mouse-playable piano at the moment, but if it's better for me to make it keyboard-based, that's something I can do at least). After (before? during?) creating that array, how do I keep the rhythm/timing correct?
I'm just super lost and really need your expertise...

You're on the right track in storing the clicks in an array. As far as rhythm and timing, when the user wants to start "recording" you can start a timer, I'd every 200ms or so. You can use that timer to determine at what point in time the key was clicked for use when playing it back.
I don't know if something like a long press is something you'd need, but to do that, with the same timer, you can set a start time and end time (press-->release) and just subtract the end time from the start time and now you have the duration of how long the key was pressed
EDIT: here is a quick example of what I was referring to in my original post: http://ronnieswietek.com/piano/piano_example.swf
the source: http://ronnieswietek.com/piano/piano_example.fla

Related

Automatically Generated rhythm game Flash Action Script 3

Is it possible to create an automatically generated Rhythm game for Flash Action Script 3 ?
But not just randomly generated, generated from the notes of a song. Or is that something I have to do manually?
How would I go about doing either of these?
I am currently following this tutorial: http://www.flashgametuts.com/tutorials/as3/how-to-make-a-rhythm-game-in-as3-part-4/ so perhaps it can be made to fit around this? (Go to the final part and View Source to see the full thing)
Thanks!
Depending on what you mean by rhythm game, check out the computeSpectrum() function of the SoundMixer class: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundMixer.html#computeSpectrum()
There's an example of it working in the link, but basically what it does is take a snapshot of the current sound wave and puts normalised (-1 to 1) values in a ByteArray. What you do with those values is up to you - e.g. you might use them as a height field to generate terrain for example.
Repeat this every frame, and you get the gist
Welcome to SO!
First off, there is nothing already built in, to my knowledge. There may be something lurking around Google that someone else wrote, but you'd need to dig around for that (though I assume you already did.)
Generated from the notes of a song. Hmm, this will take some serious ingenuity and coding on your part. I'll point you in the right direction, but it is up to you to write the code. No one here will do it for you, but we'll happily help with specific problems in your code.
The crazy (yet potentially more fun) approach MAY BE to derive the data in a similar manner that an audio visualizer does...but I can't guarantee that will work. This would work best with MIDI-generated, single instrument songs. Here is a tutorial on visualizers.
A second approach may be to actually convert MIDI files directly. Again, I can't guarantee it will work, but it would theoretically be possible, seeing how MIDI files store data to begin with. Here's an answer on playing MIDI files, to get you started. Consider looking through their class.
However, the "easiest" approach would be to come up with some sort of system by which you store the note values for a song. You can manually enter the values in an array, or in a data file (such as XML) that you can load.
I put "easiest" in quotes because you'd have to account for a LOT of information - not just note values, but note duration, rhythm, and rests.
Anyway, those are just a few ideas to get you started. Good luck!

"Play" sounds into a .wav

I'm trying to make a program that can convert ORG files into WAV files directly. The ORG format is similar to MIDI, in the sense that it is a list of "instructions" about when and how to play specific instruments, and a program plays these instruments for it to create the song.
However, as I said, I want to generate a WAV directly, instead of just playing the ORG. So, in a sense, I want to "play" the sounds into a WAV. I do know the WAV format and have created some files from raw PCM samples, but this isn't as simple.
The sounds generated by the ORG come from a bunch of files containing WAV samples I have. They're mono, 8-bit samples should be played at 22050Hz. They're all under a second long, and the largest aren't more than 11KB. I would assume that to play them all after each other, I would simply put the samples into the WAV one after the other. It isn't that simple though, as the ORG can have up to 16 different instruments playing at once, and each note of each instrument also has a pan (i.e. a balance, allowing stereo sound). What's more, each ORG has its own tempo (i.e. milliseconds between each point a sound can be played), and some sounds may be longer than this tempo, which means that two sounds on the same instrument can overlap. For instance, a note plays on an instrument, 90 milliseconds later the same note plays on the same instrument, but the first not hasn't finished, hence the first note plays into the second.
I just thought to explain all of that to be sure the situation is clear. In any case, I'd basically like to know how I would go about converting or "playing" an ORG (or if you like, a MIDI (since they're essentially the same)) into a WAV. As I mentioned each note does have a pan/balance, so the WAV would also need to be stereo.
If it matters at all, I'll be doing this in ActionScript 3.0 in FlashDevelop. I don't need any code (as that would be asking someone to do the work for me), but I just want to know how I would go about doing this correctly. An algorithm or two may be handy as well.
First let me say AS3 is not the best language to do these kind of things. Super collider would be a better and easier choice.
But if you want to do it in AS3 here's a general approach. I haven't tested any of it, this is pure theory.
First, put all your sounds into an array, and then find a way of matching the notes from your midi file to a position in the array.
I don't know the format of midi in depth, but I know the smallest value is a tick, and the length of a tick depends on the BPM. Here's the formula to calculate a midi tick: Midi Ticks to Actual PlayBack Seconds !!! ( Midi Music)
Let's say your tick is 2ms in length. So now you have a base value. You can fill a Vector (like an Array but faster) with what happens at every tick. If nothing happens at a particular tick, then insert a null value.
Now the big problem is reading that Vector. It's a problem because the Timer class does not work at small values like 2ms. But what you can do is check the ellapsed time in ms since the app started using getTimer(). You can have some loop that will check the ellapsed time, and whenever you have 2ms more, you read the next index in the Vector. If there are notes on that index, you play the sounds. If not you wait for the next tick.
The problem with this, is that if a loop goes on for more than 15 seconds (I'm not sure of that value) Flash will think the program is not responding and will kill it. So you have to take care of that too, ending the loop and opening a new one before Flash kills your program.
Ok, so now you have sounds playing. You can record the sounds that flash is making (wavs, mp3, mic) with a library called Standing Wave 3.
https://github.com/maxl0rd/standingwave3
This is very theoretical... and I'm quite sure depending on the number of sounds you want to play you can freeze your program... but I hope it will help to get you going.

AS3 SampleDataEvent from microphone

I'm writing a recorder for website with flash using the flash.events.SampleDataEvent from the Microphone. But there is one strange thing:
At the beginning the SampleEvent occurs approximately every second. That's really slow. But after waiting a while in front of the browser and starting it again, it's very fast.
So 2 questions:
Is there a way to influence the time between the events
Why is this happening?
Thanks in advance
That is kind of strange. There's no way to tell the event when to dispatch. It just gets triggered when the microphone has sound data in the buffer. For some reason, it doesn't seem like your microphone is recording very much data at first. Try adjusting Microphone.gain and also Microphone.rate. Higher gain will amplify what you are recording to hopefully trigger the event faster and increasing the rate will give you more samples per event.

Starting with HTML5 Game Development - Very confused

I'd like to start developing a "simple" game with HTML5 and I'm quite confused by the many resources I found online. I have a solid background in development, but in completely different environments (ironically, I started programming because I wanted to become a game developer, and it's the only thing I've never done in 13 years...).
The confusion derives from the fact that, although I know JavaScript very well and I have some knowledge of HTML5, I can't figure out how to mix what I know with all this new stuff. For example, here's what I was thinking of:
The game would be an implementation of chess. I have some simple "ready made" AI algorithm that I can reuse for single player; the purpose here is to learn HTML5 game development, so this part is not very important at the moment.
I'd like build a website around the game. For this I'd use a "regular" CMS, as I know many of them already and it would be faster to put it up.
Then I'd have the game itself, which, in its "offline" version, has nothing to do with the website, as, as far as I understand, it would live in a page by itself. This is the first question: how to make the Game aware of User's session? The login would be handled by the CMS (it should be much easier this way, as User Managememt is already implemented).
As a further step, I'd like to move the AI to the server. This is the second question: how do I make the game send player's actions to the Server, and how do I get the answer back?
Later on, I'd like to bring a PVP element to the game, i.e. one-against-one multiplayer (like the good old chess). This is the third question: how to send information from a client to another, and keep the conversation going on. For this, people recommended me to have a look at Node.js, but it's one more element that I can't figure out how to "glue" to the rest.
Here's an example of a single action in a PVP session, which already gives me a headache: Player 1 sends his move to the Server (how does the game talk to Node.js?). I'd need to identify the Game Id (where and how should I store it?), and make sure the player hasn't manually modified it, so it won't interfere with someone else's game (how?).
I'm aware that the whole thing, as I wrote it, is very messy, but that's precisely how I feel at the moment. I can't figure out where to start, therefore any suggestion is extremely welcome.
Too many things and probably in the wrong order.
A lot of the issues don't seem to me to be particularly related to HTML5 in the first instance.
Start with the obvious thing - you want a single page (basically a javascript application) that plays chess, so build that. If you can't build that then the rest is substantially irrelevant, if you can build (and I don't doubt that you can) then the rest is about building on that capability.
So we get to your first question - well at the point at which you load the page you will have the session, its a web page, like any other web page, so that's how you get the session. If you're offline then you've persisted that from when you were online by whatever means - presumably local storage.
You want to move the AI to the server? Ok, so make sure that the front end user interaction talks to an "interface" to record the player moves and retrieve the AI moves. Given this separation you can replaces the AI on the client with an ajax (although I'd expect the x to be json!) call to the server with the same parameters.
This gets better, if you want to do player to player you're just talking about routing through the server from one user/player to another user/player - the front end code doesn't have to change, just what the server does at the far end of the ajax call.
But for all this, take a step back and solve the problems one at a time - if you do that you should arrive where you want to go without driving yourself nuts trying to worry about a bucket full of problems that seem scary that you can probably easily solve one at a time and I'd start by getting your game to run, all on its own, in the browser.
About question one: You could maybe give the user a signed cookie. E.g. create a cookie that contains his userid or so and the SHA2 hash of his userid plus a secret, long salt (e.g. 32 bytes salt or so).
About question two: For exchanging stuff and calling remote functions, I'd use the RPC library dnode.
About question three: Use the same thing for calling methods between clients.
Client code (just an example):
DNode.connect(function (remote) {
this.newPeer = function(peer) {
peer.sendChatMessage("Hello!");
};
});
You don't have to use game IDs if you use dnode - just hand functions to the browser that are bound to the game. If you need IDs for some reason, use a UUID module to create long, random ones - they're unguessable.

Synchronize Changes To A Textfield

I'm experimenting with P2P on Flash, and I've come across a little hurdle that I'd like to clarify before moving forward. The technology itself (Flash) doesn't matter for this problem, as I think this problem occurs in other languages.
I'm trying to create a document that can be edited "live" by multiple people. Just like Google Docs pretty much. But I'm wondering, how would you suggest synchronizing everyone's text? I mean, should I message everyone with all the text in the text field every time someone makes a change? That seems very inefficient.
I'm thinking there has to be a design pattern that I can learn and implement, but I'm not sure where to start.
Optimally, the application should send the connected clients only the changes that have occurred to the document, and have some sort of buffer or error correction that can be used for retrieving earlier changes that may have been missed. Is there any established design pattern that deals with this type of issue?
Thanks,
Sandro
I think your "Optimally" solution is actually the one you should go for.
each textfield has a model, the model has a history (a FILO storing last, let's say, 10 values).
every time you edit that textfield you push the whole text into the model and send the delta to other connected clients.
as other clients receive the data they just pick the last value from the model and merge it to the received data.
you can refine the mechanism by putting an idle timer in the middle: as a user types something in the textfield you flag that model as "toBeSentThroughTheNet" and you start a timer. as the timer "ticks" (TimerEvent.TIMER) you stop it, collect the flagged data and send it to other clients. just remember to reset the timer everytime the user is actually typing (a semplification coul be keydown = reset, keyup = start).
one more optimization could be send the data packed in a compressed bytearray, but this requires you write your own protocol and may be not so an easy and quick path :)
If the requirement is that everyone can edit the document at the same time and the changes should be propagated to everyone and no changes should be lost, then it is a non-trivial problem. There are few different approaches out there, but one that is quite robust is Operational Transformation. This is the same algorithm that Google Docs uses for collaborative editing.
Understanding and Applying Operational Transformation and the attendant hacker news discussion are probably other good places to start.
The Wave Protocol was released as open source so you can take a look on how it is implemented.
You could of course forgo the tricky synchronization and just allow people to take turns and only one person can edit the document at a time and this person just pushes the changes to the remainder of the group.