DATF.as

The DSP Audio Toolkit for Flash.  The DATF is a wrapper class that provides simple interfacing with C/C++ DSP functions via Adobe Alchemy.

Summary
DATF.asThe DSP Audio Toolkit for Flash.
UsageThe DATF is designed for developers who want more control over the dynamic audio capabilities of Actionscript.
Example
Constructor
DATFConstructor to create a DATF object.
Audio Framing
setFrameThis function copies the data from a ByteArray into the shared Actionscript/C memory.
Basic Library Functions
FFTComputes the Fast Fourier Transform (FFT) of the current frame.
IFFTPerforms an Inverse Fourier Transform on the current frame.
magSpectrumCalculates the magnitude spectrum from the complex frequency spectrum.
Spectral FeaturesAll spectral features are computed on mono audio.
getBandwidthCalculates the spectral bandwidth for the current frame.
getCentroidCalculates the spectral centroid for the current spectral data.
getFluxCalculates the change in spectral energy between the current frame and the previous frame.
getIntensityCalculates the spectral intensity for the current frame.
getRolloffCalculates the spectral rolloff for the current frame.
Spectral Analysis
getHarmonicAmplitudesA function to return the amplitude of the harmonics.
getHarmonicFrequenciesReturns an array containing the partial’s frequencies populated by callilng the getHarmonics function.
getHarmonicsIsolates the harmonics (or partials more generally speaking) of spectral data.
getLPCCalculates the linear prediction coefficients using Levinson-Durbin recursion.
getPitchUses the autocorrelation method to estimate the pitch of frame.
getPitchFromSpeechSame as getPitch except it provides min/max pitch values and a threshold useful for determining if there is an active signal in the current frame.
addReverbThis function implements a well-known image model in order to simulate room reverb based on simulated room dimensions.
filterAudioFIRFilters the audio with the given filter (array of coefficients).
filterAudioIIRFilters the audio with the given filter (array of coefficients).
vocoderApplies the phase vocoder functionality to each AudioChannel object unique to the DATF
Utilities
clearAudioBuffersA Function to clean out the audioBuffers at the completion of audio file playback.
checkOutputBufferA function to determine if the C-based audioFrame is ready for reading during audio playback.
endOfFile()This function should be called when a file is complete or after ALF.stopAudio has been called.
getChOutPtrs()Returns: An array containing the pointers to the C audio buffers.
getCRAM()Returns: A pointer to the C memory buffer.
getHopSize()The current hopSize in the DATF.
getNumberOfChannels()The current number of channels.
reInitializeChannelThis funciton should be called when a new song is loaded with a different sample rate(for wav) or the hop size is changed.
resetAllThis resets all of the buffers and values to their state at initialization.

Usage

The DATF is designed for developers who want more control over the dynamic audio capabilities of Actionscript.  For simpler ‘out of the box’ functionality, use the <ALF.as>.  The DATF provides a means to access a variety of DSP functions that are written in C/C++ and then compiled with the Alchemy enabled g++ compiler to create bytecode that is optimized for the Actionscript Virtual Machine.  The ALFPackage.swc file you include in your project (process outlined in the Introduction) contains all the functions that are called from the DATF.  A simple example is given below.  Note that this is a scaled down version of what ALF does.  Again, the reason for using DATF rather than ALF is to implement the dynamic audio playback in a different manner.

Example

class myClass{

    var DSP:DATF;

    var mp3Bytes:ByteArray:
    var playBytes:ByteArray:
    var audio:Sound;
    var mp3Audio:Sounc;
    var audioCh:SoundChannel;

    var cRAM:ByteArray;
    var audioPtrs:Array;
    var leftBufferStatus:Array;
    var rightBufferStatus:Array;

    const var STEREO:Boolean = true;
    const var hopSize:uint = 2048;
    const var fs:uint = 44100;

    public function myClass(){

        var song:String = "Testsong.mp3";

        var mp3Request:URLRequest = new URLRequest(song);                       // Load filename
        mp3Bytes = new ByteArray();                                             // For raw samples from file
        mp3Bytes.endian = Endian.LITTLE_ENDIAN;

        audio = new Sound();                                                    // Sound object for playback
        mp3Audio = new Sound();                                                 // Sound object for audio file sample extraction
        audioCh = new SoundChannel();

        cRAM = new ByteArray();
        leftBufferStatus = new Array();
        rightBufferStatus = new Array();
        audioPtrs = new Array();

        // Attempting to read in the MP3 file
        try{
            sourceAudio.load(mp3Request);
        } catch(e:IOError){
                trace('Error reading MP3 file');
        }
        mp3Audio.addEventListener(Event.COMPLETE, mp3Loaded);
        audio.addEventListener(SampleDataEvent.SAMPLE_DATA, mp3AudioCallback);  // Dispatched on each audio frame
    }

