Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411258 Posts in 69320 Topics- by 58379 Members - Latest Member: bob1029

March 26, 2024, 12:32:41 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
  Show Posts
Pages: 1 ... 4 5 [6] 7 8 ... 49
101  Player / General / Re: On Websites on: September 06, 2010, 02:42:13 PM
I'd like to see a version of the diagram in that Wired article that isn't normalized by total traffic. Has the traffic to "the web" actually gone down?
102  Developer / Technical / Re: Custom noise generation on: September 04, 2010, 03:48:40 PM
An elephant never forgets.

Okay, first a lesson in Fast Fourier Transforms, or FFT for short. FFT is a magic wand that turns periodic sound waves into frequency spectrums... and it can also do the reverse! Note that a periodic wave, in this context, is a wave that wraps around cleanly, so if you make a copy of it and put the copies end-to-end, the ends would meet. Most sounds that are recorded naturally are not exactly periodic, so if you read on the internet about using FFTs, you'll likely find a bunch of information on how to trick an FFT into interpreting a non-periodic wave without spewing out garbage. (If you see the term "window function", that's the trick.) HOWEVER that mess doesn't apply to us, because our objective is not to turn a wave into a spectrum. Our objective is the reverse: to turn a spectrum into a periodic wave, and a backwards FFT is perfect for the job.

Both the input and output of an FFT is in the exact same format: a one-dimensional array of two-dimensional vectors. Um, like this:



Those vectors are just random and not meaningful, the picture is just intended to show the data structure that we're working with. Each vector is stored as a pair of coordinates, but sometimes it's also useful to think of the vector as a length value and an angle value.

Again, both the wave and the spectrum are represented in this format. This is a little unintuitive, because sound waves are not vectors: we don't normally think of sound waves as having an angle, just an amplitude that changes over time. As it turns out you can safely ignore the extra axis when interpreting the data as a sound wave, and if you follow my directions the extra axis will be constant at zero anyway. However, the spectrum that we'll start with requires both length and angle.

When designing a spectrum, each vector describes a sine wave. If you set all of the input vectors to zero except for one, and then run it backwards through the FFT, the output will be a sine wave, AKA a "pure tone".



If two of the input vectors are nonzero, then the output will be the sum of two sine waves at different frequencies. Each sine wave has three properties, and these match three properties of the spectrum vectors:

1. The amplitude of a sine wave matches the length of a spectrum vector. Sometimes I refer to this as the "energy" of the wave: it's how loud it is.

2. The phase of a sine wave matches the angle of a spectrum vector. For example, a cosine wave is just a sine wave with a phase offset of 90 degrees. Note that humans generally can't distinguish waves by their phase, so in a sense the angle doesn't matter. However, if you leave the angle at zero for all spectrum vectors, then all of the output sine waves will rise at the same time, leading to a very degenerate case. I recommend using random angles to balance out the phases, but don't change the angles if you perform multiple FFTs with different energy distributions.

3. The frequency of the sine wave is determined by the index of the vector in the spectrum array, and also by how long the array is. This is a complicated relationship, but it's important to understand because our objective is to create noise, and noise is characterized by a distribution of energy across the frequency spectrum, so I'll explain in a moment...

The duration of the output wave is exactly the same as the number of vectors in the input spectrum, and performing an FFT is most efficient if this is a power of 2. For example, if the length of the array is 2^17 = 131072 vectors, then you'll end up with 131,072 audio samples, which is about 3 seconds at 44,100 hertz (this is the standard sample rate). For demonstration purposes let's stick with this duration, though you will likely decide to make it shorter.

The frequency of a sine wave is exactly equal to the index of the vector in the spectrum array divided by the length of the array. The first index is 0, and 0/2^17 = 0, so the frequency of the first sine wave is zero. This is not very useful, so I recommend always setting the first vector to zero. It's a special case. Smiley

Code:
input[0].x = 0.0;
input[0].y = 0.0;

The next index is 1, which means that the corresponding sine wave has a frequency of 1/2^17, which means that it repeats once every 2^17 samples, or about once every 3 seconds. You'll notice that this is the period of our entire output wave. Also notice that repeating once per 3 seconds is way below a human's hearing range. We can't hear any pure tone that repeats less than 20 times per second. So again, you can probably set the first few vectors to zero, (in this case the first 60 vectors) but it's not terribly important.

