Added marker beacon sound effects.
This commit is contained in:
parent
7aa5e0a4eb
commit
2e8f9f7399
10 changed files with 340 additions and 215 deletions
|
@ -102,6 +102,7 @@ void
|
||||||
FGRadioStack::init ()
|
FGRadioStack::init ()
|
||||||
{
|
{
|
||||||
morse.init();
|
morse.init();
|
||||||
|
beacon.init();
|
||||||
|
|
||||||
search();
|
search();
|
||||||
update();
|
update();
|
||||||
|
@ -550,6 +551,8 @@ FGRadioStack::update()
|
||||||
// Update current nav/adf radio stations based on current postition
|
// Update current nav/adf radio stations based on current postition
|
||||||
void FGRadioStack::search()
|
void FGRadioStack::search()
|
||||||
{
|
{
|
||||||
|
static FGMkrBeacon::fgMkrBeacType last_beacon = FGMkrBeacon::NOBEACON;
|
||||||
|
|
||||||
double lon = longitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
|
double lon = longitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
|
||||||
double lat = latitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
|
double lat = latitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
|
||||||
double elev = altitudeVal->getDoubleValue() * SG_FEET_TO_METER;
|
double elev = altitudeVal->getDoubleValue() * SG_FEET_TO_METER;
|
||||||
|
@ -806,21 +809,58 @@ void FGRadioStack::search()
|
||||||
// cout << "not picking up vor1. :-(" << endl;
|
// cout << "not picking up vor1. :-(" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGBeacon::fgMkrBeacType beacon_type
|
FGMkrBeacon::fgMkrBeacType beacon_type
|
||||||
= current_beacons->query( lon * SGD_RADIANS_TO_DEGREES, lat * SGD_RADIANS_TO_DEGREES, elev );
|
= current_beacons->query( lon * SGD_RADIANS_TO_DEGREES,
|
||||||
|
lat * SGD_RADIANS_TO_DEGREES, elev );
|
||||||
|
|
||||||
outer_marker = middle_marker = inner_marker = false;
|
outer_marker = middle_marker = inner_marker = false;
|
||||||
|
|
||||||
if ( beacon_type == FGBeacon::OUTER ) {
|
if ( beacon_type == FGMkrBeacon::OUTER ) {
|
||||||
outer_marker = true;
|
outer_marker = true;
|
||||||
cout << "OUTER MARKER" << endl;
|
cout << "OUTER MARKER" << endl;
|
||||||
} else if ( beacon_type == FGBeacon::MIDDLE ) {
|
if ( last_beacon != FGMkrBeacon::OUTER ) {
|
||||||
|
if ( ! globals->get_soundmgr()->exists( "outer-marker" ) ) {
|
||||||
|
FGSimpleSound *sound = beacon.get_outer();
|
||||||
|
sound->set_volume( 0.3 );
|
||||||
|
globals->get_soundmgr()->add( sound, "outer-marker" );
|
||||||
|
}
|
||||||
|
if ( !globals->get_soundmgr()->is_playing("outer-marker") ) {
|
||||||
|
globals->get_soundmgr()->play_looped( "outer-marker" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( beacon_type == FGMkrBeacon::MIDDLE ) {
|
||||||
middle_marker = true;
|
middle_marker = true;
|
||||||
cout << "MIDDLE MARKER" << endl;
|
cout << "MIDDLE MARKER" << endl;
|
||||||
} else if ( beacon_type == FGBeacon::INNER ) {
|
if ( last_beacon != FGMkrBeacon::MIDDLE ) {
|
||||||
|
if ( ! globals->get_soundmgr()->exists( "middle-marker" ) ) {
|
||||||
|
FGSimpleSound *sound = beacon.get_middle();
|
||||||
|
sound->set_volume( 0.3 );
|
||||||
|
globals->get_soundmgr()->add( sound, "middle-marker" );
|
||||||
|
}
|
||||||
|
if ( !globals->get_soundmgr()->is_playing("middle-marker") ) {
|
||||||
|
globals->get_soundmgr()->play_looped( "middle-marker" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ( beacon_type == FGMkrBeacon::INNER ) {
|
||||||
inner_marker = true;
|
inner_marker = true;
|
||||||
cout << "INNER MARKER" << endl;
|
cout << "INNER MARKER" << endl;
|
||||||
|
if ( last_beacon != FGMkrBeacon::INNER ) {
|
||||||
|
if ( ! globals->get_soundmgr()->exists( "inner-marker" ) ) {
|
||||||
|
FGSimpleSound *sound = beacon.get_inner();
|
||||||
|
sound->set_volume( 0.3 );
|
||||||
|
globals->get_soundmgr()->add( sound, "inner-marker" );
|
||||||
|
}
|
||||||
|
if ( !globals->get_soundmgr()->is_playing("inner-marker") ) {
|
||||||
|
globals->get_soundmgr()->play_looped( "inner-marker" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cout << "no marker" << endl;
|
||||||
|
globals->get_soundmgr()->stop( "outer-marker" );
|
||||||
|
globals->get_soundmgr()->stop( "middle-marker" );
|
||||||
|
globals->get_soundmgr()->stop( "inner-marker" );
|
||||||
}
|
}
|
||||||
|
last_beacon = beacon_type;
|
||||||
|
|
||||||
// adf
|
// adf
|
||||||
if ( current_navlist->query( lon, lat, elev, adf_freq, &nav ) ) {
|
if ( current_navlist->query( lon, lat, elev, adf_freq, &nav ) ) {
|
||||||
|
|
|
@ -34,11 +34,13 @@
|
||||||
|
|
||||||
#include <Navaids/ilslist.hxx>
|
#include <Navaids/ilslist.hxx>
|
||||||
#include <Navaids/navlist.hxx>
|
#include <Navaids/navlist.hxx>
|
||||||
|
#include <Sound/beacon.hxx>
|
||||||
#include <Sound/morse.hxx>
|
#include <Sound/morse.hxx>
|
||||||
|
|
||||||
|
|
||||||
class FGRadioStack : public FGSubsystem
|
class FGRadioStack : public FGSubsystem
|
||||||
{
|
{
|
||||||
|
FGBeacon beacon;
|
||||||
FGMorse morse;
|
FGMorse morse;
|
||||||
|
|
||||||
SGInterpTable *term_tbl;
|
SGInterpTable *term_tbl;
|
||||||
|
|
|
@ -101,17 +101,17 @@ bool FGILSList::init( SGPath path ) {
|
||||||
if ( fabs(ils.get_omlon()) > SG_EPSILON ||
|
if ( fabs(ils.get_omlon()) > SG_EPSILON ||
|
||||||
fabs(ils.get_omlat()) > SG_EPSILON ) {
|
fabs(ils.get_omlat()) > SG_EPSILON ) {
|
||||||
current_beacons->add( ils.get_omlon(), ils.get_omlat(),
|
current_beacons->add( ils.get_omlon(), ils.get_omlat(),
|
||||||
ils.get_gselev(), FGBeacon::OUTER );
|
ils.get_gselev(), FGMkrBeacon::OUTER );
|
||||||
}
|
}
|
||||||
if ( fabs(ils.get_mmlon()) > SG_EPSILON ||
|
if ( fabs(ils.get_mmlon()) > SG_EPSILON ||
|
||||||
fabs(ils.get_mmlat()) > SG_EPSILON ) {
|
fabs(ils.get_mmlat()) > SG_EPSILON ) {
|
||||||
current_beacons->add( ils.get_mmlon(), ils.get_mmlat(),
|
current_beacons->add( ils.get_mmlon(), ils.get_mmlat(),
|
||||||
ils.get_gselev(), FGBeacon::MIDDLE );
|
ils.get_gselev(), FGMkrBeacon::MIDDLE );
|
||||||
}
|
}
|
||||||
if ( fabs(ils.get_imlon()) > SG_EPSILON ||
|
if ( fabs(ils.get_imlon()) > SG_EPSILON ||
|
||||||
fabs(ils.get_imlat()) > SG_EPSILON ) {
|
fabs(ils.get_imlat()) > SG_EPSILON ) {
|
||||||
current_beacons->add( ils.get_imlon(), ils.get_imlat(),
|
current_beacons->add( ils.get_imlon(), ils.get_imlat(),
|
||||||
ils.get_gselev(), FGBeacon::INNER );
|
ils.get_gselev(), FGMkrBeacon::INNER );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
FGBeacon::FGBeacon() {
|
FGMkrBeacon::FGMkrBeacon() {
|
||||||
FGBeacon( 0, 0, 0, NOBEACON );
|
FGMkrBeacon( 0, 0, 0, NOBEACON );
|
||||||
}
|
}
|
||||||
|
|
||||||
FGBeacon::FGBeacon( double _lon, double _lat, double _elev,
|
FGMkrBeacon::FGMkrBeacon( double _lon, double _lat, double _elev,
|
||||||
fgMkrBeacType _type ) {
|
fgMkrBeacType _type ) {
|
||||||
lon = _lon;
|
lon = _lon;
|
||||||
lat = _lat;
|
lat = _lat;
|
||||||
|
@ -44,7 +44,7 @@ FGBeacon::FGBeacon( double _lon, double _lat, double _elev,
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
FGBeacon::~FGBeacon() {
|
FGMkrBeacon::~FGMkrBeacon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ bool FGMarkerBeacons::init() {
|
||||||
|
|
||||||
|
|
||||||
// real add a marker beacon
|
// real add a marker beacon
|
||||||
bool FGMarkerBeacons::real_add( const int master_index, const FGBeacon& b ) {
|
bool FGMarkerBeacons::real_add( const int master_index, const FGMkrBeacon& b ) {
|
||||||
// cout << "Master index = " << master_index << endl;
|
// cout << "Master index = " << master_index << endl;
|
||||||
beacon_map[master_index].push_back( b );
|
beacon_map[master_index].push_back( b );
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ bool FGMarkerBeacons::real_add( const int master_index, const FGBeacon& b ) {
|
||||||
|
|
||||||
// front end for add a marker beacon
|
// front end for add a marker beacon
|
||||||
bool FGMarkerBeacons::add( double lon, double lat, double elev,
|
bool FGMarkerBeacons::add( double lon, double lat, double elev,
|
||||||
FGBeacon::fgMkrBeacType type ) {
|
FGMkrBeacon::fgMkrBeacType type ) {
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
int lonidx = (int)lon;
|
int lonidx = (int)lon;
|
||||||
|
@ -97,7 +97,7 @@ bool FGMarkerBeacons::add( double lon, double lat, double elev,
|
||||||
latidx += 90;
|
latidx += 90;
|
||||||
|
|
||||||
int master_index = lonidx * 1000 + latidx;
|
int master_index = lonidx * 1000 + latidx;
|
||||||
FGBeacon b( lon, lat, elev, type );
|
FGMkrBeacon b( lon, lat, elev, type );
|
||||||
|
|
||||||
// add to the actual bucket
|
// add to the actual bucket
|
||||||
real_add( master_index, b );
|
real_add( master_index, b );
|
||||||
|
@ -133,7 +133,7 @@ bool FGMarkerBeacons::add( double lon, double lat, double elev,
|
||||||
|
|
||||||
// returns marker beacon type if we are over a marker beacon, NOBEACON
|
// returns marker beacon type if we are over a marker beacon, NOBEACON
|
||||||
// otherwise
|
// otherwise
|
||||||
FGBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
|
FGMkrBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
|
||||||
double elev ) {
|
double elev ) {
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ FGBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
|
||||||
cout << "lon = " << lon << " lat = " << lat
|
cout << "lon = " << lon << " lat = " << lat
|
||||||
<< " closest beacon = " << sqrt( min_dist ) << endl;
|
<< " closest beacon = " << sqrt( min_dist ) << endl;
|
||||||
|
|
||||||
return FGBeacon::NOBEACON;
|
return FGMkrBeacon::NOBEACON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ SG_USING_STD(map);
|
||||||
SG_USING_STD(vector);
|
SG_USING_STD(vector);
|
||||||
|
|
||||||
|
|
||||||
class FGBeacon {
|
class FGMkrBeacon {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FGBeacon();
|
FGMkrBeacon();
|
||||||
FGBeacon( double _lon, double _lat, double _elev, fgMkrBeacType _type );
|
FGMkrBeacon( double _lon, double _lat, double _elev, fgMkrBeacType _type );
|
||||||
~FGBeacon();
|
~FGMkrBeacon();
|
||||||
|
|
||||||
inline double get_elev() const { return elev; }
|
inline double get_elev() const { return elev; }
|
||||||
inline fgMkrBeacType get_type() const { return type; }
|
inline fgMkrBeacType get_type() const { return type; }
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
class FGMarkerBeacons {
|
class FGMarkerBeacons {
|
||||||
|
|
||||||
// convenience types
|
// convenience types
|
||||||
typedef vector < FGBeacon > beacon_list_type;
|
typedef vector < FGMkrBeacon > beacon_list_type;
|
||||||
typedef beacon_list_type::iterator beacon_list_iterator;
|
typedef beacon_list_type::iterator beacon_list_iterator;
|
||||||
typedef beacon_list_type::const_iterator beacon_list_const_iterator;
|
typedef beacon_list_type::const_iterator beacon_list_const_iterator;
|
||||||
|
|
||||||
|
@ -86,7 +86,8 @@ class FGMarkerBeacons {
|
||||||
beacon_map_type beacon_map;
|
beacon_map_type beacon_map;
|
||||||
|
|
||||||
// real add a marker beacon
|
// real add a marker beacon
|
||||||
bool FGMarkerBeacons::real_add( const int master_index, const FGBeacon& b );
|
bool FGMarkerBeacons::real_add( const int master_index,
|
||||||
|
const FGMkrBeacon& b );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -98,11 +99,11 @@ public:
|
||||||
|
|
||||||
// add a marker beacon
|
// add a marker beacon
|
||||||
bool add( double lon, double lat, double elev,
|
bool add( double lon, double lat, double elev,
|
||||||
FGBeacon::fgMkrBeacType type );
|
FGMkrBeacon::fgMkrBeacType type );
|
||||||
|
|
||||||
// returns marker beacon type if we are over a marker beacon, NOBEACON
|
// returns marker beacon type if we are over a marker beacon, NOBEACON
|
||||||
// otherwise
|
// otherwise
|
||||||
FGBeacon::fgMkrBeacType query( double lon, double lat, double elev );
|
FGMkrBeacon::fgMkrBeacType query( double lon, double lat, double elev );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
noinst_LIBRARIES = libSound.a
|
noinst_LIBRARIES = libSound.a
|
||||||
|
|
||||||
libSound_a_SOURCES = \
|
libSound_a_SOURCES = \
|
||||||
|
beacon.cxx beacon.hxx \
|
||||||
morse.cxx morse.hxx \
|
morse.cxx morse.hxx \
|
||||||
soundmgr.cxx soundmgr.hxx
|
soundmgr.cxx soundmgr.hxx
|
||||||
|
|
||||||
|
|
88
src/Sound/beacon.cxx
Normal file
88
src/Sound/beacon.cxx
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// beacon.cxx -- Morse code generation class
|
||||||
|
//
|
||||||
|
// Written by Curtis Olson, started March 2001.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
|
#include "beacon.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
FGBeacon::FGBeacon() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
FGBeacon::~FGBeacon() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// allocate and initialize sound samples
|
||||||
|
bool FGBeacon::init() {
|
||||||
|
int i;
|
||||||
|
int len;
|
||||||
|
unsigned char *ptr;
|
||||||
|
|
||||||
|
// Make inner marker beacon sound
|
||||||
|
len= (int)(INNER_DIT_LEN / 2.0 );
|
||||||
|
unsigned char inner_dit[INNER_DIT_LEN];
|
||||||
|
make_tone( inner_dit, INNER_FREQ, len, INNER_DIT_LEN,
|
||||||
|
TRANSITION_BYTES );
|
||||||
|
|
||||||
|
ptr = inner_buf;
|
||||||
|
for ( i = 0; i < 6; ++i ) {
|
||||||
|
memcpy( ptr, inner_dit, INNER_DIT_LEN );
|
||||||
|
ptr += INNER_DIT_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
inner = new FGSimpleSound( inner_buf, INNER_SIZE );
|
||||||
|
|
||||||
|
// Make middle marker beacon sound
|
||||||
|
len= (int)(MIDDLE_DIT_LEN / 2.0 );
|
||||||
|
unsigned char middle_dit[MIDDLE_DIT_LEN];
|
||||||
|
make_tone( middle_dit, MIDDLE_FREQ, len, MIDDLE_DIT_LEN,
|
||||||
|
TRANSITION_BYTES );
|
||||||
|
|
||||||
|
len= (int)(MIDDLE_DAH_LEN * 3 / 4.0 );
|
||||||
|
unsigned char middle_dah[MIDDLE_DAH_LEN];
|
||||||
|
make_tone( middle_dah, MIDDLE_FREQ, len, MIDDLE_DAH_LEN,
|
||||||
|
TRANSITION_BYTES );
|
||||||
|
|
||||||
|
ptr = middle_buf;
|
||||||
|
memcpy( ptr, middle_dit, MIDDLE_DIT_LEN );
|
||||||
|
ptr += MIDDLE_DIT_LEN;
|
||||||
|
memcpy( ptr, middle_dah, MIDDLE_DAH_LEN );
|
||||||
|
|
||||||
|
middle = new FGSimpleSound( middle_buf, MIDDLE_SIZE );
|
||||||
|
|
||||||
|
// Make outer marker beacon sound
|
||||||
|
len= (int)(OUTER_DAH_LEN * 3.0 / 4.0 );
|
||||||
|
unsigned char outer_dah[OUTER_DAH_LEN];
|
||||||
|
make_tone( outer_dah, OUTER_FREQ, len, OUTER_DAH_LEN,
|
||||||
|
TRANSITION_BYTES );
|
||||||
|
|
||||||
|
ptr = outer_buf;
|
||||||
|
memcpy( ptr, outer_dah, OUTER_DAH_LEN );
|
||||||
|
ptr += OUTER_DAH_LEN;
|
||||||
|
memcpy( ptr, outer_dah, OUTER_DAH_LEN );
|
||||||
|
|
||||||
|
outer = new FGSimpleSound( outer_buf, OUTER_SIZE );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
125
src/Sound/beacon.hxx
Normal file
125
src/Sound/beacon.hxx
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* \file beacon.hxx -- Provides marker beacon audio generation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Written by Curtis Olson, started March 2001.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
|
||||||
|
//
|
||||||
|
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _BEACON_HXX
|
||||||
|
#define _BEACON_HXX
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <plib/sl.h>
|
||||||
|
#include <plib/sm.h>
|
||||||
|
|
||||||
|
#include "morse.hxx"
|
||||||
|
#include "soundmgr.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
// Quoting from http://www.smartregs.com/data/sa326.htm
|
||||||
|
// Smart REGS Glossary - marker beacon
|
||||||
|
//
|
||||||
|
// An electronic navigation facility transmitting a 75 MHz vertical fan
|
||||||
|
// or boneshaped radiation pattern. Marker beacons are identified by
|
||||||
|
// their modulation frequency and keying code, and when received by
|
||||||
|
// compatible airborne equipment, indicate to the pilot, both aurally
|
||||||
|
// and visually, that he is passing over the facility.
|
||||||
|
// (See outer marker middle marker inner marker.)
|
||||||
|
//
|
||||||
|
// Smart REGS Glossary - outer marker
|
||||||
|
//
|
||||||
|
// A marker beacon at or near the glideslope intercept altitude of an
|
||||||
|
// ILS approach. It is keyed to transmit two dashes per second on a
|
||||||
|
// 400 Hz tone, which is received aurally and visually by compatible
|
||||||
|
// airborne equipment. The OM is normally located four to seven miles from
|
||||||
|
// the runway threshold on the extended centerline of the runway.
|
||||||
|
//
|
||||||
|
// Smart REGS Glossary - middle marker
|
||||||
|
//
|
||||||
|
// A marker beacon that defines a point along the glideslope of an
|
||||||
|
// ILS normally located at or near the point of decision height
|
||||||
|
// (ILS Category I). It is keyed to transmit alternate dots and dashes,
|
||||||
|
// with the alternate dots and dashes keyed at the rate of 95 dot/dash
|
||||||
|
// combinations per minute on a 1300 Hz tone, which is received
|
||||||
|
// aurally and visually by compatible airborne equipment.
|
||||||
|
//
|
||||||
|
// Smart REGS Glossary - inner marker
|
||||||
|
//
|
||||||
|
// A marker beacon used with an ILS (CAT II) precision approach located
|
||||||
|
// between the middle marker and the end of the ILS runway,
|
||||||
|
// transmitting a radiation pattern keyed at six dots per second and
|
||||||
|
// indicating to the pilot, both aurally and visually, that he is at
|
||||||
|
// the designated decision height (DH), normally 100 feet above the
|
||||||
|
// touchdown zone elevation, on the ILS CAT II approach. It also marks
|
||||||
|
// progress during a CAT III approach.
|
||||||
|
// (See instrument landing system) (Refer to AIM.)
|
||||||
|
|
||||||
|
|
||||||
|
static const int INNER_FREQ = 3000;
|
||||||
|
static const int MIDDLE_FREQ = 1300;
|
||||||
|
static const int OUTER_FREQ = 400;
|
||||||
|
|
||||||
|
static const int INNER_SIZE = BYTES_PER_SECOND;
|
||||||
|
static const int MIDDLE_SIZE = (int)(BYTES_PER_SECOND * 60 / 95 );
|
||||||
|
static const int OUTER_SIZE = BYTES_PER_SECOND;
|
||||||
|
|
||||||
|
static const int INNER_DIT_LEN = (int)(BYTES_PER_SECOND / 6.0);
|
||||||
|
static const int MIDDLE_DIT_LEN = (int)(MIDDLE_SIZE / 3.0);
|
||||||
|
static const int MIDDLE_DAH_LEN = (int)(MIDDLE_SIZE * 2 / 3.0);
|
||||||
|
static const int OUTER_DAH_LEN = (int)(BYTES_PER_SECOND / 2.0);
|
||||||
|
|
||||||
|
// manages everything we need to know for an individual sound sample
|
||||||
|
class FGBeacon {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned char inner_buf[ INNER_SIZE ] ;
|
||||||
|
unsigned char middle_buf[ MIDDLE_SIZE ] ;
|
||||||
|
unsigned char outer_buf[ OUTER_SIZE ] ;
|
||||||
|
|
||||||
|
FGSimpleSound *inner;
|
||||||
|
FGSimpleSound *middle;
|
||||||
|
FGSimpleSound *outer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FGBeacon();
|
||||||
|
~FGBeacon();
|
||||||
|
|
||||||
|
// allocate and initialize sound samples
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
FGSimpleSound *get_inner() { return inner; }
|
||||||
|
FGSimpleSound *get_middle() { return middle; }
|
||||||
|
FGSimpleSound *get_outer() { return outer; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _BEACON_HXX
|
||||||
|
|
||||||
|
|
|
@ -65,154 +65,64 @@ FGMorse::~FGMorse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// allocate and initialize sound samples
|
// Make a tone of specified freq and total_len with trans_len ramp in
|
||||||
bool FGMorse::init() {
|
// and out and only the first len bytes with sound, the rest with
|
||||||
|
// silence
|
||||||
|
void make_tone( unsigned char *buf, int freq,
|
||||||
|
int len, int total_len, int trans_len )
|
||||||
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
// Make Low DIT
|
for ( i = 0; i < trans_len; ++i ) {
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
* ((double)i / trans_len) / 2.0 + 0.5;
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
* ((double)i / TRANSITION_BYTES)
|
/* Convert to unsigned byte */
|
||||||
|
buf[ i ] = (unsigned char) ( level * 255.0 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = trans_len; i < len - trans_len; ++i ) {
|
||||||
|
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
||||||
/ 2.0 + 0.5;
|
/ 2.0 + 0.5;
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
/* Convert to unsigned byte */
|
||||||
lo_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
buf[ i ] = (unsigned char) ( level * 255.0 ) ;
|
||||||
}
|
}
|
||||||
|
j = trans_len;
|
||||||
for ( i = TRANSITION_BYTES;
|
for ( i = len - trans_len; i < len; ++i ) {
|
||||||
i < DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE; ++i ) {
|
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
* ((double)j / trans_len) / 2.0 + 0.5;
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
lo_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DIT_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
--j;
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
/* Convert to unsigned byte */
|
||||||
lo_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
buf[ i ] = (unsigned char) ( level * 255.0 ) ;
|
||||||
}
|
}
|
||||||
for ( i = DIT_SIZE - COUNT_SIZE; i < DIT_SIZE; ++i ) {
|
for ( i = len; i < total_len; ++i ) {
|
||||||
lo_dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
buf[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// allocate and initialize sound samples
|
||||||
|
bool FGMorse::init() {
|
||||||
|
// Make Low DIT
|
||||||
|
make_tone( lo_dit, LO_FREQUENCY, DIT_SIZE - COUNT_SIZE, DIT_SIZE,
|
||||||
|
TRANSITION_BYTES );
|
||||||
|
|
||||||
// Make High DIT
|
// Make High DIT
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
make_tone( hi_dit, HI_FREQUENCY, DIT_SIZE - COUNT_SIZE, DIT_SIZE,
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
TRANSITION_BYTES );
|
||||||
/ (8000.0 / HI_FREQUENCY)) )
|
|
||||||
* ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = TRANSITION_BYTES;
|
|
||||||
i < DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE; ++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / HI_FREQUENCY) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DIT_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / HI_FREQUENCY) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
for ( i = DIT_SIZE - COUNT_SIZE; i < DIT_SIZE; ++i ) {
|
|
||||||
hi_dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make Low DAH
|
// Make Low DAH
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
make_tone( lo_dah, LO_FREQUENCY, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
TRANSITION_BYTES );
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
* ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
lo_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = TRANSITION_BYTES;
|
|
||||||
i < DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
lo_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DAH_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / LO_FREQUENCY) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
lo_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
for ( i = DAH_SIZE - COUNT_SIZE; i < DAH_SIZE; ++i ) {
|
|
||||||
lo_dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make High DAH
|
// Make High DAH
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
make_tone( hi_dah, HI_FREQUENCY, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
TRANSITION_BYTES );
|
||||||
/ (8000.0 / HI_FREQUENCY) ) )
|
|
||||||
* ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = TRANSITION_BYTES;
|
|
||||||
i < DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / HI_FREQUENCY) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DAH_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI
|
|
||||||
/ (8000.0 / HI_FREQUENCY) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
hi_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
for ( i = DAH_SIZE - COUNT_SIZE; i < DAH_SIZE; ++i ) {
|
|
||||||
hi_dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make SPACE
|
// Make SPACE
|
||||||
|
int i;
|
||||||
for ( i = 0; i < SPACE_SIZE; ++i ) {
|
for ( i = 0; i < SPACE_SIZE; ++i ) {
|
||||||
space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
|
space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
|
||||||
}
|
}
|
||||||
|
@ -226,69 +136,12 @@ bool FGMorse::cust_init(const int freq ) {
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
// Make DIT
|
// Make DIT
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
make_tone( cust_dit, freq, DIT_SIZE - COUNT_SIZE, DIT_SIZE,
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq)) )
|
TRANSITION_BYTES );
|
||||||
* ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = TRANSITION_BYTES;
|
|
||||||
i < DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE; ++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DIT_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
for ( i = DIT_SIZE - COUNT_SIZE; i < DIT_SIZE; ++i ) {
|
|
||||||
cust_dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make DAH
|
// Make DAH
|
||||||
for ( i = 0; i < TRANSITION_BYTES; ++i ) {
|
make_tone( cust_dah, freq, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
TRANSITION_BYTES );
|
||||||
* ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = TRANSITION_BYTES;
|
|
||||||
i < DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
|
||||||
/ 2.0 + 0.5;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
j = TRANSITION_BYTES;
|
|
||||||
for ( i = DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
|
|
||||||
i < DAH_SIZE - COUNT_SIZE;
|
|
||||||
++i ) {
|
|
||||||
float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
|
|
||||||
* ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
|
|
||||||
--j;
|
|
||||||
|
|
||||||
/* Convert to unsigned byte */
|
|
||||||
cust_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
|
|
||||||
}
|
|
||||||
for ( i = DAH_SIZE - COUNT_SIZE; i < DAH_SIZE; ++i ) {
|
|
||||||
cust_dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make SPACE
|
// Make SPACE
|
||||||
for ( i = 0; i < SPACE_SIZE; ++i ) {
|
for ( i = 0; i < SPACE_SIZE; ++i ) {
|
||||||
|
|
|
@ -130,6 +130,21 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \relates FGMorse
|
||||||
|
* Make a tone of specified freq and total_len with trans_len ramp in
|
||||||
|
* and out and only the first len bytes with sound, the rest with
|
||||||
|
* silence.
|
||||||
|
* @param buf unsigned char pointer to sound buffer
|
||||||
|
* @param freq desired frequency of tone
|
||||||
|
* @param len length of tone within sound
|
||||||
|
* @param total_len total length of sound (anything more than len is padded
|
||||||
|
* with silence.
|
||||||
|
* @param trans_len length of ramp up and ramp down to avoid audio "pop"
|
||||||
|
*/
|
||||||
|
void make_tone( unsigned char *buf, int freq,
|
||||||
|
int len, int total_len, int trans_len );
|
||||||
|
|
||||||
#endif // _MORSE_HXX
|
#endif // _MORSE_HXX
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue