Changeset - r14734:58c3f99dc69c
[Not reviewed]
master
0 3 0
peter1138 - 14 years ago 2010-03-06 11:08:31
peter1138@openttd.org
(svn r19332) -Codechange: Simplify sound panning by using float data, and switch to sinusoidal algorithm to maintain output level.
3 files changed with 18 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/mixer.cpp
Show inline comments
 
@@ -7,12 +7,13 @@
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file mixer.cpp Mixing of sound samples. */
 

	
 
#include "stdafx.h"
 
#include <math.h>
 
#include "core/math_func.hpp"
 

	
 
struct MixerChannel {
 
	bool active;
 

	
 
	/* pointer to allocated buffer memory */
 
@@ -182,16 +183,24 @@ void MxSetChannelRawSrc(MixerChannel *mc
 
	}
 

	
 
	mc->samples_left = (uint)size * _play_rate / rate;
 
	mc->is16bit = is16bit;
 
}
 

	
 
void MxSetChannelVolume(MixerChannel *mc, uint left, uint right)
 
/**
 
 * Set volume and pan parameters for a sound.
 
 * @param mc     MixerChannel to set
 
 * @param volume Volume level for sound, range is 0..16384
 
 * @param pan    Pan position for sound, range is 0..1
 
 */
 
void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan)
 
{
 
	mc->volume_left = left;
 
	mc->volume_right = right;
 
	/* Use sinusoidal pan to maintain overall sound power level regardless
 
	 * of position. */
 
	mc->volume_left = volume * sin((1.0 - pan) * M_PI / 2.0);
 
	mc->volume_right = volume * sin(pan * M_PI / 2.0);
 
}
 

	
 

	
 
void MxActivateChannel(MixerChannel *mc)
 
{
 
	mc->active = true;
src/mixer.h
Show inline comments
 
@@ -16,10 +16,10 @@ struct MixerChannel;
 

	
 
bool MxInitialize(uint rate);
 
void MxMixSamples(void *buffer, uint samples);
 

	
 
MixerChannel *MxAllocateChannel();
 
void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, bool is16bit);
 
void MxSetChannelVolume(MixerChannel *mc, uint left, uint right);
 
void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan);
 
void MxActivateChannel(MixerChannel*);
 

	
 
#endif /* MIXER_H */
src/sound.cpp
Show inline comments
 
@@ -21,15 +21,12 @@
 
#define SET_TYPE "sounds"
 
#include "base_media_func.h"
 

	
 
static SoundEntry _original_sounds[ORIGINAL_SAMPLE_COUNT];
 
MusicFileSettings msf;
 

	
 
/* Number of levels of panning per side */
 
#define PANNING_LEVELS 16
 

	
 
static void OpenBankFile(const char *filename)
 
{
 
	memset(_original_sounds, 0, sizeof(_original_sounds));
 

	
 
	/* If there is no sound file (nosound set), don't load anything */
 
	if (filename == NULL) return;
 
@@ -155,13 +152,13 @@ void InitializeSound()
 
{
 
	DEBUG(misc, 1, "Loading sound effects...");
 
	OpenBankFile(BaseSounds::GetUsedSet()->files->filename);
 
}
 

	
 
/* Low level sound player */
 
static void StartSound(SoundID sound_id, int panning, uint volume)
 
static void StartSound(SoundID sound_id, float pan, uint volume)
 
{
 
	if (volume == 0) return;
 

	
 
	const SoundEntry *sound = GetSound(sound_id);
 
	if (sound == NULL) return;
 

	
 
@@ -171,18 +168,15 @@ static void StartSound(SoundID sound_id,
 
	MixerChannel *mc = MxAllocateChannel();
 
	if (mc == NULL) return;
 

	
 
	if (!SetBankSource(mc, sound)) return;
 

	
 
	/* Apply the sound effect's own volume. */
 
	volume = (sound->volume * volume) / 128;
 
	volume = sound->volume * volume;
 

	
 
	panning = Clamp(panning, -PANNING_LEVELS, PANNING_LEVELS);
 
	uint left_vol = (volume * PANNING_LEVELS) - (volume * panning);
 
	uint right_vol = (volume * PANNING_LEVELS) + (volume * panning);
 
	MxSetChannelVolume(mc, left_vol * 128 / PANNING_LEVELS, right_vol * 128 / PANNING_LEVELS);
 
	MxSetChannelVolume(mc, volume, pan);
 
	MxActivateChannel(mc);
 
}
 

	
 

	
 
static const byte _vol_factor_by_zoom[] = {255, 190, 134, 87};
 
assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_COUNT);
 
@@ -241,13 +235,13 @@ static void SndPlayScreenCoordFx(SoundID
 

	
 
		if (vp != NULL &&
 
				left < vp->virtual_left + vp->virtual_width && right > vp->virtual_left &&
 
				top < vp->virtual_top + vp->virtual_height && bottom > vp->virtual_top) {
 
			int screen_x = (left + right) / 2 - vp->virtual_left;
 
			int width = (vp->virtual_width == 0 ? 1 : vp->virtual_width);
 
			int panning = (screen_x * PANNING_LEVELS * 2) / width - PANNING_LEVELS;
 
			float panning = (float)screen_x / width;
 

	
 
			StartSound(
 
				sound,
 
				panning,
 
				(msf.effect_vol * _vol_factor_by_zoom[vp->zoom - ZOOM_LVL_BEGIN]) / 256
 
			);
 
@@ -275,13 +269,13 @@ void SndPlayVehicleFx(SoundID sound, con
 
		v->coord.top, v->coord.bottom
 
	);
 
}
 

	
 
void SndPlayFx(SoundID sound)
 
{
 
	StartSound(sound, 0, msf.effect_vol);
 
	StartSound(sound, 0.5, msf.effect_vol);
 
}
 

	
 
INSTANTIATE_BASE_MEDIA_METHODS(BaseMedia<SoundsSet>, SoundsSet)
 

	
 
/** Names corresponding to the sound set's files */
 
static const char * const _sound_file_names[] = { "samples" };
0 comments (0 inline, 0 general)