SerbianEnglish (United Kingdom)
Flash10 Audio PDF Print E-mail
Written by Саша Рудан   
Sunday, 07 December 2008 03:41

Often technologies are helping to make tasks easier. That is also nice :), but when technology is helping you to make impossible tasks possible, that is exciting thing. That happened with new audio support for Flash 10. Here I am talking about way to implement FFT (Fast Fourier Transform) with Flash.

Introduction

Last few years Flashers tried in different ways to squeeze out more from Flash Audio. Flash 9 introducet audio spectrum with SoundMixer.computeSpectrum(). This gave us a chance to make attractive audio visualizers with AS3. However, the biggest problem still left unsolved:

  • real-time sound generation from Flash
  • retrieving audio spectrum in real-time (computeSpectrum() provides only asynchronous pulling and reading current spectrum)
  • real-time manipulation with audio signal in time and frequent domain
  • recording audio signal from microphone
With AS3 introduction the speed of Flash application dramatically rized providing us with different tricks related to dynamic sound generation. One of the most excitiong concept was dynamic creation of SWF fajl with embeded sound which is also dynamicaly created, of course :) (look at popforge). This is kind of dirty ;) but fascinant way of extending some framework.

Other way was by using Java applets to manipulate with sound and than pass it back to Flash using JavaScript interface.

Flash 10

Flash 10 introduced the most important news related to sound in the last few Flash versions.

Audio Signal Dynamic Creation

Now, we are able to fill Sound object with audio samples that we created in our AS3. You know that that means you can creaty any kind of sound now :)

Reading audio samples from audio signal

This is another exciting feature that gives us a chance to read audio samples from some MP3 file in the real-time and than for example to mix it with another MP3 file and that is how we made a simple mixete ;)

Examples

Examples related to these new features are realy not difficult to find. Very interesting example is in very Flash 10 documentation. I do not have to much to say about that except that you should play with it ;)

FFT (Fast Fourier Transform)

Introduction

Time and spectral signal

Time signal is record of some sginal over time. In the case of digitallysampled singal, this is a sequence of sampled intensities over time in equidistant time intervals, Tdelta.

Spectrum signal is mathematically similar :). Conceptually, it presents a set of all frequencies contained in the signal including intensities and phases. In spectrum signal we are also sampling in equidistant frequency intervals, Fdelta. It is important to realize that in order to find out frequency in some signal, we will always make Fdelta error. For some predictable signal we can make it smaller using interpolation.

FT (Fourier Transform)

FT (Fourier Transform) is mathematical tool that give us a way to calculate spectral signal from time signal and vice versa. That means, if you are able to access time signal (in Flash with extract() method= than you are able to calculate spectrum signal using FT. More precisely, you will use DFT (Discret Fourier Transform).

Acctualy, FT is function polinomialing, similar to Newton's polinoms,besides that FT transpose signal to the another domain which give us interesting possibilities:
  • signal pitching
  • Sound filtering (Lowpass, Highpass, bandpass filters), noise reduction
  • main frequency detection (i.e. guitar tunners :) )
  • etc

For some of effect we need IFT (Inverse Fourier Transform) also. It provides us with transposing signal from spectral domain into time domain.

FFT & IFFT

FFT (Fast Fourier Transform) is optimised FT that is also adopted for computer processing. Optimisation is dramatic and without it many of real-time DSP algorithms wouldn't be possible.

To be shourt, I will just say that FFT use N samples of a signal from time domain, dissasebles it into N signals containing 1 sample (but beiing wide N samples; all other samples are equal to 0), calculates N frequency domains for N signals and thanassembles back all those frequency spectrums into one spectrum that coresponds to the original unassembled signal. This sound like a more work but it is not, since in onrmal DFT, calculation for each sample depends on all other samples, so in this way we broke up that complex dependency. This gives us complexity of O(n log n) for FFT, compared with O(n2) for DFT.

Here is the scenario of some FFT application:

  • Signal (just a piece of signal like 1/20 of second) is retrieved indigitaly sampled time domain
  • There is an initial processing in time domain (i.e. signal normalization)
  • Signal is transposed to frequency domain with FFT
  • We process signal in frequency domain (i.e. lowpass filtering)
  • Signal is transposed back to time domain with IFFT
  • We have final processing in time domain
  • Signal is pushed to the output or next processing unit