    //Load MP3 file and play
    private function mp3Loaded(evt:Event):void{

        //Initilize the DATF
        DSP = new DATF(hopSize, STEREO, fs);

        cRAM = DSP.getCRAM();                                                       // Pointer to shared AS/C memory
        audioPtrs = DSP.getChAudPtrs();                                             // Pointers to the L/R channels

        // Read first frame
        mp3Bytes.position = 0;
        mp3Position += mp3Audio.extract(mp3Bytes,hopSize,mp3Position);          // Extract samples
    }

    private function mp3AudioCallback(evt:SampleDataEvent):void {

        mp3Bytes.position = 0;
        DSP.loadMP3Frame(mp3Bytes);             // Load the audio frame into the C buffer

        // You must check to see if audio is being synthesized by DATF (i.e. using reverb)
        leftBufferStatus = DSP.checkAudioBuffer("left");
        rightBufferStatus  = DSP.checkAudioBuffer("right");
        numSamplesToPlay = Math.min(leftBufferStatus[1], rightBufferStatus[1]);                 // Find how many samples to play

        for(i = 0; i < numSamplesToPlay; i++){

            cRAM.position = audioPtrs[0] + i*sizeofFloat;       //position for leftCh
            leftSample = cRAM.readFloat();
            cRAM.position = audioPtrs[1] + i*sizeofFloat;       //position for rightCh
            rightSample = cRAM.readFloat();

            evt.data.writeFloat(leftSample);
            evt.data.writeFloat(rightSample);
        }

        //Extract audio data from sound object
        mp3Bytes.length = 0;
        mp3Position += mp3Audio.extract(mp3Bytes,hopSize,mp3Position);          // Extract samples
        mp3Bytes.position = 0;                                                      // Reset pointer

        //Tell C there is a new frame coming
        DSP.newFrame();
    }
}

Constructor

DATF

public function DATF(_hopSize: uint,
_STEREO: Boolean,
_fs: uint,
frameLookAhead: Number):void

Constructor to create a DATF object.  This constructor initializes the shared memory between Actionscript and C/C++.  Only mono and stereo files are accepted.  The C/C++ library is included via the line

import cmodule.ALFPackage.CLibInit;

Parameters

_hopSizeThe hop between audio frames.  This is also the number of samples read in on each frame, except the first frame where twice the number of samples are read
_STEREOA boolean indicating whether the file is mono or stereo (False for mono, true for stereo)
_fsThe sample frequency
frameLookAheadThe number of frames that will be processed before audio playback begins

Audio Framing

setFrame

public function setFrame(audio: ByteArray,
type: String):int

This function copies the data from a ByteArray into the shared Actionscript/C memory.  The C flags are reset and then the C input buffer is polled to determine if it can accept more data without overrunning itself.  If a write is deemed safe, the number of available samples is calculated and then written to the shared memory, the number of samples is also written to the memory for proper processing by C functions.

Parameters

audioA ByteArray object containing raw sample data.  For .wav files URLLoader can be used if passed as URLLoader.data.
typeA string specifying ‘float’ or ‘short’ datatype.

Returns

Returns 1 if data was written, 0 if no data was written See Also:

DATF, AudioChannel.cpp

Example

If the URLLoader called is ‘wavData’, then the function call would be

DATF.setFrame(wavData.data, "short");

Basic Library Functions

FFT

public function FFT(_fftSize: uint):Array

Computes the Fast Fourier Transform (FFT) of the current frame.

Parameters

_fftSizeThe nuber of DFT points to be used in calculating the Discrete Fourier Transform.  Enter 0 for the default behavior.  The default is the next power of two greater than the hopSize and is the recommneded way to compute the DFT.

Returns

An array of alternating real and complex values.

See Also

IFFT(), magSpectrum()

IFFT

public function IFFT(fftSize: uint):Array

Performs an Inverse Fourier Transform on the current frame.

Parameters

fftSizeThe number of IDFT points to be used in calculating the Inverse Fourier Transform.  For reconstruction of a signal, this number needs to be the same as the fftSize used when the forward transform was calculated.

Returns

An array of sample points.

See Also

FFT()

magSpectrum

public function magSpectrum(_fftSize: int,
useDB: Number):Array

