1
0
Fork 0

Added marker beacon sound effects.

This commit is contained in:
curt 2001-03-28 07:12:11 +00:00
parent 7aa5e0a4eb
commit 2e8f9f7399
10 changed files with 340 additions and 215 deletions

View file

@ -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 ) ) {

View file

@ -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;

View file

@ -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 );
} }
} }

View file

@ -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;
} }

View file

@ -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 );
}; };

View file

@ -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
View 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
View 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

View file

@ -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 ) {

View file

@ -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