Saturday 14 May 2011

Flash Dynamic Sound Generation 1


I messed around with dynamic sound generation in Flash today, inspired by some of the interesting websites like Tone Matrix and Otomata. I created a Flash swf for testing frequencies and wave-forms.

At first I didn't know where to start so some search results turned up this useful link from Adobe. Also found this site which gave a really simple sample code which I decided to try out. However, the code did not produce any sound so I looked up the docs on the SampleDataEvent and worked from there.

Things I learnt :
  1. The number of samples should not be lower than 2048, as recommended by the docs. This is because it may cause the sound to stop playing if there is not enough data, which is why my computer did not produce any sound. The number of samples are just used as buffer and do not immediately play on the next update.
  2. The callback is only called when the buffer is running out of data to stream. I felt this was not clearly explained in the docs. So essentially setting the samples to 2048 or 8192 has no effect on the sound produced. When you update 8192 samples in one update, it just means it will take a longer duration to call the callback again to refill the buffer. However, the drawback of setting a higher sample number is that it will also take up more processing time for that update.
  3. The data is always played at 44100 Hz. This is stated in the extract function of the Sound class, however, it is not reiterated in the SampleDataEvent docs, so it confused me. I'll explain why this detail is important later in (7).
  4. Wikipedia taught me that the sin wave has a rather complex general form which we seldom see. I tried playing around the DC offset in Flash but I could not tell the difference between the sounds. In essence, we only need the simple form i.e. y = A * sin ( f*t ), where A is the amplitude and f is the frequency we want.
  5. Originally I was thinking that square, triangle and sawtooth waves had to be generated by Fourier series and adding sin waves together, which is what I remember from physics class. However, through Wikipedia I found that there are simpler methods to generate these waves. For e.g. square waves can be generated simply by just using the sign of the sin wave, i.e.:
    y = -A if sin (f*t ) < 0
    y = A if sin (f*t) > 0
    In code, this would be simply: y = (sin(f*t) > 0) ? A : -A;
  6. Originally I also thought that the speed of sound was required to generate real sound frequencies. This is because we need to map the wavelength into the generation process using the frequency equation, f = v/w. However, this is not the case as we just need to set the correct wavelength for the sound to be played in the air, so we do not need to account for velocity. In other words, frequency = 1/wavelength and this meant we could directly use the frequency in our equations.
  7. The units are important! As with all mathematical calculations, making sure the units are consistent is very important. At first I was trying out with f = 220 Hz; A = 0.25, i.e. using equation y = A * sin(f*t), I got y = 0.25 * sin (220*t). Although this seems correct, this gave me the wrong sound. The problem here is that I made the wrong assumption about the units for the equation. Instead of t being time, we are actually using samples instead. The samples are playing at 44.1kHZ mentioned in (3). Therefore, the correct equation is instead y = A*sin(f *(s/44100)), where s is the sample number. This took me a while to figure out so I hope it will save you some time.
  8. Keep in mind the periods of the waves. While figuring out how to generate the sawtooth and triangle wave forms, I got a different tone from the sine and square wave forms. I figured out that I needed to multiply 2π to the sine and square wave forms because they are using the sine function but not to the other wave forms.

No comments:

Get Adsense

Want to earn money like me? Get Google Adsense now by clicking this