One problem with signal processing in expressed way is in jittering. Where that jittering is coming from? It is a result of processing in frequency domain. If you used FFT just to obesrve signal in frequency domain, than you willnothave problems. However if you changed signal, then you destroyed signal phase at the borders of time-signal piece.This makes it unmatching with the previous and next time-signal pieces, which means that we will have jitters on "tailored" places.

There are solutions to avoid it but let's consider it later.

Example - Bandpassfilter

Introduction

This example is relatively simple. However, it consists of multiple components.

  1. Sound Dispatcher - global infrastructure that makes audio distribution between different audio processing components
  2. SourceMP3 - Component that extracts audio signal from mp3 file
  3. SourceOscillation - Component that generates sinusoidal signal
  4. Mixer - Component that mixes 2 audio signals
  5. Output - Component that "plays" audio signal
  6. FourierTransformation - Component tht executes Fourier Transform
  7. Spectrum - Component that visuelize frequency spectru
  8. KnobSlider - Vusual knob that gives us possibility to change oscillator frequency

COmponents that I will analyze are components 1, 6 and 7. The rest of components are here just to make example working, and they areneither finished nor topic of this post but probable some later one. Of course, you are free to explore and use them :)



>>> Source Code

Description

The following picture describes audio signal flow in our example:

Bandpass audio flow

Each componet is enough self-descriptive, except the one component that you couldn't even see; that component is the component that integrates all other components and forwards/dispatches requests and signal between them.

This component is contained in Мain.as file and for the present moment it is not implemented in the most elegant way and maybe too complicated. The reason for that is the fact that later will be developed AudioHeads system which will be set of Flash components for sound processing and there will be need for much more complex component for signal distribution.

Basic way of working

The basic way of working is presented with the following process: output audio component sends requests for audio samples to the sound distribution component:

	var num: int = parent.RequestData(this, this.inputBuffer, length, startPosition);

The later component tracks connections between all components and forwards request to the component that goes before in the sequence and return response to the audio output component:

	public function RequestData(requester:AudioComponent, target:ByteArray, 
length:Number, startPosition:Number = -1, channel:int=0):Number{
var sourceID:int = this.connectionsComponents[requester.id + channel*(LAST_COMPONENT+1)];
var sourceComponent:AudioComponent = this.components[sourceID];
return sourceComponent.RequestData(requester, target, length, startPosition);
}

This method finds from connectionsComponents matrix the ID of the component that goes before, than references it from the array of components components, and forwards request that component and result of that request it returns to the component that initiated request (audio output component in this case).

The earlier component will request audio signal from the component that goes before it in the signal sequence :), and in that way all up to the sound source. From sound source sound will propagate back to audio output component.

FFT/IFFT component

Component name: FourierTransformation

Package: SoundProcessors

This is the most important and the most easier component at the same time.

The following functions are important:

RequestData()

This method is inerited from AudioProvider class. It is responsible for forwarding data to the component that follows in the audio chain; audio oputput in this case.

As already said, this method asks for audio samples from the audio component that goes before it in audio chain (audio mixer in this concrete case), and to do that it talks to parent component; sound dispatcher.

In the first loop, this method prepares data for FFT processing; fills real and imaginary samples. In the case of real sygnal, imaginary samples are 0. It also fills output samples for the following component in chain (in the case there is no processing in frequency domain).

After the loop, DirectFFT method is being called which calculates signal in frequency domain from signal in time domain. The whole chapter is needed to explain this method, so I will stay on introduction in the beginning of this post. For you is probable good enough to know that it is working :).

It is interesting that DirectFFT is returning frequency spectrum in the same arrays used for time spectrum; inputs_real and inputs_imag. For application of FFT method processOutput is more important. That method finds local maximums (i.e. main frequencies). In the case of complex signal it can produce a lot of pikes, so we need either to look for global maximum ir set level of minimal intesity. For some applications (like this example) call to this funcion is not needed. You also should consider storageoptimization, since we are firing Garbage Collector in this case.

If we need filtering in frequeny domain, than we do it and after that we call method responsible for IFFT.

	for( i= 0 ; i < num ; ++i )
{
// bandwidth filtering
if(! ((i>=this.indexLow1 && i=this.indexLow2 && i<=this.indexHigh2)) ){
this.inversed_real[i] = 0;
this.inversed_imag[i] = 0;
}else{
this.inversed_real[i] = this.inputs_real[i];
this.inversed_imag[i] = this.inputs_imag[i];
}
}

