1
package com.brackeen.javagamebook.sound;
3
import com.brackeen.javagamebook.graphics.Sprite;
6
The Filter3d class is a SoundFilter that creates a 3d sound
7
effect. The sound is filtered so that it is quiter the farther
8
away the sound source is from the listener.
9
<p>Possible ideas to extend this class:
10
<ul><li>pan the sound to the left and right speakers
12
@see FilteredSoundStream
14
public class Filter3d extends SoundFilter {
16
// number of samples to shift when changing the volume.
17
private static final int NUM_SHIFTING_SAMPLES = 500;
19
private Sprite source;
20
private Sprite listener;
21
private int maxDistance;
22
private float lastVolume;
25
Creates a new Filter3d object with the specified source
26
and listener Sprites. The Sprite's position can be
27
changed while this filter is running.
28
<p> The maxDistance parameter is the maximum distance
29
that the sound can be heard.
31
public Filter3d(Sprite source, Sprite listener,
35
this.listener = listener;
36
this.maxDistance = maxDistance;
37
this.lastVolume = 0.0f;
42
Filters the sound so that it gets more quiet with
45
public void filter(byte[] samples, int offset, int length) {
47
if (source == null || listener == null) {
48
// nothing to filter - return
52
// calculate the listener's distance from the sound source
53
float dx = (source.getX() - listener.getX());
54
float dy = (source.getY() - listener.getY());
55
float distance = (float)Math.sqrt(dx * dx + dy * dy);
57
// set volume from 0 (no sound) to 1
58
float newVolume = (maxDistance - distance) / maxDistance;
63
// set the volume of the sample
65
for (int i=offset; i<offset+length; i+=2) {
67
float volume = newVolume;
69
// shift from the last volume to the new volume
70
if (shift < NUM_SHIFTING_SAMPLES) {
71
volume = lastVolume + (newVolume - lastVolume) *
72
shift / NUM_SHIFTING_SAMPLES;
76
// change the volume of the sample
77
short oldSample = getSample(samples, i);
78
short newSample = (short)(oldSample * volume);
79
setSample(samples, i, newSample);
82
lastVolume = newVolume;