Calculates the magnitude spectrum from the complex frequency spectrum.  To calclate a DFT of another size other than the framSize, use FFT() first with the desired hopSize as a parameter and then call magSpec().

Parameters

_fftSizeThe size of the FFT used in calculating the spectrum.  A value of 0 sets this to the default, which is the greatest power of two higher than the frame size.
useDBA value of 1 will return the magnitude spectrum in decibels, 0 for unmodified magnitude.

See Also

FFT()

Spectral Features

All spectral features are computed on mono audio.  For stereo files, the channels are averaged, then the feature value is computed on each frame.  This does not effect playback, only the calculation of the feature values.

getBandwidth

public function getBandwidth():Number

Calculates the spectral bandwidth for the current frame.

Returns

The spectral bandwidth.

getCentroid

public function getCentroid():Number

Calculates the spectral centroid for the current spectral data.

Returns

The spectral centroid.

getFlux

public function getFlux():Number

Calculates the change in spectral energy between the current frame and the previous frame.

Returns

The spectral flux.

getIntensity

public function getIntensity():Number

Calculates the spectral intensity for the current frame.

Returns

The spectral intensity.

getRolloff

public function getRolloff():Number

Calculates the spectral rolloff for the current frame.

Returns

The spectral rolloff.

Spectral Analysis

getHarmonicAmplitudes

public function getHarmonicAmplitudes():Array

A function to return the amplitude of the harmonics.

Returns

Returns an array containing the partial amplitudes populated by calling the getHarmonics function.  These amplitudes are specified in decibels (dB).  Note: getHarmonics() must be called before this function in order to populate the array with meaningful data.

See Also

getHarmonicFrequencies(), getHarmonics()

getHarmonicFrequencies

public function getHarmonicFrequencies():Array

Returns an array containing the partial’s frequencies populated by callilng the getHarmonics function.  The frequencies indicated are in Hertz (Hz).  Note: getHarmonics() must be called before this function in order to return meaningful data.

See Also

getHarmonics(), getHarmonicAmplitudes()

getHarmonics

public function getHarmonics(desiredHarms: uint):void

Isolates the harmonics (or partials more generally speaking) of spectral data.  The function operates on a particular channel pointer in order to extract the partials from the spectrum. getHarmonics populates two arrays: harmFreqs and harmAmps which contain the frequencies of the partials and their respective amplitudes (in dB).  Separate calls are required to retrieve harmAmps (getHarmAmps) and harmFreqs (getHarmFreqs).  This function must be called before the others to return relevant data.

Results will vary depending on a variety of factors, such as the type of spectrum (noisy or harmonic) as well as the hopSize used to process the audio.  A harmonic-like spectrum should return the fundamental frequency as well as partials that are related by integer multiples of the fundamental (harmonics: i.e.  110Hz, 220Hz, 440Hz, ...etc).  A noisy spectrum will yield non-harmoincally related peaks.  Also, a large hopSize will tend to smear the spectral data, since the stationarity assumption does not hold over longer time windows.

The C functioncall returns an array indicating 1) if an error was encountered 2) the number of harmonics found (may be less than the number requested) 3) the pointer for the amplitude (peaks) array and 4) the pointer for the frequency array

Parameters

desiredHarmsAn int specifying the desired number of harmonics the function should return.  Int value should be: 0 < desiredHarms < (hopSize/2 + 1)

See Also

getHarmonicFrequencies(), getHarmonicAmplitudes()

getLPC

public function getLPC(order: int):Array

Calculates the linear prediction coefficients using Levinson-Durbin recursion.

Parameters

orderThe prediction order.

getPitch

public function getPitch():Number

Uses the autocorrelation method to estimate the pitch of frame.

Parameters

none Returns: pitch - The estimated pitch value

See Also

DSPFunctions.c->autoCorr

getPitchFromSpeech

public function getPitchFromSpeech(pitchMin: Number,
pitchMax: Number,
intenThreshold: Number):Number

Same as getPitch except it provides min/max pitch values and a threshold useful for determining if there is an active signal in the current frame.

Parameters

pitchMinthe minimum acceptable pitch value
pitchMaxthe maximum acceptable pitch value
intenThresholdthe intensity threshold value

Returns

The estimated pitch value

See Also

getPitch()

addReverb

public function addReverb(activate: String,
level: Number,
roomX: Number,
roomY: Number,
roomZ: Number,
srcX: Number,
srcY: Number,
srcZ: Number,
micX: Number,
micY: Number,
micZ: Number):void

This function implements a well-known image model in order to simulate room reverb based on simulated room dimensions.  A filtering method in the C methods implements a fast-convolution-based filter to add the required reverb.  The reverb response is calculated based on the emitting-source’s position in the room, the room’s dimensions and the listener (microphone) position.  By default the reverb is applied to both channels.

Parameters

activateA String, either “on” or “off”.  This sets the state of the reverb.  Once turned “on”, it will remain on until turned off.  If “off”, it will remain so until turned on.
levelA Number value that indicates the reflection strength.  Possible values are integers in the range [1-4].
roomXthe width of the simulated room in the x dimension
roomYthe width of the simulated room in the y dimension
roomZthe height of the simulated room in the z dimension
srcXthe source (audio) position in the x dimension
srcYthe source (audio) position in the y dimension
srcZthe source (audio) position in the z dimension
micXthe mic (listener) position in the x dimension
micYthe mic (listener) position in the y dimension
micZthe mic (listener) position in the z dimension
  • all src and mic positions must be within the bounds defined by the simulated room dimensions.

filterAudioFIR

public function filterAudioFIR(coeffs: Array):void

Filters the audio with the given filter (array of coefficients).

Parameters

filterCoefficientsThe filter coefficients.

filterAudioIIR

public function filterAudioIIR(numCoeffs: Array,
denCoeffs: Array,
gain: Number):void

Filters the audio with the given filter (array of coefficients).

Parameters

numeratorCoefficientsThe numerator coefficients.
denominatorCoefficientsThe denominator coefficients.

vocoder

public function vocoder(active: Boolean,
newPitch: Number,
newTempo: Number)

Applies the phase vocoder functionality to each AudioChannel object unique to the DATF

Parameters

activea boolean value that indicates if the vocoder is on (1) or off(0)
newPitcha number (0.5 - 2.0) indicating the factor by which to modify the tempo.  0.5 correspoinds to an octave up and 2.0 is an octave below.
newTempo = a number (0.52.0) indicating the factor by which to modify the the tempo.  0.5 corresponds to twice the rate and 2.0 corresponds to half the rate.

Utilities

clearAudioBuffers

public function clearAudioBuffers():void

A Function to clean out the audioBuffers at the completion of audio file playback.

Notes

Buffers cleaned are -

  • inAudioFrame: A buffer allocated with each channel in C that contains the samples for the current frame to be processed and the samples for playback.
  • Circular Buffers: A buffer allocated with each channel that tracks overlapping audio samples when certain operations (i.e. filtering) are in use.

See Also

AudioChannel.cpp, ALF.stopAudio()

checkOutputBuffer

public function checkOutputBuffer(channelType: String):Array

A function to determine if the C-based audioFrame is ready for reading during audio playback.

Parameters

channelTypeA string indicating the desired channel to be checked.  “left” and “right” are valid arguments.

Returns

An array containing

  • 1) A boolean indicating whether or not the audio is ready for playback and
  • 2) The number of samples that can be played if the status is “true” (i.e. its ready).

endOfFile()

public function endOfFile():void

This function should be called when a file is complete or after ALF.stopAudio has been called.  The buffers are cleared, flags reset, and parameters in the AudioChannel set accordingly to begin playback of the beginning of a file.

See Also

AudioChannel.cpp, <ALF>

getChOutPtrs()

public function getChOutPtrs():Array

Returns: An array containing the pointers to the C audio buffers.  The first element is the left channel pointer, the second element is the right channel.  Note these pointers are different from what is returned by getCRAM() in that they provide the location of the current sample in the audio buffers where as getCRAM() provides a pointer to the entire shared C memory buffer which includes all variables instantiated in <ALFPackace.cpp>.

getCRAM()

public function getCRAM():ByteArray

Returns: A pointer to the C memory buffer.

getHopSize()

public function getHopSize():uint

Returns

The current hopSize in the DATF.

getNumberOfChannels()

public function getNumberOfChannels():uint

Returns

The current number of channels.

reInitializeChannel

public function reInitializeChannel(hop: uint,
sampleRate: uint,
channels: Number,
frameLookAhead: Number):void

This funciton should be called when a new song is loaded with a different sample rate(for wav) or the hop size is changed.  This equates to a change in the number of frames per second.  It will create a right channel if one does not exist.

Parameters

hopThe new hop size.
sampleRateThe new sample rate.
channelsThe number of channels in the new song.
frameLookAheadThe offset (in frames) between the current data being returned and audio playback.

See Also

AudioChannel.cpp->reInitChannel, ALFPackage.cpp->reInitializeChannel