this.InverseFFT(true, this.samplesNoLog2, this.samplesNo, this.inversed_real, this.inversed_imag);

Since frequency domain is symetric to Niquist frequency, that is the reason we have to clean Lower and Upper part of spectrum. Explanation for that is mathematicaly little bit too complex.

Finaly, with IFFT we transform frequency spectrum back to time domain and put it int vector that is response to the following audio component.

GetIndexForFrequency(frequency:Number, roundToHigher:Boolean)

This method calculates index in frequency spectrum that corresponds to provided frequency. I noted that samples in frequency domain are equidistant. In the case that frequency doesn't fit to the frequency of any sample, parameter roundToHigher insists on rounding up to the higher index.

SetFilter(frequencyLow:Number, frequencyHigh:Number)

This method sets filter. It calls function GetIndexForFrequency to find correct indexes, and indexes for symmetrical higher spectrum it calculates "manually".

GetSamples(spectrum:Vector., indexLow:int, indexHigh:int, samplesNo:int)

This method returns set of requested number of samples in specified frequency interval.It should be corrected to calculated cumulative average value of all samples that goes into one sample in result, and not just to take one that falls to that specific position. се узме онај који "пада" на датој позицији.

DirectFFT(dir:Boolean, m:int, n:int, re:Vector., im:Vector.)
DirectFFT method is already explained in previous text.
InverseFFT(dir:Boolean, m:int, n:int, re:Vector., im:Vector.)

IFFT method relies on call to FFT method which is based on symmetry of FFT and IFFT calculation.

createTestInput(input_signals:Vector.)

This method used just for testing and it creates input test audio signal in time domain.ектру

DirectDFT()

This method implements classical FT which we can use to test our IFFT implementation or to notice enormous difference in processing time comparing to FFT method

Spectrum component

Spectrum component is used for visualization of frequency spectrum. Each frame it calls FFT component to retrieve samples in the interval it is interested in and than visualize them as small bars with height corresponding to intensity.

Possible improvements

Main problem of FFT way of filtering is in jittering. A way to avoid it is interpolation; to calculate additional frequency spectrums from the middle of intervals (N/2) and than to use that frequency spectrum for joints and normal frequency spectrums on the rest of interval.

Other improvement about better way of storing detected frequency pitches is already mentioned.

Next improvent is related to way of processing signal and needless of copying signal in each component (except in the case of mixer and delay component, etc). This helps us to optimize our system in memory and time resources.

Last Updated on Monday, 19 January 2009 12:12
 
