]> git.mxchange.org Git - flightgear.git/commitdiff
Working on vor audio ident (morse).
authorcurt <curt>
Fri, 9 Mar 2001 02:41:04 +0000 (02:41 +0000)
committercurt <curt>
Fri, 9 Mar 2001 02:41:04 +0000 (02:41 +0000)
Fixed a bug in Network/props.cxx with the cd command.
Fixed a typo in options.cxx

src/Cockpit/radiostack.cxx
src/Cockpit/radiostack.hxx
src/Main/main.cxx
src/Main/options.cxx
src/Network/props.cxx
src/Sound/morse.cxx
src/Sound/morse.hxx
src/Sound/soundmgr.cxx
src/Sound/soundmgr.hxx

index 9b93cc8bc296bbfe95a274629f3803a090076823..82512a7e423170627d248b75ebb9d0a46f14fd32 100644 (file)
@@ -85,6 +85,8 @@ FGRadioStack::~FGRadioStack()
 void
 FGRadioStack::init ()
 {
+    morse.init();
+
     search();
     update();
 
@@ -104,6 +106,12 @@ FGRadioStack::bind ()
     fgTie("/radios/nav1/radials/selected", this,
          &FGRadioStack::get_nav1_sel_radial,
          &FGRadioStack::set_nav1_sel_radial);
+    fgTie("/radios/nav1/on", this,
+         &FGRadioStack::get_nav1_on_btn,
+         &FGRadioStack::set_nav1_on_btn);
+    fgTie("/radios/nav1/ident", this,
+         &FGRadioStack::get_nav1_ident_btn,
+         &FGRadioStack::set_nav1_ident_btn);
 
                                // Radio outputs
     fgTie("/radios/nav1/radials/actual", this, &FGRadioStack::get_nav1_radial);
@@ -126,6 +134,12 @@ FGRadioStack::bind ()
     fgTie("/radios/nav2/radials/selected", this,
          &FGRadioStack::get_nav2_sel_radial,
          &FGRadioStack::set_nav2_sel_radial);
+    fgTie("/radios/nav2/on", this,
+         &FGRadioStack::get_nav2_on_btn,
+         &FGRadioStack::set_nav2_on_btn);
+    fgTie("/radios/nav2/ident", this,
+         &FGRadioStack::get_nav2_ident_btn,
+         &FGRadioStack::set_nav2_ident_btn);
 
                                // Radio outputs
     fgTie("/radios/nav2/radials/actual", this, &FGRadioStack::get_nav2_radial);
@@ -156,6 +170,8 @@ FGRadioStack::unbind ()
     fgUntie("/radios/nav1/frequencies/standby");
     fgUntie("/radios/nav1/radials/actual");
     fgUntie("/radios/nav1/radials/selected");
+    fgUntie("/radios/nav1/on");
+    fgUntie("/radios/nav1/ident");
     fgUntie("/radios/nav1/to-flag");
     fgUntie("/radios/nav1/from-flag");
     fgUntie("/radios/nav1/in-range");
@@ -168,6 +184,8 @@ FGRadioStack::unbind ()
     fgUntie("/radios/nav2/frequencies/standby");
     fgUntie("/radios/nav2/radials/actual");
     fgUntie("/radios/nav2/radials/selected");
+    fgUntie("/radios/nav2/on");
+    fgUntie("/radios/nav2/ident");
     fgUntie("/radios/nav2/to-flag");
     fgUntie("/radios/nav2/from-flag");
     fgUntie("/radios/nav2/in-range");
@@ -181,7 +199,7 @@ FGRadioStack::unbind ()
     fgUntie("/radios/adf/rotation");
 }
 
-// Search the database for the current frequencies given current location
+// Update the various nav values based on position and valid tuned in navs
 void 
 FGRadioStack::update() 
 {
@@ -235,9 +253,20 @@ FGRadioStack::update()
        } else {
            nav1_radial = nav1_sel_radial;
        }
+
+       // play station ident via audio system if on + ident,
+       // otherwise turn it off
+       if ( nav1_on_btn && nav1_ident_btn ) {
+           if ( ! globals->get_soundmgr()->is_playing( "nav1-ident" ) ) {
+               globals->get_soundmgr()->play_once( "nav1-ident" );
+           }
+       } else {
+           globals->get_soundmgr()->stop( "nav1-ident" );
+       }
     } else {
        nav1_inrange = false;
        nav1_dme_dist = 0.0;
+       globals->get_soundmgr()->stop( "nav1-ident" );
        // cout << "not picking up vor. :-(" << endl;
     }
 
@@ -311,7 +340,7 @@ FGRadioStack::update()
 
 
 // Update current nav/adf radio stations based on current postition
-void FGRadioStack::search () 
+void FGRadioStack::search() 
 {
     double lon = longitudeVal->getDoubleValue() * DEG_TO_RAD;
     double lat = latitudeVal->getDoubleValue() * DEG_TO_RAD;
@@ -321,105 +350,145 @@ void FGRadioStack::search ()
     FGILS ils;
     FGNav nav;
 
+    static string last_nav1_ident = "";
+    static string last_nav2_ident = "";
+
     if ( current_ilslist->query( lon, lat, elev, nav1_freq, &ils ) ) {
-       nav1_valid = true;
-       nav1_loc = true;
-       nav1_has_dme = ils.get_has_dme();
-       nav1_has_gs = ils.get_has_gs();
-
-       nav1_loclon = ils.get_loclon();
-       nav1_loclat = ils.get_loclat();
-       nav1_gslon = ils.get_gslon();
-       nav1_gslat = ils.get_gslat();
-       nav1_dmelon = ils.get_dmelon();
-       nav1_dmelat = ils.get_dmelat();
-       nav1_elev = ils.get_gselev();
-       nav1_magvar = 0;
-       nav1_effective_range = FG_ILS_DEFAULT_RANGE;
-       nav1_target_gs = ils.get_gsangle();
-       nav1_radial = ils.get_locheading();
-       while ( nav1_radial <   0.0 ) { nav1_radial += 360.0; }
-       while ( nav1_radial > 360.0 ) { nav1_radial -= 360.0; }
-       nav1_x = ils.get_x();
-       nav1_y = ils.get_y();
-       nav1_z = ils.get_z();
-       nav1_gs_x = ils.get_gs_x();
-       nav1_gs_y = ils.get_gs_y();
-       nav1_gs_z = ils.get_gs_z();
-       nav1_dme_x = ils.get_dme_x();
-       nav1_dme_y = ils.get_dme_y();
-       nav1_dme_z = ils.get_dme_z();
-       // cout << "Found an ils station in range" << endl;
-       // cout << " id = " << ils.get_locident() << endl;
+       nav1_ident = ils.get_locident();
+       if ( last_nav1_ident != nav1_ident ) {
+           last_nav1_ident = nav1_ident;
+           nav1_valid = true;
+           nav1_loc = true;
+           nav1_has_dme = ils.get_has_dme();
+           nav1_has_gs = ils.get_has_gs();
+
+           nav1_loclon = ils.get_loclon();
+           nav1_loclat = ils.get_loclat();
+           nav1_gslon = ils.get_gslon();
+           nav1_gslat = ils.get_gslat();
+           nav1_dmelon = ils.get_dmelon();
+           nav1_dmelat = ils.get_dmelat();
+           nav1_elev = ils.get_gselev();
+           nav1_magvar = 0;
+           nav1_effective_range = FG_ILS_DEFAULT_RANGE;
+           nav1_target_gs = ils.get_gsangle();
+           nav1_radial = ils.get_locheading();
+           while ( nav1_radial <   0.0 ) { nav1_radial += 360.0; }
+           while ( nav1_radial > 360.0 ) { nav1_radial -= 360.0; }
+           nav1_x = ils.get_x();
+           nav1_y = ils.get_y();
+           nav1_z = ils.get_z();
+           nav1_gs_x = ils.get_gs_x();
+           nav1_gs_y = ils.get_gs_y();
+           nav1_gs_z = ils.get_gs_z();
+           nav1_dme_x = ils.get_dme_x();
+           nav1_dme_y = ils.get_dme_y();
+           nav1_dme_z = ils.get_dme_z();
+
+           if ( globals->get_soundmgr()->exists( "nav1-ident" ) ) {
+               globals->get_soundmgr()->remove( "nav1-ident" );
+           }
+           FGSimpleSound *sound = morse.make_ident( nav1_ident );
+           sound->set_volume( 0.3 );
+           globals->get_soundmgr()->add( sound, "nav1-ident" );
+
+           // cout << "Found an ils station in range" << endl;
+           // cout << " id = " << ils.get_locident() << endl;
+       }
     } else if ( current_navlist->query( lon, lat, elev, nav1_freq, &nav ) ) {
-       nav1_valid = true;
-       nav1_loc = false;
-       nav1_has_dme = nav.get_has_dme();
-       nav1_has_gs = false;
-       nav1_loclon = nav.get_lon();
-       nav1_loclat = nav.get_lat();
-       nav1_elev = nav.get_elev();
-       nav1_magvar = nav.get_magvar();
-       nav1_effective_range = kludgeRange(nav1_elev, elev, nav.get_range());
-       nav1_target_gs = 0.0;
-       nav1_radial = nav1_sel_radial;
-       nav1_x = nav1_dme_x = nav.get_x();
-       nav1_y = nav1_dme_y = nav.get_y();
-       nav1_z = nav1_dme_z = nav.get_z();
-       // cout << "Found a vor station in range" << endl;
-       // cout << " id = " << nav.get_ident() << endl;
+       nav1_ident = nav.get_ident();
+       if ( last_nav1_ident != nav1_ident ) {
+           last_nav1_ident = nav1_ident;
+           nav1_valid = true;
+           nav1_loc = false;
+           nav1_has_dme = nav.get_has_dme();
+           nav1_has_gs = false;
+           nav1_loclon = nav.get_lon();
+           nav1_loclat = nav.get_lat();
+           nav1_elev = nav.get_elev();
+           nav1_magvar = nav.get_magvar();
+           nav1_effective_range
+               = kludgeRange(nav1_elev, elev, nav.get_range());
+           nav1_target_gs = 0.0;
+           nav1_radial = nav1_sel_radial;
+           nav1_x = nav1_dme_x = nav.get_x();
+           nav1_y = nav1_dme_y = nav.get_y();
+           nav1_z = nav1_dme_z = nav.get_z();
+
+           if ( globals->get_soundmgr()->exists( "nav1-ident" ) ) {
+               globals->get_soundmgr()->remove( "nav1-ident" );
+           }
+           FGSimpleSound *sound = morse.make_ident( nav1_ident );
+           sound->set_volume( 0.3 );
+           globals->get_soundmgr()->add( sound, "nav1-ident" );
+
+           // cout << "Found a vor station in range" << endl;
+           // cout << " id = " << nav.get_ident() << endl;
+       }
     } else {
        nav1_valid = false;
+       nav1_ident = "";
        nav1_radial = 0;
        nav1_dme_dist = 0;
+       globals->get_soundmgr()->remove( "nav1-ident" );
        // cout << "not picking up vor1. :-(" << endl;
     }
 
     if ( current_ilslist->query( lon, lat, elev, nav2_freq, &ils ) ) {
-       nav2_valid = true;
-       nav2_loc = true;
-       nav2_has_dme = ils.get_has_dme();
-       nav2_has_gs = ils.get_has_gs();
-
-       nav2_loclon = ils.get_loclon();
-       nav2_loclat = ils.get_loclat();
-       nav2_elev = ils.get_gselev();
-       nav2_magvar = 0;
-       nav2_effective_range = FG_ILS_DEFAULT_RANGE;
-       nav2_target_gs = ils.get_gsangle();
-       nav2_radial = ils.get_locheading();
-       while ( nav2_radial <   0.0 ) { nav2_radial += 360.0; }
-       while ( nav2_radial > 360.0 ) { nav2_radial -= 360.0; }
-       nav2_x = ils.get_x();
-       nav2_y = ils.get_y();
-       nav2_z = ils.get_z();
-       nav2_gs_x = ils.get_gs_x();
-       nav2_gs_y = ils.get_gs_y();
-       nav2_gs_z = ils.get_gs_z();
-       nav2_dme_x = ils.get_dme_x();
-       nav2_dme_y = ils.get_dme_y();
-       nav2_dme_z = ils.get_dme_z();
-       // cout << "Found an ils station in range" << endl;
-       // cout << " id = " << ils.get_locident() << endl;
+       nav2_ident = ils.get_locident();
+       if ( last_nav2_ident != nav2_ident ) {
+           last_nav2_ident = nav2_ident;
+           nav2_valid = true;
+           nav2_loc = true;
+           nav2_has_dme = ils.get_has_dme();
+           nav2_has_gs = ils.get_has_gs();
+
+           nav2_loclon = ils.get_loclon();
+           nav2_loclat = ils.get_loclat();
+           nav2_elev = ils.get_gselev();
+           nav2_magvar = 0;
+           nav2_effective_range = FG_ILS_DEFAULT_RANGE;
+           nav2_target_gs = ils.get_gsangle();
+           nav2_radial = ils.get_locheading();
+           while ( nav2_radial <   0.0 ) { nav2_radial += 360.0; }
+           while ( nav2_radial > 360.0 ) { nav2_radial -= 360.0; }
+           nav2_x = ils.get_x();
+           nav2_y = ils.get_y();
+           nav2_z = ils.get_z();
+           nav2_gs_x = ils.get_gs_x();
+           nav2_gs_y = ils.get_gs_y();
+           nav2_gs_z = ils.get_gs_z();
+           nav2_dme_x = ils.get_dme_x();
+           nav2_dme_y = ils.get_dme_y();
+           nav2_dme_z = ils.get_dme_z();
+           // cout << "Found an ils station in range" << endl;
+           // cout << " id = " << ils.get_locident() << endl;
+       }
     } else if ( current_navlist->query( lon, lat, elev, nav2_freq, &nav ) ) {
-       nav2_valid = true;
-       nav2_loc = false;
-       nav2_has_dme = nav.get_has_dme();
-       nav2_has_dme = false;
-       nav2_loclon = nav.get_lon();
-       nav2_loclat = nav.get_lat();
-       nav2_elev = nav.get_elev();
-       nav2_magvar = nav.get_magvar();
-       nav2_effective_range = kludgeRange(nav2_elev, elev, nav.get_range());
-       nav2_target_gs = 0.0;
-       nav2_radial = nav2_sel_radial;
-       nav2_x = nav2_dme_x = nav.get_x();
-       nav2_y = nav2_dme_y = nav.get_y();
-       nav2_z = nav2_dme_z = nav.get_z();
-       // cout << "Found a vor station in range" << endl;
-       // cout << " id = " << nav.get_ident() << endl;
+       nav2_ident = nav.get_ident();
+       if ( last_nav2_ident != nav2_ident ) {
+           last_nav2_ident = nav2_ident;
+           nav2_valid = true;
+           nav2_loc = false;
+           nav2_has_dme = nav.get_has_dme();
+           nav2_has_dme = false;
+           nav2_loclon = nav.get_lon();
+           nav2_loclat = nav.get_lat();
+           nav2_elev = nav.get_elev();
+           nav2_magvar = nav.get_magvar();
+           nav2_effective_range
+               = kludgeRange(nav2_elev, elev, nav.get_range());
+           nav2_target_gs = 0.0;
+           nav2_radial = nav2_sel_radial;
+           nav2_x = nav2_dme_x = nav.get_x();
+           nav2_y = nav2_dme_y = nav.get_y();
+           nav2_z = nav2_dme_z = nav.get_z();
+           // cout << "Found a vor station in range" << endl;
+           // cout << " id = " << nav.get_ident() << endl;
+       }
     } else {
        nav2_valid = false;
+       nav2_ident = "";
        nav2_radial = 0;
        nav2_dme_dist = 0;
        // cout << "not picking up vor2. :-(" << endl;
index c2031790322f9a2ffc9de23e89dbbd0fe9c6368d..aa9f28d383f0dc42f4255cb013361c823b75f910 100644 (file)
 
 #include <Navaids/ilslist.hxx>
 #include <Navaids/navlist.hxx>
-
+#include <Sound/morse.hxx>
 
 
 class FGRadioStack : public FGSubsystem
 {
+    FGMorse morse;
 
     SGValue * latitudeVal;
     SGValue * longitudeVal;
@@ -44,6 +45,7 @@ class FGRadioStack : public FGSubsystem
 
     bool need_update;
 
+    string nav1_ident;
     bool nav1_valid;
     bool nav1_inrange;
     bool nav1_has_dme;
@@ -76,7 +78,10 @@ class FGRadioStack : public FGSubsystem
     double nav1_heading;
     double nav1_target_gs;
     double nav1_magvar;
+    bool nav1_on_btn;
+    bool nav1_ident_btn;
 
+    string nav2_ident;
     bool nav2_valid;
     bool nav2_inrange;
     bool nav2_has_dme;
@@ -109,6 +114,8 @@ class FGRadioStack : public FGSubsystem
     double nav2_heading;
     double nav2_target_gs;
     double nav2_magvar;
+    bool nav2_on_btn;
+    bool nav2_ident_btn;
 
     bool adf_valid;
     bool adf_inrange;
@@ -146,6 +153,8 @@ public:
     inline void set_nav1_sel_radial( double radial ) {
        nav1_sel_radial = radial; need_update = true;
     }
+    inline void set_nav1_on_btn( bool val ) { nav1_on_btn = val; }
+    inline void set_nav1_ident_btn( bool val ) { nav1_ident_btn = val; }
 
     // NAV2 Setters
     inline void set_nav2_freq( double freq ) {
@@ -155,6 +164,8 @@ public:
     inline void set_nav2_sel_radial( double radial ) {
        nav2_sel_radial = radial; need_update = true;
     }
+    inline void set_nav2_on_btn( bool val ) { nav2_on_btn = val; }
+    inline void set_nav2_ident_btn( bool val ) { nav2_ident_btn = val; }
 
     // ADF Setters
     inline void set_adf_freq( double freq ) {
@@ -205,6 +216,8 @@ public:
     inline double get_nav1_magvar() const { return nav1_magvar; }
     double get_nav1_heading_needle_deflection() const;
     double get_nav1_gs_needle_deflection() const;
+    inline bool get_nav1_on_btn() const { return nav1_on_btn; }
+    inline bool get_nav1_ident_btn() const { return nav1_ident_btn; }
 
     inline bool get_nav2_inrange() const { return nav2_inrange; }
     bool get_nav2_to_flag () const;
@@ -231,6 +244,8 @@ public:
     inline double get_nav2_magvar() const { return nav2_magvar; }
     double get_nav2_heading_needle_deflection() const;
     double get_nav2_gs_needle_deflection() const;
+    inline bool get_nav2_on_btn() const { return nav2_on_btn; }
+    inline bool get_nav2_ident_btn() const { return nav2_ident_btn; }
 
     inline bool get_adf_inrange() const { return adf_inrange; }
     inline double get_adf_lon() const { return adf_lon; }
index d3246848e9d7a39447326a82e02bab2432509339..9321b9d63c6e0c4e3de603c28c50e5d2b1402812 100644 (file)
@@ -1067,10 +1067,10 @@ static void fgMainLoop( void ) {
                 << cur_fdm_state->get_engine(0)->get_Manifold_Pressure()
                 << endl; */
 
-           double volume = 0.3 + mp_factor;
+           double volume = 0.15 + mp_factor / 2.0;
 
-           if ( volume < 0.3 ) { volume = 0.3; }
-           if ( volume > 1.0 ) { volume = 1.0; }
+           if ( volume < 0.15 ) { volume = 0.15; }
+           if ( volume > 0.5 ) { volume = 0.5; }
            // cout << "volume = " << volume << endl;
 
            s1->set_pitch( pitch );
@@ -1183,7 +1183,8 @@ static void fgIdleFunction ( void ) {
        if ( fgGetBool("/sim/sound") ) {
            globals->get_soundmgr()->init();
 
-           s1 = new FGSimpleSound( "Sounds/wasp.wav" );
+           s1 = new FGSimpleSound( fgGetString("/sim/sounds/engine",
+                                               "Sounds/wasp.wav") );
            globals->get_soundmgr()->add( s1, "engine loop" );
            globals->get_soundmgr()->play_looped( "engine loop" );
            FG_LOG( FG_GENERAL, FG_INFO,
@@ -1192,11 +1193,11 @@ static void fgIdleFunction ( void ) {
                    << "  Stereo = " << s1->get_sample()->getStereo() );
 
            // s2 = new FGSimpleSound( "Sounds/corflaps.wav" );
-           // s2->set_volume( 2.0 );
-           // FGMorse mmm;
-           // mmm.init();
-           // s2 = mmm.make_ident( "JLI" );
-           // globals->get_soundmgr()->add( s2, "flaps" );
+           FGMorse mmm;
+           mmm.init();
+           s2 = mmm.make_ident( "JLI" );
+           s2->set_volume( 0.3 );
+           globals->get_soundmgr()->add( s2, "flaps" );
        }
 #endif
 
index 786749278d89929236b9cc50b5b77ca37ce2f833..52d30fab49850eaca084a1ae8d922b306e28d294 100644 (file)
@@ -490,7 +490,7 @@ static bool
 parse_flightplan(const string& arg)
 {
     fg_gzifstream infile(arg.c_str());
-    if (!infile) {
+    if ( !infile.is_open() ) {
        return false;
     }
     while ( true ) {
@@ -867,8 +867,8 @@ parse_option (const string& arg)
        parse_wp( arg.substr( 5 ) );
     } else if ( arg.find( "--flight-plan=") == 0) {
        parse_flightplan ( arg.substr (14) );
-    } else if ( arg.find( "--file=" ) == 0 ) {
-        string file = arg.substr(7);
+    } else if ( arg.find( "--config=" ) == 0 ) {
+        string file = arg.substr(9);
         if (!readProperties(file, globals->get_props())) {
          FG_LOG(FG_IO, FG_ALERT,
                 "--config: failed to read properties from " << file);
index f249f23b8524a8e49e81c91ef08b8a34fcdeba59..e82d8a10c44862b6d5134272b6bb6bd9523512c1 100644 (file)
@@ -155,7 +155,8 @@ bool FGProps::process_command( const char *cmd ) {
        } else {
            SGPropertyNode *child = node->getNode(tokens[1]);
            if ( child ) {
-               path = child->getPath();
+               node = child;
+               path = node->getPath();
            } else {
                tokens[1] += " Not Found\n";
                io->writestring( tokens[1].c_str() );
index e4cf3efc12be072b820f2d3cbf10fe3e2e85ff2f..4414b70b1bbef90927abc9ba47c3725a0e3a8ae2 100644 (file)
@@ -67,69 +67,189 @@ FGMorse::~FGMorse() {
 bool FGMorse::init() {
     int i, j;
 
+    // Make Low DIT
+    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_PI
+                            / (8000.0 / LO_FREQUENCY) ) )
+           * ((double)i / TRANSITION_BYTES)
+           / 2.0 + 0.5;
+
+       /* Convert to unsigned byte */
+       lo_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 * M_PI
+                            / (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 * M_PI
+                            / (8000.0 / LO_FREQUENCY) ) )
+           * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
+       --j;
+
+       /* Convert to unsigned byte */
+       lo_dit[ 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 * M_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 = TRANSITION_BYTES;
+         i < DIT_SIZE - TRANSITION_BYTES - COUNT_SIZE; ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_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 * M_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
+    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_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 * M_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 ( int i = DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
+         i < DAH_SIZE - COUNT_SIZE;
+         ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_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 ( int i = DAH_SIZE - COUNT_SIZE; i < DAH_SIZE; ++i ) {
+       lo_dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
+    }
+
+    // Make SPACE
+    for ( int i = 0; i < SPACE_SIZE; ++i ) {
+       space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
+    }
+
+    return true;
+}
+
+
+// allocate and initialize sound samples
+bool FGMorse::cust_init(const int freq ) {
+    int i, j;
+
     // Make DIT
     for ( i = 0; i < TRANSITION_BYTES; ++i ) {
-       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY)) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq)) )
            * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
 
        /* Convert to unsigned byte */
-       dit[ i ] = (unsigned char) ( level * 255.0 ) ;
+       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 * M_PI / (8000.0 / FREQUENCY) ) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq) ) )
            / 2.0 + 0.5;
 
        /* Convert to unsigned byte */
-       dit[ i ] = (unsigned char) ( level * 255.0 ) ;
+       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 * M_PI / (8000.0 / FREQUENCY) ) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq) ) )
            * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
        --j;
 
        /* Convert to unsigned byte */
-       dit[ i ] = (unsigned char) ( level * 255.0 ) ;
+       cust_dit[ i ] = (unsigned char) ( level * 255.0 ) ;
     }
     for ( i = DIT_SIZE - COUNT_SIZE; i < DIT_SIZE; ++i ) {
-       dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
+       cust_dit[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
     }
 
     // Make DAH
     for ( i = 0; i < TRANSITION_BYTES; ++i ) {
-       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY) ) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq) ) )
            * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
 
        /* Convert to unsigned byte */