resetAll

public function resetAll():void

This resets all of the buffers and values to their state at initialization.

See Also

ALFPackage.cpp->resetAll

public function DATF(_hopSize: uint,
_STEREO: Boolean,
_fs: uint,
frameLookAhead: Number):void
Constructor to create a DATF object.
public function setFrame(audio: ByteArray,
type: String):int
This function copies the data from a ByteArray into the shared Actionscript/C memory.
public function FFT(_fftSize: uint):Array
Computes the Fast Fourier Transform (FFT) of the current frame.
public function IFFT(fftSize: uint):Array
Performs an Inverse Fourier Transform on the current frame.
public function magSpectrum(_fftSize: int,
useDB: Number):Array
Calculates the magnitude spectrum from the complex frequency spectrum.
public function getBandwidth():Number
Calculates the spectral bandwidth for the current frame.
public function getCentroid():Number
Calculates the spectral centroid for the current spectral data.
public function getFlux():Number
Calculates the change in spectral energy between the current frame and the previous frame.
public function getIntensity():Number
Calculates the spectral intensity for the current frame.
public function getRolloff():Number
Calculates the spectral rolloff for the current frame.
public function getHarmonicAmplitudes():Array
A function to return the amplitude of the harmonics.
public function getHarmonicFrequencies():Array
Returns an array containing the partial’s frequencies populated by callilng the getHarmonics function.
public function getHarmonics(desiredHarms: uint):void
Isolates the harmonics (or partials more generally speaking) of spectral data.
public function getLPC(order: int):Array
Calculates the linear prediction coefficients using Levinson-Durbin recursion.
public function getPitch():Number
Uses the autocorrelation method to estimate the pitch of frame.
public function getPitchFromSpeech(pitchMin: Number,
pitchMax: Number,
intenThreshold: Number):Number
Same as getPitch except it provides min/max pitch values and a threshold useful for determining if there is an active signal in the current frame.
public function addReverb(activate: String,
level: Number,
roomX: Number,
roomY: Number,
roomZ: Number,
srcX: Number,
srcY: Number,
srcZ: Number,
micX: Number,
micY: Number,
micZ: Number):void
This function implements a well-known image model in order to simulate room reverb based on simulated room dimensions.
public function filterAudioFIR(coeffs: Array):void
Filters the audio with the given filter (array of coefficients).
public function filterAudioIIR(numCoeffs: Array,
denCoeffs: Array,
gain: Number):void
Filters the audio with the given filter (array of coefficients).
public function vocoder(active: Boolean,
newPitch: Number,
newTempo: Number)
Applies the phase vocoder functionality to each AudioChannel object unique to the DATF
public function clearAudioBuffers():void
A Function to clean out the audioBuffers at the completion of audio file playback.
public function checkOutputBuffer(channelType: String):Array
A function to determine if the C-based audioFrame is ready for reading during audio playback.
public function endOfFile():void
This function should be called when a file is complete or after ALF.stopAudio has been called.
public function stopAudio():void
A function to stop playback of an audio file.
public function getChOutPtrs():Array
Returns: An array containing the pointers to the C audio buffers.
public function getCRAM():ByteArray
Returns: A pointer to the C memory buffer.
public function getHopSize():uint
The current hopSize in the DATF.
public function getNumberOfChannels():uint
The current number of channels.
public function reInitializeChannel(hop: uint,
sampleRate: uint,
channels: Number,
frameLookAhead: Number):void
This funciton should be called when a new song is loaded with a different sample rate(for wav) or the hop size is changed.
public function resetAll():void
This resets all of the buffers and values to their state at initialization.
Thank you for trying the Audio Processing Library for Flash (ALF) developed by the Music and Entertainment Technology Lab in the Department of Electrical and Computer Engineering at Drexel University.
This class manages the buffers and other data needed in audio storage, playback, and processing.
void autoCorr(float *corrData,
int fftSize)
Computes the autocorrelation of a given sequence, which is just its cross correlation with itself.
void AudioChannel::reInitChannel(int _hopSize,
int _fftSize,
int _fs,
int numCh,
int _lookAheadFrames)
This funciton is called when a channel (L or R) has already been instantiated and initialized and a new song is loaded that requires changes to the buffer sizes.
AS3_Val reInitializeChannel(void* self,
AS3_Val args)
Re-initializes the channel after a new song of different sample rate has been loaded
AS3_Val resetAll(void *self,
AS3_Val args)
This funciton resets all of the buffers in the AudioChannel as well as the flags.
Close