Pew Pew Pew! Sound synthesis

I started out trying to make a straight port of the excellent SFXR, but quickly got tired of picking through opaquely-named variables, and so made my own sound synthesis doodad instead.

Behold!

http://base.googlehosted.com/base_media?q=hand-4378782228061589590&size=1

Download the jar here.

A rundown of what does what:
The black panels control the value of some variable over time. Left click on them to add a point, right click to remove the closest point, and the points are draggable too. The top 4 panels should be self-explanatory, the fifth shows the effect of the vibrato on the final sound frequency, the final two control the delightfully-named flange effect.
Used to great effect by Hendrix and Procol Harum, flanging overlays the signal with a delayed version of itself, creating some weird effects.
The delay panel controls how delayed the overlay is, while the alpha panel controls how much of the delayed signal is added.

The “Signal” combobox controls the waveform of the sound, the “Vibrato” combobox controls the waveform of the vibrato that’s added to the base frequency, length controls the duration of the sound, in seconds.
“Export” saves the sound as a wav, “Play” plays the sound, and “Save” saves the data needed to recreate the sound if you want to generate it at runtime, like so:


TerrainSound ts = new TerrainSound( getClass().getClassLoader().getResourceAsStream( mySoundFilename ) );
ByteBuffer littleEndian16BitPCMData = ts.generate( 44100 );

All the code is available here.

If you’re hardcore and want to define the sound in code, you can do that too:


SoundSpec ss = new SoundSpec();

ss.volumeEnvelope = new Variable() {
	public float getValue( float time )
	{
		return the volume at that time;
	}
};
ss.waveform = new Waveform( ) {
	public float valueForPhase( float phase )
	{
		return the value at this point in a wave, eg sin( 2*PI*phase);
	}		
};
ss.waveform.frequency = new Variable( ) {
	public float getValue( float time )
	{
		return the frequency at that time;
	}
};
ss.length = foo;
ss.postProcess = new PostProcess( ) {
	public void process( ShortBuffer data, int sampleRate )
	{
		postprocesses are optional, but feel free to monkey with the data samples how you like
	}
};
		
ByteBuffer littleEndian16bitPCMData = ss.generate( 44100 );

Enjoy!

Awesomeness! /me saves next to SFXR ;D

Any chance of adding some random and mutate buttons? They were the best features of SFXR for a non-sound-inclined person like me.

Wow that is just soo brilliant! 8)

Both great to be able to create some own sounds and I guess that is also makes it possible to compress sounds heavily (if you generate at runtime) for web based stuff or anywhere that size really matters. Especially if one wants some pac-man style sounds. Could you share some presets of different types if you have some? I am specifically looking for vehicle sounds that would be possible change revs in realtime or something that can be pregenerated that one can then slide between in realtime. An accelerating car for example. Is that what one can do with the code example? (Haven’t tried it yet)

Sfxr also has the autogenerate certain types of sounds and mutate and randomize which was really great for me since I don’t quite know what I am doing, but, can then start with a good idea and then mutate or try and error til it is good enough. Load would also be useful.

Thanks for sharing!

Usability stuff like load/random/mutate/presets/space to play will probably appear tomorrow, unless I know what’s good for me and I work on my thesis instead (depressingly unlikely :-\ ).

File sizes if you’re generating at runtime are tiny - 36 bytes + 8 bytes for every point you define versus tens of kilobytes for the generated pcm data. They could certainly be reduced more, but is it worth it? I’ll leave it to the 4K-ers.

As to vehicle sounds: nothing presents itself off the top of my head, but I’d start by looking at low frequency noise, or perhaps a low hum with a noise vibrato.

This is awesome! I’d like to second the idea of adding ‘random’ and ‘mutate’ buttons and also some presets :slight_smile:

The code looks good, too. I’ll definitely be keeping an eye on this.

Alrighty then, that’s random/mutate/presets/loading added. Again, get the jar here.

I’m currently torn over whether to implement incremental sound generation. On one hand it’s going to be a minor pain in the bum to do, on the other hand it would be nice not to have the delay when you click “play”…
Maybe later…

this is very cool, amazingly useful for indie games.

heh, this brings me back to my Amstrad CPC664 days and passing random values thru its 3 channel sound generator until i found something that sounded good and used it for a simple crappy games! (well i was about 9-10 at the time :slight_smile: )

good work!

The explosion sounds exactly like the explosion from MGS1 on the PSX with the grenades…

Legend!

DP :slight_smile:

Brilliant. The new version works on Mac OS X Java 5, too. Cheers!

Good stuff! I was mildly worried about endian issues there. I had a bash at incremental generation, but it was difficult to apply postprocesses correctly and the SourceDataLine didn’t seem to want to cooperate, so I rolled back the changes.

On to actually writing a game now I suppose…

Cool program, it’s really quite funny!

Thanks for making it so easy to export stuff into a wav file :slight_smile:

PS: what’s your thesis about (80’s sound effects?!)

I wish. It’s on location algorithms for wireless sensor networks.
After four years, and now deep in a writing-up deathmarch, I’m desperate for diversions. Hence the recent burst of activity here as I finally get round to writing some gaming stuff: the sound generation, the texture packer and the font rendering. Coming next - a stupidly over-specified game of asteroids.

Hehe, well it’s said that if you want something done, give it to a busy person :stuck_out_tongue:

I was the same when I was doing my honours thesis last year, I would just sit in the computer labs and stuff around in these forums, mostly watching what other people were looking at and checking it out… pretty sad but sometimes pretty interesting seeing the funny old things that people used to have heated discussions about! I’d also lament how many cool things I could do if only I didn’t have to do my thesis. At least you’re actually making the cool things!

Apologies for the thread hijack, but is the ‘location algorithms for wireless sensor networks’ about finding people who are on their mobile phone? Sounds cool enough. My fun-packed thesis was ‘The price and volume effects of off-market share buy backs in Australia’ :’( :frowning:

Similar, but much, much harder. In the particular flavour of WSN that I’ve been looking at, the nodes are very small (and so completely crap from a capability and reliability point of view), potentially mobile, and extremely numerous. I also can’t rely on any infrastructure like cellphone masts, gps satellites or compute servers.
So it’s all error-tolerant distributed algorithms, each node working out its location with respect to its neighbours, emergent behaviour, that kind of thing.

I’m sorry for the bump, but SoundGen is exactly what I was looking for. Awesome stuff, I hope you’re still around here! I love sound synthesis, so you made me want to set up a multi-instrument enviroment for my applet game :slight_smile:

I want to buffer some random output for little sounds effects (like coin, powerup…) and pre-generate a tune. What would be better in each case, keeping ByteBuffers or Clips cached? I mean, the little wait time when clicking play in your app is caused by SoundSpec generation or in the Clip player? Is Clip much bigger in memory?

Howdy

The time for generation depends on the duration of the sound as you would expect, and it’s always a good idea to avoid work when you can, so I would keep hold of the generated buffers.
I don’t have enough experience with the javasound APIs to say much about clip objects, but I would be surprised if they were much more than a wrapper on top of the buffer.
Does anyone else know? Are Clip objects a limited resource like OpenAL sources?