sfxr for flixel

Also Posted here

I've got a game in progress using flixel, and I used sfxr to generate the sounds, but I ran into a bunch of mp3-related issues during the embedding process, and I decided I would go ahead and implement sfxr directly into my game to see how that works. So, I wrote a very basic class 'SfxrSound' which handles this. I've added it as a zip which includes the original as3sfxr code, and pasted it below.

Using it is pretty basic. For starters, just unzip the code into your app. I've got it setup to work with embedded sfs files, although there is an (untested) method for loading settings directly as well. To use it you'll want to do something like this:

[Embed(source = 'explosion.sfs', mimeType="application/octet-stream")] public static var ExplosionSound:Class;

var explosion:SfxrSound; explosion = new SfxrSound(); explosion.loadEmbedded(ExplosionSound);

// meanwhile, something blows up explosion.play() </code>

Right now, the sound is generated when it is loaded and cached so its ready to be played on demand, because there's a chunk of lag the 1st time you generate it. From my experience, it is wise to instantiate the sound well before you need it, and it might be worthwhile to have some sort of sound manager class if you want to call the same sound from a bunch of different objects.

The code inherits from FlxSound and could probably be made to work with the proximity/translation methods with a little tweaking.

I'm experiencing a certain amount of latency which sounds like it's an FP10 issue. There might not be a decent workaround, so I'm not sure this is a good option if you need your sounds to play with any precision.

Anyway, it's rough and might not work for you, but hopefully it's helpful.

/** * very basic integration of SFXR AS3 lib into Flixel, to generate sounds on the fly * coded by Colin Mitchell (colin@muffinlabs.com) * licensed under WTFPL http://sam.zoy.org/wtfpl/ * * usage: * embedded sfs files * [Embed(source = 'explosion.sfs', mimeType="application/octet-stream")] public static var ExplosionSound:Class; * var explosion:SfxrSound; * explosion = new SfxrSound(); * explosion.loadEmbedded(ExplosionSound); */ package sfxr { import org.flixel.*; import flash.events.Event; import flash.utils.Endian; import flash.utils.ByteArray;

public class SfxrSound extends FlxSound { private var _synth:SfxrSynth;

public function SfxrSound():void {
  super();
  _synth = new SfxrSynth();
}

override public function loadEmbedded(EmbeddedSound:Class, Looped:Boolean=false):FlxSound {
  var tmpData:ByteArray = new EmbeddedSound() as ByteArray;

  stop();
  init();

  setSettingsFile(tmpData);
  initSound();
  return this;
}

private function initSound(Looped:Boolean=false):void {
  _synth.cacheSound();
  _looped = Looped;

  updateTransform();
  active = true;

  updateSound();
}

public function loadSettings(string:String, looped:Boolean=false):Boolean {
  if ( _synth.setSettingsString(string) == false ) {
	return false;
  }

  initSound(looped);
  return true;
}

/**
 * Call this function to play the sound.
 */
override public function play():void {
  _synth.playCached();
}

private function updateTransform():void	{
  _transform.volume = FlxG.getMuteValue()*FlxG.volume*_volume*_volumeAdjust;
  if(_channel != null)
	_channel.soundTransform = _transform;
}


/**
 * Reads parameters from a ByteArray file
 * Compatible with the original Sfxr files
 * @param	file	ByteArray of settings data
 */
public function setSettingsFile(file:ByteArray):void {
  _synth.deleteCache();
  file.position = 0;
  file.endian = Endian.LITTLE_ENDIAN;
		
  var version:int = file.readInt();
  
  if(version != 100 && version != 101 && version != 102) return;
		
  _synth.waveType = file.readInt();
  _synth.masterVolume = (version == 102) ? file.readFloat() : 0.5;
		
  _synth.startFrequency = file.readFloat();
  _synth.minFrequency = file.readFloat();
  _synth.slide = file.readFloat();
  _synth.deltaSlide = (version >= 101) ? file.readFloat() : 0.0;
		
  _synth.squareDuty = file.readFloat();
  _synth.dutySweep = file.readFloat();
		
  _synth.vibratoDepth = file.readFloat();
  _synth.vibratoSpeed = file.readFloat();
  var unusedVibratoDelay:Number = file.readFloat();
		
  _synth.attackTime = file.readFloat();
  _synth.sustainTime = file.readFloat();
  _synth.decayTime = file.readFloat();
  _synth.sustainPunch = file.readFloat();
  
  var unusedFilterOn:Boolean = file.readBoolean();
  _synth.lpFilterResonance = file.readFloat();
  _synth.lpFilterCutoff = file.readFloat();
  _synth.lpFilterCutoffSweep = file.readFloat();
  _synth.hpFilterCutoff = file.readFloat();
  _synth.hpFilterCutoffSweep = file.readFloat();
  
  _synth.phaserOffset = file.readFloat();
  _synth.phaserSweep = file.readFloat();
		
  _synth.repeatSpeed = file.readFloat();
  
  _synth.changeSpeed = (version >= 101) ? file.readFloat() : 0.0;
  _synth.changeAmount = (version >= 101) ? file.readFloat() : 0.0;
  
  _synth.validate();
}

} // SfxrSound } // package </code>

Filed under: Games