Skip to content

Commit

Permalink
Fixed 3D positioning and adjusted software HRTF parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Dec 7, 2011
1 parent 6e36822 commit 22a3036
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 58 deletions.
13 changes: 2 additions & 11 deletions doomsday/engine/portable/src/s_sfx.c
Expand Up @@ -43,7 +43,6 @@

#define SFX_MAX_CHANNELS (64)
#define SFX_LOWEST_PRIORITY (-1000)
#define UPDATE_TIME (2.0/TICSPERSEC) // Seconds.

// TYPES -------------------------------------------------------------------

Expand Down Expand Up @@ -923,18 +922,10 @@ void Sfx_StartFrame(void)

void Sfx_EndFrame(void)
{
static double lastUpdate = 0;
double nowTime = Sys_GetSeconds();

if(!sfxAvail)
return;

// Is it time to do a channel update?
if(nowTime - lastUpdate >= UPDATE_TIME)
{
lastUpdate = nowTime;
Sfx_Update();
}
Sfx_Update();

// The sound frame ends.
audioDriver->Event(SFXEV_END);
Expand Down Expand Up @@ -1098,7 +1089,7 @@ boolean Sfx_Init(void)
// is 56 units tall, 60 is about two meters.
//// \fixme Derive from the viewheight.
iSFX->Listener(SFXLP_UNITS_PER_METER, 30);
iSFX->Listener(SFXLP_DOPPLER, 1);
iSFX->Listener(SFXLP_DOPPLER, 1.5f);

// The audioDriver is working, let's create the channels.
Sfx_InitChannels();
Expand Down
6 changes: 4 additions & 2 deletions doomsday/plugins/fmod/fmod.pro
Expand Up @@ -16,13 +16,15 @@ HEADERS += \
include/driver_fmod.h \
include/fmod_cd.h \
include/fmod_music.h \
include/fmod_sfx.h
include/fmod_sfx.h \
include/fmod_util.h

SOURCES += \
src/driver_fmod.cpp \
src/fmod_cd.cpp \
src/fmod_music.cpp \
src/fmod_sfx.cpp
src/fmod_sfx.cpp \
src/fmod_util.cpp

win32 {
RC_FILE = res/fmod.rc
Expand Down
1 change: 1 addition & 0 deletions doomsday/plugins/fmod/include/driver_fmod.h
Expand Up @@ -54,5 +54,6 @@ extern FMOD::System* fmodSystem;
#include "fmod_sfx.h"
#include "fmod_music.h"
#include "fmod_cd.h"
#include "fmod_util.h"

#endif /* end of include guard: __DSFMOD_DRIVER_H__ */
52 changes: 52 additions & 0 deletions doomsday/plugins/fmod/include/fmod_util.h
@@ -0,0 +1,52 @@
/**\file
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2011 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

#ifndef __DSFMOD_UTIL_H__
#define __DSFMOD_UTIL_H__

#include <fmod.h>
#include <fmod.hpp>
#include <cstring>

class FMODVector : public FMOD_VECTOR
{
public:
FMODVector(float _x = 0, float _y = 0, float _z = 0) {
x = _x;
y = _y;
z = _z;
}

void set(const float* values) {
x = values[0];
y = values[1];
z = values[2];
}
};

template <typename T> void zeroStruct(T& t) {
std::memset(&t, 0, sizeof(T));
t.cbsize = sizeof(T);
}

#endif /* end of include guard: __DSFMOD_UTIL_H__ */
10 changes: 9 additions & 1 deletion doomsday/plugins/fmod/src/driver_fmod.cpp
Expand Up @@ -50,14 +50,22 @@ int DS_Init(void)
}

// Initialize FMOD.
if((result = fmodSystem->init(50, FMOD_INIT_NORMAL, 0)) != FMOD_OK)
if((result = fmodSystem->init(50, FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_HRTF_LOWPASS, 0)) != FMOD_OK)
{
printf("DS_Init: FMOD init failed: (%d) %s\n", result, FMOD_ErrorString(result));
fmodSystem->release();
fmodSystem = 0;
return false;
}

// Options.
FMOD_ADVANCEDSETTINGS settings;
zeroStruct(settings);
settings.HRTFMaxAngle = 360;
settings.HRTFMinAngle = 180;
settings.HRTFFreq = 11000;
fmodSystem->setAdvancedSettings(&settings);

DSFMOD_TRACE("DS_Init: FMOD initialized.");
return true;
}
Expand Down
74 changes: 30 additions & 44 deletions doomsday/plugins/fmod/src/fmod_sfx.cpp
Expand Up @@ -27,7 +27,7 @@
#include <cmath>
#include <vector>

typedef std::vector<char> SamplePCM8;
typedef std::vector<char> RawSamplePCM8;