Comments (29)
answer
29 Friday, 03 September 2010 19:05
This post is really awesome! I have been searching for some information about the Ohio health care system and accidentally I have noticed this headline. As I see, this site is full of more such great posts like this one so I will definitely bookmark it. Thanks a lot one more time. Mike.
Interesting
28 Friday, 03 September 2010 10:08
Interesting article, Thanks!
Nice work
27 Wednesday, 01 September 2010 12:13
This method returns set of requested number of samples in specified frequency interval.It should be corrected to calculated cumulative average value of all samples
thanks
26 Tuesday, 31 August 2010 18:48
Thank you for this beautiful theme I wish you more such fascinating topics Thank you
25 Tuesday, 31 August 2010 09:04
Well, I am deeply impressed by your point here!!! And I like the way which you build your article!! Looking forward to read your more posts??
iphone 3g case
respond.
24 Monday, 23 August 2010 10:13
Accept with you in this points:Main problem of FFT way of filtering is in jittering. A way to avoid it is interpolation; to calculate additional frequency spectrums from the middle of intervals (N/2) and than to use that frequency spectrum for joints and normal frequency spectrums on the rest of interval.I have been using FFT and I know this clearly.
Cheers, chase personal loans
Tuesday, 31 August 2010 21:07
I suppose to receive mortgage loans from banks must present a great motivator. However, once I have a bank loan because he wanted to buy a building. jewelry buyer Houston
hi
23 Sunday, 22 August 2010 17:41
gives us a chance to read audio samples from some MP3 file in the real-time and than for example to mix it with another MP3 file and that is how we made a simple mixete ;)
cool
22 Saturday, 07 August 2010 11:17
I came to your article from another article and am really interested in this learning about this. , I feel strongly about information and love learning more on this. If possible, as you gain expertise, It is extremely helpful for me.
would you mind updating your blog with more information?
21 Friday, 06 August 2010 05:14
I really like this article. It contains a lot of useful information. I can set up my new idea from this post. Thanks so much!
satellite pc tv
My thought
20 Thursday, 05 August 2010 04:46
Hey...i must say " simply professional "
Good efforts...I am also working as a web designer as i am from art background.
I am more interested in flash animations/ sites.
thanks
19 Tuesday, 03 August 2010 12:16
thanks for your good article ;)
flash 10
18 Monday, 02 August 2010 14:15
i haven´t tried the software yet, but it looks promising with a lot of new functionalities
Flash 10
17 Thursday, 29 July 2010 08:22
Flash is really awesome technology and it is very Common now a days.
nice
16 Wednesday, 28 July 2010 12:16
Ok, I can understand the fact that the version is only the beta one not the final, but we have expected a better version from Adobe. I think Adobe should work on decreasing the Audio’s request-response time, which is very important especially for any
thanks
15 Wednesday, 14 July 2010 13:39
Substantially, the article is really the best on this laudable topic. I concur with your conclusions and will eagerly look forward to your future updates. Just saying thank you will not just be enough, for the wonderful lucidity in your writing. I will instantly grab your rss feed to stay abreast of any udates.
Gratifying work and much success in your business endeavors!!!!
cool
14 Monday, 05 July 2010 08:46
This is a nice blog. Good clean UI and nice informative blog. I will be coming back soon, Thanks for posting some great ideas and I'll try to return back with a completely different browser to check things out! Also, I put a link to your blog at my site, hope you don't mind?
music
13 Saturday, 03 July 2010 22:53
I ve worked with this program for a week. Good job. How can I use it for my fav.music from music search ?
12 Sunday, 27 June 2010 03:35
axx
i haven't tried out yet, but it's offering a lot, nice job
i'm trying to construct a visualisation fitted to the beat of musik. i're in a despaired need of fast band filtering to have time for further computations. posting results asap ...
-
még nem próbáltam ki, de nagyon igéretes, szép munka
én egy olyan vizualizációt próbálok megvalósítani, ami a zene üteméhez igazodik. nagy szükségem volt arra, hogy sávokra tudjam osztani a jelet gyorsan, hogy maradjon idő a további számításokra. az eredményet postolom, amint lehet ...
Friday, 03 September 2010 04:03
I am sorry to say that I could not make out the idea conveyed through this blog. In fact blogs like these serve only purpose – wasting the valuable time of the reader. Nowadays blogging is used by people throughout the world for mostly two purposes - to express their opinion and to facilitate exchange of information. But this blog has failed miserably in both the accounts. I hope that the author will be a little bit more careful while writing blogs in the future.
Thursday, 01 July 2010 13:31
axx
final step not fine, sry
Thursday, 01 July 2010 13:29
axx
bro!
sry i have to tell that it's creaking. i changed song, like u told, and i found awfull noise when filtering. i think its generated throught ifft from 0 u'r using afther freq cut to keep signal length.
by the way fft algorithm u'r using is a Cooley-Tukey algoritm, rn't u? i belive if u calculate the fine step with dft, it can be usded not just power of 2 number of samples. am i rigth? it called somthing Danielson-Lanczos lemma. im fighting with math can u help me, pls.

with all respect
...
11 Wednesday, 02 June 2010 17:14
Quite informative article on not so well explored
subject :) It's very hard to find any examples
in this subject... Could you be so nice and post
some code you've mentioned in the article ?

