Compare commits

...

9 Commits

Author SHA1 Message Date
mfranz
46a32dd3ee coding style fixes 2007-07-22 13:58:26 +00:00
mfranz
ecb4dc57b4 Maik JUSTUS: workaround for broken Doppler effect in OpenAL
mf: this patch is meant to be removed as soon as OpenAL got fixed. (The
    OpenAL developers acknowleged the bug and announced that it'll get
    fixed.) For removal try
    $ cd simgear/sound
    $ cvs diff -rAFTER_OPENAL_DOPPLER_WORKAROUND -rBEFORE_OPENAL_DOPPLER_WORKAROUND|patch
2007-07-22 13:50:24 +00:00
mfranz
89d426470b Maik JUSTUS: Doppler fixes (add option to turn off Doppler for sounds that
shouldn't be affected -- marker beep, ATIS messages, etc.)

mf: this is the first part of the original patch. It is supposed to contain
    fixes that are not caused by OpenAL bugs, and thus aren't meant to be
    reverted later. The second part will contain a temprary workaround for
    OpenAL bugs. Unfortunately, I had to do the split myself as the contributor
    refused to do it.
2007-07-22 13:33:23 +00:00
mfranz
23c7a1b5b7 - close loophole through which one could sneak in illegal property names
containing slashes, colons and all sorts of evil characters. In Nasal
  this could be done via props.globals.getChild("1!@#$//[]{}", 0, 1).setValue(0);
  The cause is that getChild() hands the given name directly over to an
  alternative SGPropertyNode ("convenience") constructor which sets the
  name without any checks.
- unify exception messages: first character is lower case
2007-07-17 14:52:51 +00:00
frohlich
3b21e9434f Modified Files:
simgear/route/route.hxx: Remove unused include.
2007-07-08 08:43:40 +00:00
frohlich
d4a4428e64 Modified Files:
simgear/route/waypoint.hxx simgear/route/waypoint.cxx: Use const
	refs where possible.
2007-07-08 08:43:15 +00:00
mfranz
2dfc057135 replace exit() by throw sg_exception(). Of course, we have to be aware
that interdependencies between sg libs are generally unwelcome, but
sg_exception is a rather basic part, and it's already used by xml, props,
scene, sound and, of course, structure. Since props and xml are core
libs, we can assume that sg_exceptions are available.  (OK'ed by Curt)
2007-07-02 15:42:19 +00:00
mfranz
a25eebef9b add SG_ORIGIN macro that expands to a string __FILE__":"__LINE__
Note that __LINE__ is a number and can't be directly used in string
context, which makes the macro worthwhile. (IMHO :-)
2007-07-02 12:55:10 +00:00
mfranz
741c4ca15a back out last changes (radar patch) 2007-06-29 22:45:37 +00:00
14 changed files with 175 additions and 53 deletions

View File

@@ -322,6 +322,9 @@ sglog()
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
#endif
#define SG_STRINGIFY(x) #x
#define SG_TOSTRING(x) SG_STRINGIFY(x)
#define SG_ORIGIN __FILE__ ":" SG_TOSTRING(__LINE__)
#endif // _LOGSTREAM_H

View File

@@ -1,9 +1,6 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
// Minor changes/additions by Vivian Meazza Apr- May 2007
//
// Ported to OSG by Tim Moore Jun 2007
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
@@ -334,7 +331,7 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
}
}
void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family, float dist, int cloudId) {
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
// send data to wx radar
// compute turbulence
// draw precipitation
@@ -409,7 +406,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
// add to the list for the wxRadar instrument
if( LWC > 0.0 )
radarEcho.push_back( SGWxRadarEcho ( bearing, alt, radius, dist, 0.0 , LWC, false, cloudId, false ) );
radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
// NB:data valid only from cockpit view
@@ -422,7 +419,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
orig.setlon(last_lon * SG_DEGREES_TO_RADIANS );
orig.setelev(0.0);
dist = sgSqrt(dist);
dest = calc_gc_lon_lat(orig, bearing, dist);
dest = calc_gc_lon_lat(orig, heading, dist);
lon = dest.lon() * SG_RADIANS_TO_DEGREES;
lat = dest.lat() * SG_RADIANS_TO_DEGREES;
addLightning( lon, lat, alt );
@@ -714,7 +711,7 @@ void SGLightning::lt_Render(void) {
glTranslatef( ax, ay, -sgEnviro.last_alt );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, 0.0, age, true, 0, false ) );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
for( int n = 0 ; n < nb_tree ; n++ ) {
if( lt_tree[n].prev < 0 )

View File

@@ -1,9 +1,6 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
// Minor changes/additions by Vivian Meazza Apr- May 2007
//
// Ported to OSG by Tim Moore Jun 2007
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
@@ -43,32 +40,24 @@ class SGSoundMgr;
*/
class SGWxRadarEcho {
public:
SGWxRadarEcho(float _bearing, float _alt, float _radius, float _dist, float _heading,
double _LWC, bool _lightning, int _cloudId, bool _aircraft) :
bearing (_bearing),
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist,
double _LWC, bool _lightning, int _cloudId ) :
heading( _heading ),
alt ( _alt ),
radius ( _radius ),
dist ( _dist ),
LWC ( _LWC ),
lightning ( _lightning ),
aircraft ( _aircraft ),
cloudId ( _cloudId )
{}
/** the heading and bearing in radian are versus north */
float bearing, heading;
/** the heading in radian is versus north */
float heading;
float alt, radius, dist;
/** reflectivity converted to liquid water content. */
double LWC;
/** if true then this data is for a lightning else it is for water echo. */
bool lightning;
/** if true then this data is for an aircraft */
bool aircraft;
bool lightning;
/** Unique identifier of cloud */
int cloudId;
};