-       dah[ i ] = (unsigned char) ( level * 255.0 ) ;
+       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 * M_PI / (8000.0 / FREQUENCY) ) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq) ) )
            / 2.0 + 0.5;
 
        /* Convert to unsigned byte */
-       dah[ i ] = (unsigned char) ( level * 255.0 ) ;
+       cust_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
     }
     j = TRANSITION_BYTES;
     for ( int i = DAH_SIZE - TRANSITION_BYTES - COUNT_SIZE;
          i < DAH_SIZE - COUNT_SIZE;
          ++i ) {
-       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY) ) )
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / freq) ) )
            * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
        --j;
 
        /* Convert to unsigned byte */
-       dah[ i ] = (unsigned char) ( level * 255.0 ) ;
+       cust_dah[ i ] = (unsigned char) ( level * 255.0 ) ;
     }
     for ( int i = DAH_SIZE - COUNT_SIZE; i < DAH_SIZE; ++i ) {
-       dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
+       cust_dah[ i ] = (unsigned char) ( 0.5 * 255.0 ) ;
     }
 
     // Make SPACE
@@ -142,12 +262,28 @@ bool FGMorse::init() {
 
 
 // make a FGSimpleSound morse code transmission for the specified string
-FGSimpleSound *FGMorse::make_ident( const string& id ) {
+FGSimpleSound *FGMorse::make_ident( const string& id, const int freq ) {
     char *idptr = (char *)id.c_str();
 
     int length = 0;
     int i, j;
 
+    // 0. Select the frequency.  If custom frequency, generate the
+    // sound fragments we need on the fly.
+    unsigned char *dit_ptr, *dah_ptr;
+
+    if ( freq == LO_FREQUENCY ) {
+       dit_ptr = lo_dit;
+       dah_ptr = lo_dah;
+    } else if ( freq == HI_FREQUENCY ) {
+       dit_ptr = hi_dit;
+       dah_ptr = hi_dah;
+    } else {
+       cust_init( freq );
+       dit_ptr = cust_dit;
+       dah_ptr = cust_dah;
+    }
+
     // 1. Determine byte length of message
     for ( i = 0; i < (int)id.length(); ++i ) {
        if ( idptr[i] >= 'A' && idptr[i] <= 'Z' ) {
@@ -164,31 +300,37 @@ FGSimpleSound *FGMorse::make_ident( const string& id ) {
            // skip unknown character
        }
     }
+    // add 2x more space to the end of the string
+    length += 2 * SPACE_SIZE;
 
     // 2. Allocate space for the message
     unsigned char *buffer = new unsigned char[length];
 
     // 3. Assemble the message;
-    unsigned char *bufptr = buffer;
+    unsigned char *buf_ptr = buffer;
 
     for ( i = 0; i < (int)id.length(); ++i ) {
        if ( idptr[i] >= 'A' && idptr[i] <= 'Z' ) {
            char c = idptr[i] - 'A';
            for ( j = 0; j < 4 || alphabet[c][j] == end; ++j ) {
                if ( alphabet[c][j] == DIT ) {
-                   memcpy( bufptr, dit, DIT_SIZE );
-                   bufptr += DIT_SIZE;
+                   memcpy( buf_ptr, dit_ptr, DIT_SIZE );
+                   buf_ptr += DIT_SIZE;
                } else if ( alphabet[c][j] == DAH ) {
-                   memcpy( bufptr, dah, DAH_SIZE );
-                   bufptr += DAH_SIZE;
+                   memcpy( buf_ptr, dah_ptr, DAH_SIZE );
+                   buf_ptr += DAH_SIZE;
                }
            }
-           memcpy( bufptr, space, SPACE_SIZE );
-           bufptr += SPACE_SIZE;
+           memcpy( buf_ptr, space, SPACE_SIZE );
+           buf_ptr += SPACE_SIZE;
        } else {
            // skip unknown character
        }
     }
+    memcpy( buf_ptr, space, SPACE_SIZE );
+    buf_ptr += SPACE_SIZE;
+    memcpy( buf_ptr, space, SPACE_SIZE );
+    buf_ptr += SPACE_SIZE;
 
     // 4. create the simple sound and return
     FGSimpleSound *sample = new FGSimpleSound( buffer, length );
index c4038fcac9fd17d1a4aef8d9dcf51b5b310325f8..c17635ef91fc7f377717f75e79f783d36cfe4079 100644 (file)
@@ -97,15 +97,25 @@ static const int COUNT_SIZE = BYTES_PER_SECOND * BEAT_LENGTH / 1000;
 static const int DIT_SIZE = 2 * COUNT_SIZE;   // 2 counts
 static const int DAH_SIZE = 4 * COUNT_SIZE;   // 4 counts
 static const int SPACE_SIZE = 3 * COUNT_SIZE; // 3 counts
-static const int FREQUENCY = 1020;      // AIM 1-1-7 (f) specified in Hz
+static const int LO_FREQUENCY = 1020;   // AIM 1-1-7 (f) specified in Hz
+static const int HI_FREQUENCY = 1350;   // AIM 1-1-7 (f) specified in Hz
 
 // manages everything we need to know for an individual sound sample
 class FGMorse {
 
-    unsigned char dit[ DIT_SIZE ] ;
-    unsigned char dah[ DAH_SIZE ] ;
+private:
+
+    unsigned char hi_dit[ DIT_SIZE ] ;
+    unsigned char lo_dit[ DIT_SIZE ] ;
+    unsigned char hi_dah[ DAH_SIZE ] ;
+    unsigned char lo_dah[ DAH_SIZE ] ;
     unsigned char space[ SPACE_SIZE ] ;
 
+    unsigned char cust_dit[ DIT_SIZE ] ;
+    unsigned char cust_dah[ DAH_SIZE ] ;
+
+    bool cust_init( const int freq );
+
 public:
 
     FGMorse();
@@ -115,7 +125,8 @@ public:
     bool init();
 
     // make a FGSimpleSound morse code transmission for the specified string
-    FGSimpleSound *make_ident( const string& id );
+    FGSimpleSound *make_ident( const string& id,
+                              const int freq = LO_FREQUENCY );
 };
 
 
index 8b3756abf1ccc24cbcea5a79904dc86a492c4124..6ec0ed1de8770d48138baefcf05409b317c7d3b8 100644 (file)
@@ -118,7 +118,7 @@ bool FGSoundMgr::update() {
 }
 
 
-// add a sound effect
+// add a sound effect, return true if successful
 bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname  ) {
     sounds[refname] = sound;
 
@@ -126,6 +126,52 @@ bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname  ) {
 }
 
 
+// remove a sound effect, return true if successful
+bool FGSoundMgr::remove( const string& refname ) {
+    sound_map_iterator it = sounds.find( refname );
+    if ( it != sounds.end() ) {
+       // first stop the sound from playing (so we don't bomb the
+       // audio scheduler)
+       FGSimpleSound *sample = it->second;
+
+       cout << "Playing "
+            << sample->get_sample()->getPlayCount() << " instances!" << endl;
+
+       audio_sched->stopSample( sample->get_sample() );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
+                                       NULL,
+                                       SL_PITCH_ENVELOPE );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, 
+                                       NULL,
+                                       SL_VOLUME_ENVELOPE );
+
+       // must call audio_sched->update() after stopping the sound
+       // but before deleting it.
+       audio_sched -> update();
+       cout << "Still playing "
+            << sample->get_sample()->getPlayCount() << " instances!" << endl;
+
+       delete sample;
+        sounds.erase( it );
+
+       return true;
+   } else {
+       return false;
+    }
+}
+
+
+// return true of the specified sound exists in the sound manager system
+bool FGSoundMgr::exists( const string& refname ) {
+    sound_map_iterator it = sounds.find( refname );
+    if ( it != sounds.end() ) {
+       return true;
+   } else {
+       return false;
+    }
+}
+
+
 // tell the scheduler to play the indexed sample in a continuous
 // loop
 bool FGSoundMgr::play_looped( const string& refname ) {
@@ -152,6 +198,7 @@ bool FGSoundMgr::FGSoundMgr::play_once( const string& refname ) {
     sound_map_iterator it = sounds.find( refname );
     if ( it != sounds.end() ) {
        FGSimpleSound *sample = it->second;
+       audio_sched->stopSample( sample->get_sample() );
        audio_sched->playSample( sample->get_sample() );
        audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
                                        sample->get_pitch_envelope(),
@@ -165,3 +212,29 @@ bool FGSoundMgr::FGSoundMgr::play_once( const string& refname ) {
        return false;
     }
 }
+
+
+// return true of the specified sound is currently being played
+bool FGSoundMgr::is_playing( const string& refname ) {
+    sound_map_iterator it = sounds.find( refname );
+    if ( it != sounds.end() ) {
+       FGSimpleSound *sample = it->second;
+       return (sample->get_sample()->getPlayCount() > 0 );
+       return true;
+    } else {
+       return false;
+    }
+}
+
+
+// immediate stop playing the sound
+bool FGSoundMgr::stop( const string& refname ) {
+    sound_map_iterator it = sounds.find( refname );
+    if ( it != sounds.end() ) {
+       FGSimpleSound *sample = it->second;
+       audio_sched->stopSample( sample->get_sample() );
+       return true;
+    } else {
+       return false;
+    }
+}
index 6b404599e0842fad2600ef67ac27d7e7470b5dae..b475aaf0c438ccf246b1a30d4964a321ed592ccf 100644 (file)
@@ -100,15 +100,27 @@ public:
     // is audio working?
     inline bool is_working() const { return !audio_sched->not_working(); }
 
-    // add a sound effect, return the index of the sound
+    // add a sound effect, return true if successful
     bool add( FGSimpleSound *sound, const string& refname );
 
+    // remove a sound effect, return true if successful
+    bool remove( const string& refname );
+
+    // return true of the specified sound exists in the sound manager system
+    bool exists( const string& refname );
+
     // tell the scheduler to play the indexed sample in a continuous
     // loop
     bool play_looped( const string& refname );
 
     // tell the scheduler to play the indexed sample once
     bool play_once( const string& refname );
+
+    // return true of the specified sound is currently being played
+    bool is_playing( const string& refname );
+
+    // immediate stop playing the sound
+    bool stop( const string& refname );
 };