struct BufferInfo
{
Expand All @@ -38,17 +38,19 @@ struct BufferInfo
float volume;
float minDistanceMeters;
float maxDistanceMeters;
FMOD_VECTOR position;
FMOD_VECTOR velocity;
FMODVector position;
FMODVector velocity;

BufferInfo()
: channel(0), sound(0), mode(0),
pan(0.f), volume(1.f),
minDistanceMeters(10), maxDistanceMeters(100) {
memset(&position, 0, sizeof(position));
memset(&velocity, 0, sizeof(velocity));
}
minDistanceMeters(10), maxDistanceMeters(100) {}

/**
* Changes the channel's 3D position mode (head-relative or world coordinates).
*
* @param newMode @c true, if the channel should be head-relative.
*/
void setRelativeMode(bool newMode) {
if(newMode) {
mode &= ~FMOD_3D_WORLDRELATIVE;
Expand All @@ -64,10 +66,10 @@ struct BufferInfo

struct Listener
{
FMOD_VECTOR position;
FMOD_VECTOR velocity;
FMOD_VECTOR front;
FMOD_VECTOR up;
FMODVector position;
FMODVector velocity;
FMODVector front;
FMODVector up;

/**
* Parameters are in radians.
Expand All @@ -80,12 +82,15 @@ struct Listener
using std::cos;

front.x = cos(yaw) * cos(pitch);
front.z = sin(yaw) * cos(pitch);
front.y = sin(pitch);
front.y = sin(yaw) * cos(pitch);
front.z = sin(pitch);

up.x = -cos(yaw) * sin(pitch);
up.z = -sin(yaw) * sin(pitch);
up.y = cos(pitch);
up.y = -sin(yaw) * sin(pitch);
up.z = cos(pitch);

/*DSFMOD_TRACE("Front:" << front.x << "," << front.y << "," << front.z << " Up:"
<< up.x << "," << up.y << "," << up.z);*/
}
};

Expand Down Expand Up @@ -150,17 +155,6 @@ int DS_SFX_Init(void)
return fmodSystem != 0;
}

#if 0
/**
* @return The length of the buffer in milliseconds.
*/
static unsigned int bufferLength(sfxbuffer_t* buf)
{
if(!buf || !buf->sample) return 0;
return 1000 * buf->sample->numSamples / buf->freq;
}
#endif

sfxbuffer_t* DS_SFX_CreateBuffer(int flags, int bits, int rate)
{
DSFMOD_TRACE("SFX_CreateBuffer: flags=" << flags << ", bits=" << bits << ", rate=" << rate);
Expand Down Expand Up @@ -198,7 +192,7 @@ void DS_SFX_DestroyBuffer(sfxbuffer_t* buf)
free(buf);
}

static void toSigned8bit(const unsigned char* source, int size, SamplePCM8& output)
static void toSigned8bit(const unsigned char* source, int size, RawSamplePCM8& output)
{
output.clear();
output.resize(size);
Expand All @@ -225,8 +219,7 @@ void DS_SFX_Load(sfxbuffer_t* buf, struct sfxsample_s* sample)
BufferInfo& info = bufferInfo(buf);

FMOD_CREATESOUNDEXINFO params;
memset(&params, 0, sizeof(params));
params.cbsize = sizeof(params);
zeroStruct(params);
params.length = sample->size;
params.defaultfrequency = sample->rate;
params.numchannels = 1; // Doomsday only uses mono samples currently.
Expand All @@ -244,7 +237,7 @@ void DS_SFX_Load(sfxbuffer_t* buf, struct sfxsample_s* sample)
info.sound->release();
}

SamplePCM8 signConverted;
RawSamplePCM8 signConverted;
const char* sampleData = reinterpret_cast<const char*>(sample->data);
if(sample->bytesPer == 1)
{
Expand Down Expand Up @@ -457,16 +450,12 @@ void DS_SFX_Setv(sfxbuffer_t* buf, int prop, float* values)
switch(prop)
{
case SFXBP_POSITION:
info.position.x = values[0];
info.position.y = values[1];
info.position.z = values[2];
info.position.set(values);
if(info.channel) info.channel->set3DAttributes(&info.position, &info.velocity);
break;

case SFXBP_VELOCITY:
info.velocity.x = values[0];
info.velocity.y = values[1];
info.velocity.z = values[2];
info.velocity.set(values);
if(info.channel) info.channel->set3DAttributes(&info.position, &info.velocity);
break;

Expand All @@ -493,7 +482,7 @@ void DS_SFX_Listener(int prop, float value)
case SFXLP_DOPPLER:
dopplerScale = value;
fmodSystem->set3DSettings(dopplerScale, unitsPerMeter, 1.0f);
DSFMOD_TRACE("SFX_Listener: Doppler = " << value);
DSFMOD_TRACE("SFX_Listener: Doppler factor = " << value);
break;

case SFXLP_UPDATE:
Expand All @@ -515,20 +504,17 @@ void DS_SFX_Listenerv(int prop, float* values)
switch(prop)
{
case SFXLP_POSITION:
listener.position.x = values[0];
listener.position.y = values[1];
listener.position.z = values[2];
listener.position.set(values);
//DSFMOD_TRACE("Pos:" << values[0] << "," << values[1] << "," << values[2]);
break;

case SFXLP_ORIENTATION:
// Convert the angles to front and up vectors.
listener.setOrientation(values[0], values[1]);
listener.setOrientation(values[0]/180*M_PI, values[1]/180*M_PI);
break;

case SFXLP_VELOCITY:
listener.velocity.x = values[0];
listener.velocity.y = values[1];
listener.velocity.z = values[2];
listener.velocity.set(values);
break;

case SFXLP_REVERB:
Expand Down
18 changes: 18 additions & 0 deletions doomsday/plugins/fmod/src/fmod_util.cpp
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2011 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/


0 comments on commit 22a3036

Please sign in to comment.