FGRadioStack::init ()
{
morse.init();
+ beacon.init();
search();
update();
// Update current nav/adf radio stations based on current postition
void FGRadioStack::search()
{
+ static FGMkrBeacon::fgMkrBeacType last_beacon = FGMkrBeacon::NOBEACON;
+
double lon = longitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
double lat = latitudeVal->getDoubleValue() * SGD_DEGREES_TO_RADIANS;
double elev = altitudeVal->getDoubleValue() * SG_FEET_TO_METER;
// cout << "not picking up vor1. :-(" << endl;
}
- FGBeacon::fgMkrBeacType beacon_type
- = current_beacons->query( lon * SGD_RADIANS_TO_DEGREES, lat * SGD_RADIANS_TO_DEGREES, elev );
+ FGMkrBeacon::fgMkrBeacType beacon_type
+ = current_beacons->query( lon * SGD_RADIANS_TO_DEGREES,
+ lat * SGD_RADIANS_TO_DEGREES, elev );
outer_marker = middle_marker = inner_marker = false;
- if ( beacon_type == FGBeacon::OUTER ) {
+ if ( beacon_type == FGMkrBeacon::OUTER ) {
outer_marker = true;
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;
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;
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
if ( current_navlist->query( lon, lat, elev, adf_freq, &nav ) ) {
#include <Navaids/ilslist.hxx>
#include <Navaids/navlist.hxx>
+#include <Sound/beacon.hxx>
#include <Sound/morse.hxx>
class FGRadioStack : public FGSubsystem
{
+ FGBeacon beacon;
FGMorse morse;
SGInterpTable *term_tbl;
if ( fabs(ils.get_omlon()) > SG_EPSILON ||
fabs(ils.get_omlat()) > SG_EPSILON ) {
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 ||
fabs(ils.get_mmlat()) > SG_EPSILON ) {
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 ||
fabs(ils.get_imlat()) > SG_EPSILON ) {
current_beacons->add( ils.get_imlon(), ils.get_imlat(),
- ils.get_gselev(), FGBeacon::INNER );
+ ils.get_gselev(), FGMkrBeacon::INNER );
}
}
// constructor
-FGBeacon::FGBeacon() {
- FGBeacon( 0, 0, 0, NOBEACON );
+FGMkrBeacon::FGMkrBeacon() {
+ FGMkrBeacon( 0, 0, 0, NOBEACON );
}
-FGBeacon::FGBeacon( double _lon, double _lat, double _elev,
+FGMkrBeacon::FGMkrBeacon( double _lon, double _lat, double _elev,
fgMkrBeacType _type ) {
lon = _lon;
lat = _lat;
}
// destructor
-FGBeacon::~FGBeacon() {
+FGMkrBeacon::~FGMkrBeacon() {
}
// 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;
beacon_map[master_index].push_back( b );
// front end for add a marker beacon
bool FGMarkerBeacons::add( double lon, double lat, double elev,
- FGBeacon::fgMkrBeacType type ) {
+ FGMkrBeacon::fgMkrBeacType type ) {
double diff;
int lonidx = (int)lon;
latidx += 90;
int master_index = lonidx * 1000 + latidx;
- FGBeacon b( lon, lat, elev, type );
+ FGMkrBeacon b( lon, lat, elev, type );
// add to the actual bucket
real_add( master_index, b );
// returns marker beacon type if we are over a marker beacon, NOBEACON
// otherwise
-FGBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
+FGMkrBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
double elev ) {
double diff;
cout << "lon = " << lon << " lat = " << lat
<< " closest beacon = " << sqrt( min_dist ) << endl;
- return FGBeacon::NOBEACON;
+ return FGMkrBeacon::NOBEACON;
}
SG_USING_STD(vector);
-class FGBeacon {
+class FGMkrBeacon {
public:
public:
- FGBeacon();
- FGBeacon( double _lon, double _lat, double _elev, fgMkrBeacType _type );
- ~FGBeacon();
+ FGMkrBeacon();
+ FGMkrBeacon( double _lon, double _lat, double _elev, fgMkrBeacType _type );
+ ~FGMkrBeacon();
inline double get_elev() const { return elev; }
inline fgMkrBeacType get_type() const { return type; }
class FGMarkerBeacons {
// 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::const_iterator beacon_list_const_iterator;
beacon_map_type beacon_map;
// 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:
// add a marker beacon
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
// otherwise
- FGBeacon::fgMkrBeacType query( double lon, double lat, double elev );
+ FGMkrBeacon::fgMkrBeacType query( double lon, double lat, double elev );
};
noinst_LIBRARIES = libSound.a
libSound_a_SOURCES = \
+ beacon.cxx beacon.hxx \
morse.cxx morse.hxx \
soundmgr.cxx soundmgr.hxx
--- /dev/null
+// 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;
+}
--- /dev/null
+/**
+ * \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
+
+
}
-// allocate and initialize sound samples
-bool FGMorse::init() {
+// 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
+void make_tone( unsigned char *buf, int freq,
+ int len, int total_len, int trans_len )
+{
int i, j;
- // Make Low DIT
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI
- / (8000.0 / LO_FREQUENCY) ) )
- * ((double)i / TRANSITION_BYTES)
- / 2.0 + 0.5;
+ for ( i = 0; i < trans_len; ++i ) {
+ float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
+ * ((double)i / trans_len) / 2.0 + 0.5;
/* Convert to unsigned byte */
- lo_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
+ buf[ 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 / LO_FREQUENCY) ) )
+ 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;
/* Convert to unsigned byte */
- lo_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
+ buf[ 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 = trans_len;
+ for ( i = len - trans_len; i < len; ++i ) {
+ float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
+ * ((double)j / trans_len) / 2.0 + 0.5;
--j;
/* 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 ) {
- lo_dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
- }
-
- // Make High DIT
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI
- / (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 = len; i < total_len; ++i ) {
+ buf[ i ] = (unsigned char) ( 0.5 * 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;
+// 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 );
- /* 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 High DIT
+ make_tone( hi_dit, HI_FREQUENCY, DIT_SIZE - COUNT_SIZE, DIT_SIZE,
+ TRANSITION_BYTES );
// Make Low DAH
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI
- / (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_tone( lo_dah, LO_FREQUENCY, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
+ TRANSITION_BYTES );
// Make High DAH
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI
- / (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_tone( hi_dah, HI_FREQUENCY, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
+ TRANSITION_BYTES );
// Make SPACE
+ int i;
for ( i = 0; i < SPACE_SIZE; ++i ) {
space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
}
int i, j;
// Make DIT
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq)) )
- * ((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_tone( cust_dit, freq, DIT_SIZE - COUNT_SIZE, DIT_SIZE,
+ TRANSITION_BYTES );
// Make DAH
- for ( i = 0; i < TRANSITION_BYTES; ++i ) {
- float level = ( sin( (double) i * 2.0 * SGD_PI / (8000.0 / freq) ) )
- * ((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_tone( cust_dah, freq, DAH_SIZE - COUNT_SIZE, DAH_SIZE,
+ TRANSITION_BYTES );
// Make SPACE
for ( i = 0; i < SPACE_SIZE; ++i ) {
};
+/**
+ * \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