I've been a little dismayed when I found out that some of the HTML5 Audio properties (duration, currentTime, some control CSS properties) don't work as they do in other browsers. Part of that distress was that I made an assumption. Not a good idea. I had been hearing for a long time about the need for audio sprites because iPhone (and others) couldn't play two sounds at once. Remy Sharp's article made a big impression on a lot of people (http://remysharp.com/2010/12/23/audio-sprites/) and many people decided that audio for HTML5 wasn't going to work. And I notice that a lot of the games I'm playing don't have any audio.
But you need currentTime to work with audio sprites because you need to load one file and then run your audio from whatever position you want to start the playing from. Sounds like that doesn't work. But you don't need it! Then I realized I hadn't tested it, so I wrote a simple test and guess what?
Two audio files can dance with each other!
So now your jump sounds can take place without cutting off your music and your collision sounds can ignore the capture of coins. Dance!
My test program sets up two audio players and lets you listen to both songs, and start and stop each whenever you want. The songs repeat, and you can play with this all day, enjoying the combination of two different songs. I remember doing some singing like this, and I think it was a song called Frère Jacques, where some people would start singing and others would start singing a few measures later. I wonder if this song has been sung in other languages?
Anyway, here's what the program looks like in Firefox OS on my ZTE Open.
The top set of controls are playing oggsong.ogg and the bottom set of controls are playing a different song, oggsong_2.ogg. Start and stop each one by clicking on the | | symbol in each control. So these controls are useful for testing, even though you can't do much more than position them so they don't overlap.
And here's the code, very similar to the code in my first post on Audio Programming (http://firefoxosgaming.blogspot.com/2013/12/html5-audio-game-programming_10.html).
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>
Audio x 2
</title>
<script>
// Global variables
var myAudio;
var myAudio2;
// Load the page.
window.addEventListener("load",
runFirst, false);
// Runs when the page is loaded.
function runFirst() {
console.log("page loaded");
// Create two audio objects.
// We like OGG.
myAudio = new Audio("oggsong.ogg");
myAudio2 = new Audio("oggsong_2.ogg");
// Need this to see the controls.
document.getElementById("myBody").
appendChild(myAudio);
document.getElementById("myBody").
appendChild(myAudio2);
// Loop both songs.
myAudio.loop = true;
myAudio2.loop = true;
// Make both controls visible.
myAudio.controls = true;
myAudio2.controls = true;
// Position 1st audio control.
myAudio.id = "player1";
player1.style.position = "absolute";
player1.style.top = "70px";
player1.style.left = "10px";
// Position 2nd audio control.
myAudio2.id = "player2";
player2.style.position = "absolute";
player2.style.top = "200px";
player2.style.left = "10px";
// Listen for fully loaded audios.
myAudio.addEventListener("canplaythrough",
processMyAudio, false);
myAudio2.addEventListener("canplaythrough",
processMyAudio2, false);
}
// The first audio is ready to play.
function processMyAudio() {
console.log("audio one loaded");
// Event no longer needed.
myAudio.removeEventListener("canplaythrough",
processMyAudio, false);
// Play the first audio.
myAudio.play();
}
// The second audio is ready to play.
function processMyAudio2() {
console.log("audio two loaded");
// Event no longer needed.
myAudio2.removeEventListener("canplaythrough",
processMyAudio2, false);
// Play the second audio.
myAudio2.play();
}
</script>
</head>
<body id="myBody">
<p>Audio Controls</p>
</body>
</html>
The trick here is very, very simple. For every audio track you want to create, create a new Audio object, give them different names, and process them separately.
For example:
myAudio = new Audio("oggsong.ogg");
myAudio2 = new Audio("oggsong_2.ogg");
This makes two Audio objects, each with a different name and each with a different song file (but both of them are OGG, yay OGG).
Add them both to the page, make them both loop and have controls. I then positioned each control so they don't fit on the screen.
// Position 1st audio control.
myAudio.id = "player1";
player1.style.position = "absolute";
player1.style.top = "70px";
player1.style.left = "10px";
// Position 2nd audio control.
myAudio2.id = "player2";
player2.style.position = "absolute";
player2.style.top = "200px";
player2.style.left = "10px";
I'm still working out what happens. I think the controls are centered on the phone page and maybe that's a bug someone should file, or maybe they want it that way? At least the top, left styles (absolute) let me have them not overlap.
Next I set up event listeners to make sure that each audio loads.
// Listen for fully loaded audios.
myAudio.addEventListener("canplaythrough",
processMyAudio, false);
myAudio2.addEventListener("canplaythrough",
processMyAudio2, false);
Then, finally, I have a separate function that is called when the audio is ready to play (canplaythrough). Here's the function for the first audio and the second is similar, except for the change in object names.
// The first audio is ready to play.
function processMyAudio() {
console.log("audio one loaded");
// Event no longer needed.
myAudio.removeEventListener("canplaythrough",
processMyAudio, false);
// Play the first audio.
myAudio.play();
}
And that's it! Start and stop the two tracks and see that they can both play at the same time. So who needs Remy Sharp?
Mangling Mozart
In case you want to listen to the two actual songs, you can download them for free (and you don't need to register there either, just click the Download button). Here are the links.
https://soundcloud.com/thulfram/oggsong
https://soundcloud.com/thulfram/oggsong_2
SoundCloud is a cool service for people who want to share their music and it is very easy to use. Put the songs in the same root folder as your index.html file and they will magically be loaded into the simulator and your phone.
The two songs are both about 9 seconds long. The two songs are mangled versions of a Mozart piece called Palindrome (which means running back and forth). I mangled them by putting the tune into FL Studio (http://www.image-line.com/documents/flstudio.html), loading in a synthesizer (H.G. Fortune's Swamp XT at http://www.hgf-synthesizer.com/), and then using FL Studio's Riff Machine to mangle the original music in two different ways (two different sounds, tempos, everything different).
What I find interesting is that even if you combine the two songs starting at different times, the human mind makes them sound like one song. Weird. But you can stop and start each song independently and see that they really are playing simultaneously.
But the important thing is that you can have two songs playing at the same time, so there's no excuse for not adding music and sound effects to your games. I have one or two more audio posts to do and then we can get back to making games. As I've learned, HTML5 Audio is a little tricky, but worth it.
Showing posts with label audio. Show all posts
Showing posts with label audio. Show all posts
Tuesday, December 17, 2013
Monday, December 16, 2013
Son of HTML5 Audio Followup (Game Programming)
While most of the rest of HTML5 has grown up and is very capable (we're looking at you, Canvas), HTML5 Audio still seems to have some growing pains. It may be replaced at some point soon by Web Audio, but for now, HTML5 Audio works pretty well if you don't ask too much out of it except play an audio.
There are a few more nooks and crannies I've been exploring, namely the Audio object properties of loop and controls.
Loop simply plays the audio over and over again. This is ideal for game music you want in the background, but I'm still investigating what happens if two audios overlap each other. I'm working on that and that's one of my next tasks. But loop works! How it works I'll explain in a minute.
The other fun bit for today are controls. If you just play audio, you don't see anything in your user interface. If you want to give the user some control over the controls of your audio, you have two ways to go.
Note that the words "Audio Controls" are NOT part of the control. They are text I put in the web page just for fun.
This takes up a fair amount of screen space, so it may not be useful. And then again, it may. The controls show the current time (0:02 seconds), the duration (0:09 seconds), and graphically shows you where the song is at this moment. The user also can press the pause ( || ) button in the top center and the mute button on the right.
If you tap the mute button, it turns color. The music still plays but you can't hear it. It looks like this:
Perhaps of limited interest, but you might find a use for it, especially if you put it on a separate page.
But there's a little bit more you can do. If you can get at the Audio object, you can modify some of the properties of the visual controls.
For example, you can change the background color, indent, and width of the box.
Oops, that's not what it looked like on the desktop! Yes, the controls are narrower, but I don't think they are indented, and the red background is, um, not behind the controls, but above it.
Here's what it looked like on the Firefox OS desktop browser (nightly):
Indented, narrow, and reddish (actually red + gray). So there's some work to do here and I probably should file a bug (except that I'm not sure how many people want to have standard controls in Firefox OS). The main problem is that you can't really adjust the height, and the default is too big.
I don't exactly fault Firefox OS folks for not making this work. There are much higher priorities and there's a workaround. You can make your own controls (or maybe all you want is to toggle mute). I'll cover that next time (or soon).
So here's the code, similar to the code for http://firefoxosgaming.blogspot.com/2013/12/html5-audio-followup-game-programming.html.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>
Loop & Controls
</title>
<script>
// Global variables
var myAudio;
// Load the page.
window.addEventListener("load",
runFirst, false);
// Runs when the page is loaded.
function runFirst() {
console.log("page loaded");
// Create audio object.
// We like OGG.
myAudio = new Audio("oggsong.ogg");
// Need this to see the controls.
document.getElementById("myBody").
appendChild(myAudio);
// Show the controls.
myAudio.controls = true;
// Allow looping.
myAudio.loop = true;
// Use an ID to work with controls.
myAudio.id = "controlID";
// Change width, margin, and color.
controlID.style.width = "150px";
controlID.style.marginLeft = "50px";
controlID.style.backgroundColor = "red";
// Listen for fully loaded audio.
myAudio.addEventListener("canplaythrough",
processMyAudio, false);
}
// The audio is ready to play.
function processMyAudio() {
console.log("audio loaded");
// Event no longer needed.
myAudio.removeEventListener("canplaythrough",
processMyAudio, false);
// Play the audio.
myAudio.play();
}
</script>
</head>
<body id="myBody">
<p>Audio Controls</p>
</body>
</html>
Looping
Adding looping is pretty simple. Just add this line:
myAudio.loop = true;
If you want to stop the looping (but not stop the audio playing), set loop to false.
Controls
Setting the controls is a little bit more work. The first part is easy:
myAudio.controls = true;
But that won't work by itself. To make the controls visible, you must attach the control to the web page by this time-honored technique:
document.getElementById("myBody").
appendChild(myAudio);
This just attaches the myAudio object to the body of the web page. If you are just playing audio invisibly you don't need to do this. To display, all objects must be attached somewhere to the page.
Then, to modify the controls, you need to do one other thing, which is make an id for the audio control. This lets it be styled by CSS. Here's what you need to add:
myAudio.id = "controlID";
This just give the audio object an id named controlID. It can be named anything as long as it doesn't conflict with any other names.
Now your control can be stylin'. Just add these three lines:
controlID.style.width = "150px";
controlID.style.marginLeft = "50px";
controlID.style.backgroundColor = "red";
The width works just fine and could be very useful. The margin doesn't look like it works and the control is still centered. The background color is red, but not lined up with the control. "Oops" sounds like a good description here.
CSS to JavaScript
By the way, the sharp-eyed among you might have noticed that the syntax for background color is NOT background-color (like it would be in HTML), but is backgroundColor. When you move from the world of HTML tags to JavaScript properties, the wording changes slightly. It's maybe like switching from Spanish to Portuguese, where you can figure it out, but you don't want to make a mistake. I found a great page that has a great table comparing CSS property names to JavaScript references (properties) by Aaron Hancock at http://noobflash.com/set-style-dynamically-with-javascript/.
So stay tuned (but not iTuned) for more about audio as I dig deeper into this surprisingly mysterious world. What ever happened to the happy simple assembly language for MS-DOS that just produced a single beep?
Beep PROC USES AX BX CX
IN AL, 61h ;Save state
PUSH AX
MOV BX, 6818; 1193180/175
MOV AL, 6Bh ; Select Channel 2, write LSB/BSB mode 3
OUT 43h, AL
MOV AX, BX
OUT 24h, AL ; Send the LSB
MOV AL, AH
OUT 42h, AL ; Send the MSB
IN AL, 61h ; Get the 8255 Port Contence
OR AL, 3h
OUT 61h, AL ;End able speaker and use clock channel 2 for input
MOV CX, 03h ; High order wait value
MOV DX 0D04h; Low order wait value
MOV AX, 86h;Wait service
INT 15h
POP AX;restore Speaker state
OUT 61h, AL
RET
BEEP ENDP
Why doesn't JavaScript have a beep() command? Next they'll take out blink()!
And why doesn't Blogger let me insert smiley faces?
There are a few more nooks and crannies I've been exploring, namely the Audio object properties of loop and controls.
Loop simply plays the audio over and over again. This is ideal for game music you want in the background, but I'm still investigating what happens if two audios overlap each other. I'm working on that and that's one of my next tasks. But loop works! How it works I'll explain in a minute.
The other fun bit for today are controls. If you just play audio, you don't see anything in your user interface. If you want to give the user some control over the controls of your audio, you have two ways to go.
- You can display a set of simple controls that will let you play, stop, and show your progress. This is what I'll cover in this post.
- You can make your own controls and fit it into your application the way you want. I'll show this soon.
Note that the words "Audio Controls" are NOT part of the control. They are text I put in the web page just for fun.
This takes up a fair amount of screen space, so it may not be useful. And then again, it may. The controls show the current time (0:02 seconds), the duration (0:09 seconds), and graphically shows you where the song is at this moment. The user also can press the pause ( || ) button in the top center and the mute button on the right.
If you tap the mute button, it turns color. The music still plays but you can't hear it. It looks like this:
Perhaps of limited interest, but you might find a use for it, especially if you put it on a separate page.
But there's a little bit more you can do. If you can get at the Audio object, you can modify some of the properties of the visual controls.
For example, you can change the background color, indent, and width of the box.
Oops, that's not what it looked like on the desktop! Yes, the controls are narrower, but I don't think they are indented, and the red background is, um, not behind the controls, but above it.
Here's what it looked like on the Firefox OS desktop browser (nightly):
Indented, narrow, and reddish (actually red + gray). So there's some work to do here and I probably should file a bug (except that I'm not sure how many people want to have standard controls in Firefox OS). The main problem is that you can't really adjust the height, and the default is too big.
I don't exactly fault Firefox OS folks for not making this work. There are much higher priorities and there's a workaround. You can make your own controls (or maybe all you want is to toggle mute). I'll cover that next time (or soon).
So here's the code, similar to the code for http://firefoxosgaming.blogspot.com/2013/12/html5-audio-followup-game-programming.html.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>
Loop & Controls
</title>
<script>
// Global variables
var myAudio;
// Load the page.
window.addEventListener("load",
runFirst, false);
// Runs when the page is loaded.
function runFirst() {
console.log("page loaded");
// Create audio object.
// We like OGG.
myAudio = new Audio("oggsong.ogg");
// Need this to see the controls.
document.getElementById("myBody").
appendChild(myAudio);
// Show the controls.
myAudio.controls = true;
// Allow looping.
myAudio.loop = true;
// Use an ID to work with controls.
myAudio.id = "controlID";
// Change width, margin, and color.
controlID.style.width = "150px";
controlID.style.marginLeft = "50px";
controlID.style.backgroundColor = "red";
// Listen for fully loaded audio.
myAudio.addEventListener("canplaythrough",
processMyAudio, false);
}
// The audio is ready to play.
function processMyAudio() {
console.log("audio loaded");
// Event no longer needed.
myAudio.removeEventListener("canplaythrough",
processMyAudio, false);
// Play the audio.
myAudio.play();
}
</script>
</head>
<body id="myBody">
<p>Audio Controls</p>
</body>
</html>
Looping
Adding looping is pretty simple. Just add this line:
myAudio.loop = true;
If you want to stop the looping (but not stop the audio playing), set loop to false.
Controls
Setting the controls is a little bit more work. The first part is easy:
myAudio.controls = true;
But that won't work by itself. To make the controls visible, you must attach the control to the web page by this time-honored technique:
document.getElementById("myBody").
appendChild(myAudio);
This just attaches the myAudio object to the body of the web page. If you are just playing audio invisibly you don't need to do this. To display, all objects must be attached somewhere to the page.
Then, to modify the controls, you need to do one other thing, which is make an id for the audio control. This lets it be styled by CSS. Here's what you need to add:
myAudio.id = "controlID";
This just give the audio object an id named controlID. It can be named anything as long as it doesn't conflict with any other names.
Now your control can be stylin'. Just add these three lines:
controlID.style.width = "150px";
controlID.style.marginLeft = "50px";
controlID.style.backgroundColor = "red";
The width works just fine and could be very useful. The margin doesn't look like it works and the control is still centered. The background color is red, but not lined up with the control. "Oops" sounds like a good description here.
CSS to JavaScript
By the way, the sharp-eyed among you might have noticed that the syntax for background color is NOT background-color (like it would be in HTML), but is backgroundColor. When you move from the world of HTML tags to JavaScript properties, the wording changes slightly. It's maybe like switching from Spanish to Portuguese, where you can figure it out, but you don't want to make a mistake. I found a great page that has a great table comparing CSS property names to JavaScript references (properties) by Aaron Hancock at http://noobflash.com/set-style-dynamically-with-javascript/.
So stay tuned (but not iTuned) for more about audio as I dig deeper into this surprisingly mysterious world. What ever happened to the happy simple assembly language for MS-DOS that just produced a single beep?
Beep PROC USES AX BX CX
IN AL, 61h ;Save state
PUSH AX
MOV BX, 6818; 1193180/175
MOV AL, 6Bh ; Select Channel 2, write LSB/BSB mode 3
OUT 43h, AL
MOV AX, BX
OUT 24h, AL ; Send the LSB
MOV AL, AH
OUT 42h, AL ; Send the MSB
IN AL, 61h ; Get the 8255 Port Contence
OR AL, 3h
OUT 61h, AL ;End able speaker and use clock channel 2 for input
MOV CX, 03h ; High order wait value
MOV DX 0D04h; Low order wait value
MOV AX, 86h;Wait service
INT 15h
POP AX;restore Speaker state
OUT 61h, AL
RET
BEEP ENDP
Why doesn't JavaScript have a beep() command? Next they'll take out blink()!
And why doesn't Blogger let me insert smiley faces?
Thursday, December 12, 2013
HTML5 Audio Followup (Game Programming)
I'm still deep into HTML5 Audio programming as it relates to Firefox OS. I ran into some interesting problems and filed bug 949129 to make sure I'm not crazy. I'll be working on some work-arounds for the problems I'm seeing so you can still use audio in your games.

This post will cover a few things more I've found, in random order.
Audio Codecs
André Jaenisch pointed out that I didn't explain that MP3 and OGG are not lossless. This means that when the audio file is created, some of the bits are removed so that the file size is smaller. A popular format for lossless audio is FLAC. But this blog is all about Firefox OS gaming and right now, FLAC is not supported. As a matter of fact, MP3 is not supported either.
The original non-lossy formats were WAV (Windows) and AIFF (Apple). There might be an original Unix/Linux format (AU?) but I've not used it. WMA (Windows), AAC (Apple), and MP3 (Fraunhofer) all use compression to make file sizes smaller, but still sound pretty good. Somewhere in the middle is the open-source FLAC, which uses compression but doesn't lose any quality and is considered lossless.
MP3 is an interesting issue for Firefox. For a long time, Firefox didn't support MP3 directly unless your operating system had already set up support. Because of this, when programming audio for the Firefox browser, you had to make two files, one MP3 and the other OGG. And for other browsers, you might have to add in an Apple codec (but we don't speak Apple here). You can read about Firefox support at https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats, but keep in mind that this is a moving target.
Very recently, Mozilla announced that they will support MP3 and pay the fee. MP3 costs money right now, OGG is free! The good news is that the MP3 patents will expire in a year or two.
Why does all this matter? If you have your music in MP3 and you convert it to OGG, the lossy audio will become more lossy. Right now, the music I download onto my ZTE Open will play even if it is MP3, but if I want to write a program in HTML5, my best bet is OGG. Firefox will let you program a WAV file, but the WAV file size is larger than OGG or MP3, and for a phone, you always want the smallest of everything.
So the point is, if you are making music for the Firefox OS, create your original file in WAV format (or one of the Apple formats), but at some point, convert it to OGG. But save your original file (lossless) so you can convert it later if you want to program with MP3.
My own personal guess is that OGG will be supported in Firefox OS for a long time, so its a safe bet. WAV is supported, but large file sizes will make it a poor option for phones and tablets. MP3 support will be soon, and I wouldn't be surprised to see in the future support for Apple's AAC, which is catching on fast (because it has smaller file sizes and better fidelity than MP3).
And don't forget, OGG is open source and very cool!
So if you think HTML5 audio is confusing, wait until you get to HTML5 video! But the answer is to start working with Web Audio (not the same as HTML5 Audio) which is supported. I'll be poking into that soon, but there's more pressing matters.
Oh, and I misspelled the cool audio workstation Ardour. Sorry, guys. Get it at http://ardour.org/.
Globals
According to many wise JavaScript gurus, you should avoid globals. However, I find that I need them to make things simple for small game demos. So in the recent HTML5 Audio post at http://firefoxosgaming.blogspot.com/2013/12/html5-audio-game-programming_10.html, I had this global definition:
// Global variables
var myAudio;
I don't assign it anything yet, because I need to wait until the page loads. This variable is used for the audio object and gets created in the audio constructor here, but only after the page loads:
myAudio = new Audio("oggsong.ogg");
When working with objects and loading things, you always want to make sure that you know something is loaded before you use it. But also, in this case, if you don't make myAudio global, the function processMyAudio won't know where to find it.
And as part of the making sure, processMyAudio doesn't get called until canplaythrough tells us that the audio is now loaded and ready to go!
If you do these things without some of the safeguards, things might work or they might not. But you want to be sure. But if you don't make myAudio global, the music won't play. Using JavaScript functions is cool, but you want to make sure that everything inside the function can be used.
You can rewrite this program to avoid globals and pass things through function calls, but for now, I want to keep everything as simple as possible. If you want to know more about why globals are evil, check out JavaScript, the Good Parts. The book is difficult but worth reading several times, and I don't always agree with the author, but he clearly knows what he's talking about.
Here's a great picture of the two best books on JavaScript:
The thin book on the left is Crockford's JavaScript: The Good Parts. The thick book on the right is called JavaScript: The Definitive Guide by David Flanagan. Read both and you'll know most of what you need to know. Make sure you get the latest edition of Flanagan, because it gets updated every few years. Note the size difference of the two books, but there's lots of good parts in the bigger book also.
Firefox OS Simulator
The Firefox OS simulator (available to your Firefox browser as a plug-in) is really valuable for debugging audio. Something that runs just fine in the desktop browser may not work on the phone. Why do I bring this up?
If you use MP3 in the Firefox desktop browser, all works well. But not on the phone. If you use OGG, your audio works in the simulator. Before audio, I barely looked at the simulator unless there was a sizing issue, but for audio, it's crucial that the sound works at the simulator level.
What Might Not Be Working
I was surprised to see that two of the audio object's properties, duration and currentTime didn't work in Firefox OS when they work just fine in desktop Firefox. I haven't read all the browser source code yet, but I filed a bug 949129. You can check it out at https://bugzilla.mozilla.org/show_bug.cgi?id=949129. You can read my test code there.
By the way, if you find any kind of bug, make sure you can reproduce it, and file it at Bugzilla. Remember, YOU are Mozilla. Make it better and bang on it today. Especially with Firefox OS, which is still young and growing.
I'll keep you posted.
Next
I'm working on a work-around for the lack of currentTime. I'll also do some short code samples for loop and controls. And there's a sample game I want to get on to next, and maybe some game engines, and oh, yes, more game reviews. And vibration and tilt and oh, the list goes on forever!

This post will cover a few things more I've found, in random order.
Audio Codecs
André Jaenisch pointed out that I didn't explain that MP3 and OGG are not lossless. This means that when the audio file is created, some of the bits are removed so that the file size is smaller. A popular format for lossless audio is FLAC. But this blog is all about Firefox OS gaming and right now, FLAC is not supported. As a matter of fact, MP3 is not supported either.
The original non-lossy formats were WAV (Windows) and AIFF (Apple). There might be an original Unix/Linux format (AU?) but I've not used it. WMA (Windows), AAC (Apple), and MP3 (Fraunhofer) all use compression to make file sizes smaller, but still sound pretty good. Somewhere in the middle is the open-source FLAC, which uses compression but doesn't lose any quality and is considered lossless.
MP3 is an interesting issue for Firefox. For a long time, Firefox didn't support MP3 directly unless your operating system had already set up support. Because of this, when programming audio for the Firefox browser, you had to make two files, one MP3 and the other OGG. And for other browsers, you might have to add in an Apple codec (but we don't speak Apple here). You can read about Firefox support at https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats, but keep in mind that this is a moving target.
Very recently, Mozilla announced that they will support MP3 and pay the fee. MP3 costs money right now, OGG is free! The good news is that the MP3 patents will expire in a year or two.
Why does all this matter? If you have your music in MP3 and you convert it to OGG, the lossy audio will become more lossy. Right now, the music I download onto my ZTE Open will play even if it is MP3, but if I want to write a program in HTML5, my best bet is OGG. Firefox will let you program a WAV file, but the WAV file size is larger than OGG or MP3, and for a phone, you always want the smallest of everything.
So the point is, if you are making music for the Firefox OS, create your original file in WAV format (or one of the Apple formats), but at some point, convert it to OGG. But save your original file (lossless) so you can convert it later if you want to program with MP3.
My own personal guess is that OGG will be supported in Firefox OS for a long time, so its a safe bet. WAV is supported, but large file sizes will make it a poor option for phones and tablets. MP3 support will be soon, and I wouldn't be surprised to see in the future support for Apple's AAC, which is catching on fast (because it has smaller file sizes and better fidelity than MP3).
And don't forget, OGG is open source and very cool!
So if you think HTML5 audio is confusing, wait until you get to HTML5 video! But the answer is to start working with Web Audio (not the same as HTML5 Audio) which is supported. I'll be poking into that soon, but there's more pressing matters.
Oh, and I misspelled the cool audio workstation Ardour. Sorry, guys. Get it at http://ardour.org/.
Globals
According to many wise JavaScript gurus, you should avoid globals. However, I find that I need them to make things simple for small game demos. So in the recent HTML5 Audio post at http://firefoxosgaming.blogspot.com/2013/12/html5-audio-game-programming_10.html, I had this global definition:
// Global variables
var myAudio;
I don't assign it anything yet, because I need to wait until the page loads. This variable is used for the audio object and gets created in the audio constructor here, but only after the page loads:
myAudio = new Audio("oggsong.ogg");
When working with objects and loading things, you always want to make sure that you know something is loaded before you use it. But also, in this case, if you don't make myAudio global, the function processMyAudio won't know where to find it.
And as part of the making sure, processMyAudio doesn't get called until canplaythrough tells us that the audio is now loaded and ready to go!
If you do these things without some of the safeguards, things might work or they might not. But you want to be sure. But if you don't make myAudio global, the music won't play. Using JavaScript functions is cool, but you want to make sure that everything inside the function can be used.
You can rewrite this program to avoid globals and pass things through function calls, but for now, I want to keep everything as simple as possible. If you want to know more about why globals are evil, check out JavaScript, the Good Parts. The book is difficult but worth reading several times, and I don't always agree with the author, but he clearly knows what he's talking about.
Here's a great picture of the two best books on JavaScript:
The thin book on the left is Crockford's JavaScript: The Good Parts. The thick book on the right is called JavaScript: The Definitive Guide by David Flanagan. Read both and you'll know most of what you need to know. Make sure you get the latest edition of Flanagan, because it gets updated every few years. Note the size difference of the two books, but there's lots of good parts in the bigger book also.
Firefox OS Simulator
The Firefox OS simulator (available to your Firefox browser as a plug-in) is really valuable for debugging audio. Something that runs just fine in the desktop browser may not work on the phone. Why do I bring this up?
If you use MP3 in the Firefox desktop browser, all works well. But not on the phone. If you use OGG, your audio works in the simulator. Before audio, I barely looked at the simulator unless there was a sizing issue, but for audio, it's crucial that the sound works at the simulator level.
What Might Not Be Working
I was surprised to see that two of the audio object's properties, duration and currentTime didn't work in Firefox OS when they work just fine in desktop Firefox. I haven't read all the browser source code yet, but I filed a bug 949129. You can check it out at https://bugzilla.mozilla.org/show_bug.cgi?id=949129. You can read my test code there.
By the way, if you find any kind of bug, make sure you can reproduce it, and file it at Bugzilla. Remember, YOU are Mozilla. Make it better and bang on it today. Especially with Firefox OS, which is still young and growing.
I'll keep you posted.
Next
I'm working on a work-around for the lack of currentTime. I'll also do some short code samples for loop and controls. And there's a sample game I want to get on to next, and maybe some game engines, and oh, yes, more game reviews. And vibration and tilt and oh, the list goes on forever!
Labels:
AAC,
AIFF,
AU,
audio,
Firefox OS simulator,
FLAC,
globals proved harmful,
HTML5 audio,
JavaScript,
mp3,
OGG,
WAV,
WMA
Subscribe to:
Posts (Atom)