You can also ignore the frequencies higher than about 20000 times per second. However, if you do the math, you'll find that the entire second half of the frequency spectrum is higher than that, from index 2^(17 - 1) to index (2^17) - 1. That's okay, don't think too hard about the second half. You only need to design the lower half of the spectrum, and then afterwards you have to put a backwards copy of the lower half in the upper half. Um, just trust me, do it like this:

Code:
input[SAMPLES / 2].x = 0.0;
input[SAMPLES / 2].y = 0.0;
for (int i = 1; i < SAMPLES / 2; i++) {
input[SAMPLES / 2 + i].x = -input[SAMPLES / 2 - i].x;
input[SAMPLES / 2 + i].y = -input[SAMPLES / 2 - i].y;
}

As for the remaining input vectors, if you set all of them to have a length equal to 1 (and random angles) then you will get white noise after you perform the FFT. Technically, white noise has a flat distribution of energy across the frequency spectrum, and we represent that by setting each amplitude to the same value. However, humans are used to noise with less energy at higher frequencies, so I prefer to start with pink noise, which you can compute like this:

Code:
input[0].x = 0.0;
input[0].y = 0.0;

for (int i = 1; i < SAMPLES / 2; i++) {

// Pink Noise:
float length = 1.0 / sqrt((float) i);

float angle = randomAngle();
input[ i ].x = length * cos(angle);
input[ i ].y = length * sin(angle);
}

// And finally copy the lower spectrum into the upper spectrum.
input[SAMPLES / 2].x = 0.0;
input[SAMPLES / 2].y = 0.0;
for (int i = 1; i < SAMPLES / 2; i++) {
input[SAMPLES / 2 + i].x = -input[SAMPLES / 2 - i].x;
input[SAMPLES / 2 + i].y = -input[SAMPLES / 2 - i].y;
}

To generate something other than pink noise, multiply the "length" variable in the first loop by whatever you want! Then run it through the FFT and you've got your audio wave. Download some FFT library and call whatever function you need to call to perform the FFT. I've had success with FFTW, which is very fast at the cost of having a complicated API, but any FFT library should work.

Afterwards, you'll want to copy the 2D audio samples into 1D audio samples, by dropping whichever dimension is left at zero, before trying to output the wave through speakers. You'll also probably want to normalize the wave, so that the peak of the wave is 1.0. And now you're done!