View File

@@ -116,7 +116,7 @@ parse_name (const string &path, int &i)
name = ".";
}
if (i < max && path[i] != '/')
throw string("Illegal character after " + name);
throw string("illegal character after " + name);
}
else if (isalpha(path[i]) || path[i] == '_') {
@@ -295,7 +295,7 @@ find_node (SGPropertyNode * current,
else if (components[position].name == "..") {
SGPropertyNode * parent = current->getParent();
if (parent == 0)
throw string("Attempt to move past root with '..'");
throw string("attempt to move past root with '..'");
else
return find_node(parent, components, position + 1, create);
}
@@ -739,7 +739,11 @@ SGPropertyNode::SGPropertyNode (const char * name,
_attr(READ|WRITE),
_listeners(0)
{
_name = name;
int i = 0;
_name = parse_name(name, i);
if (i != int(strlen(name)) || name[0] == '.')
throw string("plain name expected instead of '") + name + '\'';
_local_val.string_val = 0;
}

View File

@@ -32,13 +32,10 @@
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include STL_STRING
#include <vector>
SG_USING_STD(string);
SG_USING_STD(vector);
#include <simgear/route/waypoint.hxx>

View File

@@ -32,7 +32,7 @@
// Constructor
SGWayPoint::SGWayPoint( const double lon, const double lat, const double alt,
const modetype m, const string s, const string n ) {
const modetype m, const string& s, const string& n ) {
target_lon = lon;
target_lat = lat;
target_alt = alt;

View File

@@ -91,7 +91,7 @@ public:
*/
SGWayPoint( const double lon = 0.0, const double lat = 0.0,
const double alt = 0.0, const modetype m = WGS84,
const string s = "", const string n = "" );
const string& s = "", const string& n = "" );
/** Destructor */
~SGWayPoint();

View File

@@ -75,12 +75,17 @@ SGSoundSample::SGSoundSample() :
reference_dist(500.0),
max_dist(3000.),
loop(AL_FALSE),
playing(false)
#ifdef USE_SOFTWARE_DOPPLER
doppler_pitch_factor(1),
doppler_volume_factor(1),
#endif
playing(false),
no_Doppler_effect(true)
{
}
// constructor
SGSoundSample::SGSoundSample( const char *path, const char *file) :
SGSoundSample::SGSoundSample( const char *path, const char *file, bool _no_Doppler_effect ) :
buffer(0),
source(0),
pitch(1.0),
@@ -88,7 +93,12 @@ SGSoundSample::SGSoundSample( const char *path, const char *file) :
reference_dist(500.0),
max_dist(3000.),
loop(AL_FALSE),
playing(false)
#ifdef USE_SOFTWARE_DOPPLER
doppler_pitch_factor(1),
doppler_volume_factor(1),
#endif
playing(false),
no_Doppler_effect(_no_Doppler_effect)
{
SGPath samplepath( path );
if ( strlen(file) ) {
@@ -145,7 +155,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file) :
}
// constructor
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) :
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq, bool _no_Doppler_effect ) :
buffer(0),
source(0),
pitch(1.0),
@@ -153,7 +163,12 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) :
reference_dist(500.0),
max_dist(3000.),
loop(AL_FALSE),
playing(false)
#ifdef USE_SOFTWARE_DOPPLER
doppler_pitch_factor(1),
doppler_volume_factor(1),
#endif
playing(false),
no_Doppler_effect(_no_Doppler_effect)
{
SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" );
@@ -247,14 +262,23 @@ SGSoundSample::bind_source() {
}
alSourcei( source, AL_BUFFER, buffer );
#ifndef USE_SOFTWARE_DOPPLER
alSourcef( source, AL_PITCH, pitch );
alSourcef( source, AL_GAIN, volume );
#else
print_openal_error("bind_sources return");
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
alGetError(); // ignore if the pitch is clamped by the driver
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
#endif
alSourcefv( source, AL_POSITION, source_pos );
alSourcefv( source, AL_DIRECTION, direction );
alSourcef( source, AL_CONE_INNER_ANGLE, inner );
alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
alSourcef( source, AL_CONE_OUTER_GAIN, outergain);
#ifdef USE_OPEN_AL_DOPPLER
alSourcefv( source, AL_VELOCITY, source_vel );
#endif
alSourcei( source, AL_LOOPING, loop );
alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
@@ -273,8 +297,13 @@ SGSoundSample::set_pitch( double p ) {
if ( p > 2.0 ) { p = 2.0; }
pitch = p;
if (playing) {
#ifndef USE_SOFTWARE_DOPPLER
alSourcef( source, AL_PITCH, pitch );
print_openal_error("set_pitch");
#else
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
alGetError(); // ignore if the pitch is clamped by the driver
#endif
}
}
@@ -282,7 +311,11 @@ void
SGSoundSample::set_volume( double v ) {
volume = v;
if (playing) {
#ifndef USE_SOFTWARE_DOPPLER
alSourcef( source, AL_GAIN, volume );
#else
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
#endif
print_openal_error("set_volume");
}
}
@@ -313,6 +346,7 @@ SGSoundSample::set_source_pos( ALfloat *pos ) {
sgAddVec3( final_pos, source_pos, offset_pos );
alSourcefv( source, AL_POSITION, final_pos );
print_openal_error("set_source_pos");
}
}
@@ -327,6 +361,7 @@ SGSoundSample::set_offset_pos( ALfloat *pos ) {
sgAddVec3( final_pos, source_pos, offset_pos );
alSourcefv( source, AL_POSITION, final_pos );
print_openal_error("set_offset_pos");
}
}
@@ -350,13 +385,85 @@ SGSoundSample::set_orientation( ALfloat *dir, ALfloat inner_angle,
}
void
SGSoundSample::set_source_vel( ALfloat *vel ) {
source_vel[0] = vel[0];
source_vel[1] = vel[1];
source_vel[2] = vel[2];
SGSoundSample::set_source_vel( ALfloat *vel, ALfloat *listener_vel ) {
if (no_Doppler_effect) {
source_vel[0] = listener_vel[0];
source_vel[1] = listener_vel[1];
source_vel[2] = listener_vel[2];
} else {
source_vel[0] = vel[0];
source_vel[1] = vel[1];
source_vel[2] = vel[2];
}
#ifdef USE_OPEN_AL_DOPPLER
if (playing) {
alSourcefv( source, AL_VELOCITY, source_vel );
}
#elif defined (USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER)
if (playing) {
sgVec3 relative_vel;
sgSubVec3( relative_vel, source_vel, listener_vel );
alSourcefv( source, AL_VELOCITY, relative_vel );
}
#else
if (no_Doppler_effect) {
doppler_pitch_factor = 1;
doppler_volume_factor = 1;
return;
}
double doppler, mfp;
sgVec3 final_pos;
sgAddVec3( final_pos, source_pos, offset_pos );
mfp = sgLengthVec3(final_pos);
if (mfp > 1e-6) {
double vls = -sgScalarProductVec3( listener_vel, final_pos ) / mfp;
double vss = -sgScalarProductVec3( source_vel, final_pos ) / mfp;
if (fabs(340 - vss) > 1e-6)
{
doppler = (340 - vls) / (340 - vss);
doppler = ( doppler > 0) ? ( ( doppler < 10) ? doppler : 10 ) : 0;
}
else
doppler = 0;
}
else
doppler = 1;
/* the OpenAL documentation of the Doppler calculation
SS: AL_SPEED_OF_SOUND = speed of sound (default value 343.3)
DF: AL_DOPPLER_FACTOR = Doppler factor (default 1.0)
vls: Listener velocity scalar (scalar, projected on source-to-listener vector)
vss: Source velocity scalar (scalar, projected on source-to-listener vector)
SL = source to listener vector
SV = Source Velocity vector
LV = Listener Velocity vector
vls = DotProduct(SL, LV) / Mag(SL)
vss = DotProduct(SL, SV) / Mag(SL)
Dopper Calculation:
vss = min(vss, SS/DF)
vls = min(vls, SS/DF)
f' = f * (SS - DF*vls) / (SS - DF*vss)
*/
if (doppler > 0.1) {
if (doppler < 10) {
doppler_pitch_factor = doppler;
doppler_volume_factor = 1;
}
else {
doppler_pitch_factor = (doppler < 11) ? doppler : 11;
doppler_volume_factor = (doppler < 11) ? 11-doppler : 0;
}
}
else {
doppler_pitch_factor = 0.1;
doppler_volume_factor = (doppler > 0) ? doppler * 10 : 0;
}
if (playing) {
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
print_openal_error("set_source_vel: volume");
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
alGetError(); //ignore if the pitch is clamped
}
#endif
}
void

View File

@@ -52,6 +52,17 @@
# include <AL/alut.h>
#endif
#ifndef HAVE_WINDOWS_H
#ifdef AL_VERSION_1_2
#define USE_OPEN_AL_DOPPLER should work
#else
#define USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER better than nothing
#endif
#else
// the Open_AL Doppler calculation seems to be buggy on windows
#define USE_SOFTWARE_DOPPLER seem to be necessary
#endif
SG_USING_STD(string);
/**
@@ -90,12 +101,17 @@ private:
double pitch;
double volume;
#ifdef USE_SOFTWARE_DOPPLER
double doppler_pitch_factor;
double doppler_volume_factor;
#endif
double reference_dist;
double max_dist;
ALboolean loop;
bool playing;
bool bind_source();
bool no_Doppler_effect;
public:
@@ -112,7 +128,7 @@ public:
should usually be true unless you want to manipulate the data
later.)
*/
SGSoundSample( const char *path, const char *file );
SGSoundSample( const char *path, const char *file, bool no_Doppler_effect = true );
/**
* Constructor.
@@ -123,7 +139,7 @@ public:
should usually be true unless you want to manipulate the data
later.)
*/
SGSoundSample( unsigned char *_data, int len, int _freq );
SGSoundSample( unsigned char *_data, int len, int _freq, bool no_Doppler_effect = true );
~SGSoundSample();
@@ -208,7 +224,7 @@ public:
/**
* Set velocity of sound source (uses same coordinate system as opengl)
*/
void set_source_vel( ALfloat *vel );
void set_source_vel( ALfloat *vel, ALfloat *listener_vel );
/**

View File

@@ -345,6 +345,6 @@ void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
sample_map_iterator sample_end = samples.end();
for ( ; sample_current != sample_end; ++sample_current ) {
SGSoundSample *sample = sample_current->second;
sample->set_source_vel( vel );
sample->set_source_vel( vel, listener_vel );
}
}

View File

@@ -206,7 +206,9 @@ public:
listener_vel[0] = vel[0];
listener_vel[1] = vel[1];
listener_vel[2] = vel[2];
#ifdef USE_OPEN_AL_DOPPLER
alListenerfv( AL_VELOCITY, listener_vel );
#endif
}
/**

View File

@@ -272,7 +272,8 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node, SGSoundMgr *sndmgr,
// "alSource". The semantics of what is going on here seems
// confused and needs to be thought through more carefully.
_sample = new SGSoundSample( path.c_str(),
node->getStringValue("path", "") );
node->getStringValue("path", ""),
false );
_mgr->add( _sample, _name );
}

View File

@@ -40,6 +40,9 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <simgear/structure/exception.hxx>
#include "lowleveltime.h"
@@ -331,19 +334,18 @@ static void fgtzset_internal (int always, const char *tz)
fgtzfile_read (tz);
if (use_fgtzfile)
return;
// The default behaviour of the originale tzset_internal (int always, char* tz)
// function is to set up a default timezone, in any casetz file_read() fails
// Currently this leads to problems, because it modidifies the system timezone
// The default behaviour of the original tzset_internal (int always, char* tz)
// function is to set up a default timezone, in any case file_read() fails
// Currently this leads to problems, because it modifies the system timezone
// and not the local aircraft timezone, contained in FlightGear. I could adapt
// this in future versions of this code, but doubt whether this is what we really
// want. So right now, exit when timezone information reading failed.
// want. So right now, throw an exception when timezone information reading failed.
// Guess I'll change that to something like 12 * (FG_LON / 180.0)
//
// For now, I'll leave it like this.
else
{
printf ("Timezone reading failed\n");
exit(1);
throw sg_exception("Timezone reading failed");
}
// this emacs "comment out" function is cool!

View File

@@ -29,6 +29,9 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <simgear/structure/exception.hxx>
#include "timezone.h"
SGTimeZone::SGTimeZone(float la, float lo, char* cc, char* desc) :
@@ -126,8 +129,9 @@ SGTimeZoneContainer::SGTimeZoneContainer(const char *filename)
char buffer[256];
FILE* infile = fopen(filename, "rb");
if (!(infile)) {
fprintf(stderr, "Unable to open file %s\n", filename);
exit(1);
string e = "Unable to open time zone file '";
throw sg_exception(e + filename + '\'');
} else {
errno = 0;