BTW. Do you think that's possible to calculate FFT
via PixelBender in favour of performance gain ?
Flash
10 Monday, 31 May 2010 16:47
hey i am currently working on a multi touch project where i have defined the sound where user puts the finger on the screen it generates sound what i would like to know if it is possible to give real time spectrum to the visuals in the amplitude of the sound ?
nice
9 Tuesday, 25 May 2010 16:23
Bonjour et merci pour les informations bonne continuation
re
8 Tuesday, 18 May 2010 22:29
I agree with your conclusions and will eagerly look forward to your next updates. Saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will immediately grab your rss feed to stay privy of any updates. Pleasant work and much success in your business dealings!
buy
7 Tuesday, 27 April 2010 14:04
If there is any problem just ask.
Friday, 03 September 2010 01:59
i'm hoping you can help me with a game i am making that i think requires pitch conrol.
i am making a automobile racing game, and i think the best way to make a dynamic engine nosie would be to get the mid range rev engine sound and use a pitch control in relation to the car's speed to change how high or low the revs sound.
do you think this would be the best way to do it?
if so are you able to give me some tips or point me in the right direction?
of even better...do it for me? :D
Thanks
Mensagens para Orkut
Thursday, 29 April 2010 18:00
cam
This is very complex and I am also having trouble understanding it.
i don't konw
6 Friday, 23 April 2010 21:09
i don't understand
Comment
5 Thursday, 01 April 2010 10:14
Hi! We wanted a new version with dynamic sound and we got it. But I‘m also not satisfied with the very long audio latency using the new dynamic sound generation APIs. Ok, I can understand the fact that the version is only the beta one not the final, but we have expected a better version from Adobe. I think Adobe should work on decreasing the Audio’s request-response time, which is very important especially for any electronic musician.
Friday, 03 September 2010 04:06
Just recently I used Adobe Audition 3 software. In fact I brought it for my son who wants to be a singer. He points out it has been of immense help to him in recording, mixing, editing etc. it has got a variety of features and in my view it is the best audition software available in the market. It provides real value for money. I encourage all my fellow bloggers to try it, especially those working in the music industry.
Saturday, 07 August 2010 12:41
Administrator
This method calculates index in frequency spectrum that corresponds to provided frequency. I noted that samples in frequency domain are equidistant. In the case that frequency doesn't fit to the frequency of any sample, parameter roundToHigher insists on rounding up to the higher index.
4 Friday, 23 October 2009 08:28
hey i am currently working on a multi touch project where i have defined the sound where user puts the finger on the screen it generates sound what i would like to know if it is possible to give real time spectrum to the visuals in the amplitude of the sound ?
Wednesday, 01 September 2010 17:34
Always good to see, this was a brilliant post. In theory I would like to write like this too. You need time to creat that interesting and additionally real effort to make such a good article. muscle building
PB
3 Tuesday, 14 April 2009 11:28
jkozniewski
In case you've missed this:
http://www.kaourantin.net/2008/10/audio-mixing-with-pixel-bender.html

Note that PB Toolkit has been updater recently
so maybe they solved a bug that Tinic refered to in
his post.
:)
2 Tuesday, 14 April 2009 10:23
Hi, thanks a lot :)
I'm in process of building kind of "sound game" in which
accessing sound spectrum data for particular sounds separately (instead of built-in global SoundSpectrum) is essential.

Regarding PB i think that with few hacks it's possible
to force it to process arbitrary data - in form of bytearray or even vector... Main problem may be it's inability of computing more complexed algorithms ( lack of loops, arrays etc ).

I'll post any progress I'll made in this subject :)
Hope to stay in touch :)
code :) ?
1 Tuesday, 14 April 2009 00:30
Hi,
Quite informative article on not so well explored
subject :) It's very hard to find any examples
in this subject... Could you be so nice and post
some code you've mentioned in the article ?

BTW. Do you think that's possible to calculate FFT
via PixelBender in favour of performance gain ?
Friday, 03 September 2010 04:07
I would like to add a little more facts about Pixel Bender. It delivers a common image and video processing infrastructure which will facilitate automatic runtime optimization on heterogeneous hardware. Pixel Bender kernel language can be used for implementation of image processing algorithms in a hardware-independent manner. Thus it saves valuable time and energy. Regarding the question mentioned in the blog I have asked one of my friends who is an expert in these things. He will be mailing me within two days.
Tuesday, 14 April 2009 01:11
Sasha Rudan
Hi,

I just put code and working example.

Sorry for missing this out :)

If you want to try it, you need to set correct path to your mp3 file in Main.as (line 125).

If there is any problem just ask.

Sasha

P.S. I hope, it would be possible to speed up with PixelBender. I just started investigating on it. It mainly depends what PB can accept as input. I think it is addressing only few pixels in image, so it seems it cannot work with big arrays that represents audio samples :(

We can play with it together and see if it works :)
In source code you have FFT algorithm

Add your comment

Very HappySmileWinkSadSurprisedShockedConfusedCoolLaughingMadRazzEmbarrassedCrying or Very SadEvil or Very MadTwisted EvilRolling EyesExclamationQuestionIdeaArrowNeutralMr. GreenGeekUber Geek
Your name:
Your website:
Subject:
Comment (you may use HTML tags here):