...Okay that was pretty complicated after all, sorry. Tongue
103  Player / Games / Re: Notgames on: September 04, 2010, 12:21:00 PM
I'm not sure what you're asking. Are you asking what procedural generation is good for? (There are lots of possible answers to that question, but my favorite is that it can be used to prevent the player from memorizing patterns and performing them mechanically.) (Also PG and custom content are not mutually exclusive.)
104  Developer / Technical / Re: Faux 3D with sprites - Layering on: September 04, 2010, 08:03:17 AM
Insertion sort sounds pretty good to me. Is this a premature optimization? Is this your bottleneck?
105  Developer / Technical / Re: The grumpy old programmer room on: September 03, 2010, 03:45:55 PM
You're talking about Flash? There is no limit to the number of listeners in an EventDispatcher. (Except I don't think you can add the same listener twice.) (Although if you want the mechanism to be clearer, you can manage your own callbacks via "var callback: Function = something; ... callback(args)".)
106  Player / Games / Re: Indie games with zombies ? on: September 03, 2010, 03:04:09 PM
*shrug* Depends whose definition of "indie" you're using. Doesn't matter much to me. Cool
107  Player / Games / Re: Indie games with zombies ? on: September 03, 2010, 02:48:49 PM
Oh yeah that reminds me:
http://www.mojang.com/notch/j4k/l4kd/
108  Player / Games / Re: Indie games with zombies ? on: September 03, 2010, 02:08:11 PM
Off the top of my head:
http://www.kloonigames.com/blog/games/bloody
http://www.gungirl2.com/
http://www.popcap.com/games/pvz
http://deleongames.com/classic/DarkPlace.html
109  Player / General / Re: Metroid Fusion 3D on: September 03, 2010, 11:24:05 AM
Most of what I wanted to say has been said. It's basically fan fiction, complete with fan service (which I like, aside from Samus's portrayal) and crappy dialogue (which I don't like). I'm not even saying that all of the dialogue was crappy, or that it shouldn't have had any dialogue. It's just that *some* of the dialogue is extremely, eye-gougingly bad.

It's frustrating because there's great parts, and there's shitty parts mixed in, and the shitty stuff distracts from the great stuff. This goes for the dialogue, and also graphics, the gameplay, the level design, even the camera. The third person camera is pretty much the best third person camera in any 3D game, but it's used alongside pretty much the worst first person camera in any 3D game.

This is a game of extremes.

I'm glad I played it. It was fascinating, from a game design perspective.
110  Developer / Technical / Re: Custom noise generation on: August 30, 2010, 09:04:19 AM
I know exactly how to generate arbitrary noise spectrums. It's not really that complicated. It involves a backwards fourier transform. At some point when I am not sitting in the office I will explain it.

(In the meantime, if you have a mac you can try it out with this tool.)
111  Community / Townhall / Re: Phenomenon 32 on: August 23, 2010, 08:49:05 PM
I totally cracked up at 0:30.  Cheesy

EDIT: I can sympathize with the rest. Voice acting is totally fun.
112  Developer / Art / Re: Looking for characters with long necks... on: August 23, 2010, 08:03:06 PM
Before you edited your post, Jafar popped into my head.  Tongue

Quadrupeds can get away with long necks more easily, and also things that generally are not shaped like humans, such as Ridley in Super Metroid and Metroid Prime. It probably helps to have a narrow neck.

Hehe.
113  Player / General / Re: List of active members on: August 23, 2010, 02:25:06 PM
I don't understand the benefit of being able to recognize people based on a list, rather than on past experiences with them.
114  Player / General / Re: List of active members on: August 23, 2010, 01:16:46 PM
There's this:

http://forums.tigsource.com/index.php?action=mlist;sort=posts;start=0

I'd be concerned that something else might degenerate into weird popularity contests. What did you have in mind?
115  Developer / Design / Re: adding Strategy to Rock Paper Scissors on: August 20, 2010, 03:48:06 PM
Of course Rock Paper Scissors already has strategy, with humans or with AI or both. But personally I don't think it's very fun, and I'm guessing you agree since you're trying to change the strategy.  Tongue

Sirlin suggests unequal payoffs.
116  Community / Competitions / Re: Ludum Dare 18 on: August 20, 2010, 02:07:39 PM
Yep.  Tiger
117  Player / General / Re: A San Fran Job Search. on: August 19, 2010, 02:45:47 PM
For slightly less soul-crushing social gaming work, the small company that I work for in SF is hiring.
118  Community / A Game by Its Cover / Re: [AGBIC] flowEST [FINISHED] on: August 18, 2010, 05:31:03 PM
My website is currently down for unknown reasons, to be investigated. In the meantime, you can play flowEST on Newgrounds:

http://www.newgrounds.com/portal/view/544659

If I don't figure it out soon maybe I'll ask Melly to change the link for me in the compilation...

EDIT: Okay it's back. Yay!
119  Community / A Game by Its Cover / Re: [AGBIC] For The Twin [FINISHED] on: August 14, 2010, 07:03:59 PM
The artist of the original Twins picture is the same as the artist for my game's inspiration, who seemed to appreciate being notified about my game. Maybe you should say something too. Smiley
120  Community / A Game by Its Cover / Re: [AGBIC] flowEST [FINISHED] on: August 13, 2010, 12:34:29 PM
I don't know how flash's renderer is implemented, but in my code, the sprites are neither quads nor triangles. They are a call to Graphics.moveto(), followed by a sequence of Graphics.lineto()s. Some of the critters are just one polygon, plus a couple dots for eyes whose coordinates are calculated in the same manner as the rest of the vertices of the polygon. 

Maybe this screenshot of my desktop taken during development would help:
http://snoopon.me/shaktool/406
Pages: 1 ... 4 5 [6] 7 8 ... 49
Theme orange-lt created by panic