Flash Mod Player

From Forskningsavdelningen Wiki
Jump to: navigation, search
float

Source code[edit]

Available as a GitHub repository: Flash ProTracker Mod Player AS3

Participants[edit]

Introduction[edit]

Flash games often suffer from deficiencies when it comes to music. The fact that Flash only natively supports MP3 encoded audio coupled with the need for flash games to download quickly leads many authors to either using short loops that soon become annoying, or very low bitrate audio that frankly sounds awful.

Today, filesize is often not a problem - but it used to be in the past. It is a problem for which many solutions have already been invented. I had no interest in re-inventing the wheel, but instead to bring a solution from the past into the future - ProTracker Modules.

A ProTracker module is a music format from the Commodore Amiga-500. It is capable of producing quality game music using very limited filesizes. As an example, including the nearly 6-minute long song Audiokraft in a Flash file using our mp3 encoded samples method results in an swf-file that takes only 36kB, of which a significant part is Flash and player code overhead that will not have to be repeated for each included song.

This allows flash games to have more variation, better quality and longer loops than before - while still downloading much, much faster!

It also opens up possibilities for dynamic music that responds to the action on screen. For example, tracks can be switched out, transposed or sped up/down in response to in-game events. It is also possible to have graphics respond to music on a level that is not possible with recorded music.

License[edit]

This project is published under the Creative Commons BY-NC license available at the Creative Commons website

There are also commercial licenses available, see the source code for contact information.

You are free:

  • to Share - to copy, distribute and transmit the work
  • to Remix - to adapt the work

Under the following conditions:

  • Attribution - You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
  • Noncommercial - You may not use this work for commercial purposes.

With the understanding that:

  • Waiver - Any of the above conditions can be waived if you get permission from the copyright holder.
  • Public Domain - Where the work or any of its elements is in the public domain under applicable law, that status is in no way affected by the license.
  • Other Rights - In no way are any of the following rights affected by the license:
    • Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;
    • The author's moral rights;
    • Rights other persons may have either in the work itself or in how the work is used, such as publicity or privacy rights.
  • Notice - For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page.

Status and useage[edit]

Project is completed and fully operational.

Realtime playback[edit]

The player requires very little cpu-time and in most cases it can be used to play modules in realtime without affecting the performance of the game. Realtime playback in it's simplest form can be achieved using only a few lines of code:

import stg.mod.*;

[Embed(source="protracker.mod", mimeType="application/octet-stream")] const mod_data:Class;

var modPlayer:stg.mod.player = new stg.mod.player( new mod_data() as ByteArray );

modPlayer.play();

Preloaded playback[edit]

Preloading ensures that playback requires an absolutely minimal amount of cpu-time by spending time loading the entire module into memory before launching the game. Since it requires a significant amount of memory, it is not suitable for long songs. Also, it only supports the most basic kinds of looping.

import stg.mod.*;

[Embed(source="protracker.mod", mimeType="application/octet-stream")] const mod_data:Class;

var loaded:Boolean = false;
var modPlayer:stg.mod.player = new stg.mod.player( new mod_data() as ByteArray );

addEventListener( Event.ENTER_FRAME, Tick );

function Tick( e:Event ) {
  if( !loaded ) {
    loaded = modPlayer.preLoad( 1000 / 24 );
    if( modPlayer.preLoaded > 44100 * 8 && !modPlayer.isPlaying ) modPlayer.play(); // Play while loading
  } else {
    // Module is loaded and playing...
  }
}

MP3 compressed samples[edit]

It is possible to split modules into a data and audio section so that the audio section can be MP3-compressed by Flash and later extracted to reconstruct the sample data for playback. For some modules this results in a significant reduction of the final file size without seriously affecting the audio quality, but sometimes it does not work well for modules using very short sample loops.

The splitting is done by the mod_splitter application which is provided as a VB6 application. It is a small and simple application and can easily be ported into the language of your choice. Feel free to contact me if you require a compiled version of this application.

Once split, import the wave file into flash and export it for ActionScript. In this case I've used mod_samples as the export class name.

import stg.mod.*;

[Embed(source="protracker.mod.hdr", mimeType="application/octet-stream")] const mod_data:Class;

var modPlayer:stg.mod.player = new stg.mod.player( new mod_data() as ByteArray, new mod_samples() );

modPlayer.play();

Sound transformations[edit]

It is possible to attach a SoundTransform-object to the player. Since modules have 100% stereo separation they can be a bit harsh on the ears - especially when using headphones. Decreasing stereo separation is always recommended.

// Decrease stereo separation by 50%
modPlayer.soundTransform = new SoundTransform();
modPlayer.soundTransform.leftToLeft   = 0.75;
modPlayer.soundTransform.rightToRight = 0.75;
modPlayer.soundTransform.leftToRight  = 0.25;
modPlayer.soundTransform.rightToLeft  = 0.25;