]> git.mxchange.org Git - flightgear.git/commitdiff
Reshuffled some of the sound code and created a "src/Sound" subdirectory.
authorcurt <curt>
Mon, 5 Mar 2001 22:54:20 +0000 (22:54 +0000)
committercurt <curt>
Mon, 5 Mar 2001 22:54:20 +0000 (22:54 +0000)
13 files changed:
FlightGear.dsp
src/Main/Makefile.am
src/Main/globals.hxx
src/Main/main.cxx
src/Main/morse.cxx [deleted file]
src/Main/morse.hxx [deleted file]
src/Main/soundmgr.cxx [deleted file]
src/Main/soundmgr.hxx [deleted file]
src/Makefile.am
src/Sound/Makefile.am [new file with mode: 0644]
src/Sound/morse.cxx [new file with mode: 0644]
src/Sound/morse.hxx [new file with mode: 0644]
src/Sound/soundmgr.cxx [new file with mode: 0644]

index 4911b921429eb46e023433be8478fe9b575626d6..e42fcdf3677901853b82085428044b6a6100caf7 100644 (file)
@@ -2373,6 +2373,21 @@ SOURCE=.\src\Main\options.cxx
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=.\src\Main\soundmgr.cxx\r
+\r
+!IF  "$(CFG)" == "FlightGear - Win32 Release"\r
+\r
+# PROP Intermediate_Dir "Release\main"\r
+\r
+!ELSEIF  "$(CFG)" == "FlightGear - Win32 Debug"\r
+\r
+# PROP Intermediate_Dir "Debug\main"\r
+\r
+!ENDIF \r
+\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=.\src\Main\splash.cxx\r
 \r
 !IF  "$(CFG)" == "FlightGear - Win32 Release"\r
index b359d223caaec1fc7f3a986975223ed2400eb52e..1f8250ec6646135b752339f9b18080cf27bdd191 100644 (file)
@@ -42,9 +42,7 @@ fgfs_SOURCES = \
         fgfs.cxx fgfs.hxx \
        globals.cxx globals.hxx \
        keyboard.cxx keyboard.hxx \
-       morse.cxx morse.hxx \
        options.cxx options.hxx \
-       soundmgr.cxx soundmgr.hxx \
        splash.cxx splash.hxx \
        viewer.cxx viewer.hxx \
        viewer_lookat.cxx viewer_lookat.hxx \
@@ -65,6 +63,7 @@ fgfs_LDADD = \
        $(top_builddir)/src/GUI/libGUI.a \
        $(top_builddir)/src/Navaids/libNavaids.a \
        $(top_builddir)/src/Scenery/libScenery.a \
+       $(top_builddir)/src/Sound/libSound.a \
        $(top_builddir)/src/Airports/libAirports.a \
         $(NETWORK_LIBS) \
        $(top_builddir)/src/Objects/libObjects.a \
index 79afec3b20bd95fc388ad0e5d953571ad85df870..06155b7bc1c856f5377afe704f538c2fae3cf487 100644 (file)
@@ -36,7 +36,7 @@
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/misc/props.hxx>
 
-#include "soundmgr.hxx"
+#include <Sound/soundmgr.hxx>
 #include "viewmgr.hxx"
 
 FG_USING_STD( vector );
index 9cd830f71b276398f6025441661ba9f88442e101..d3246848e9d7a39447326a82e02bab2432509339 100644 (file)
 #endif
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
+#ifdef ENABLE_AUDIO_SUPPORT
+#  include <Sound/soundmgr.hxx>
+#  include <Sound/morse.hxx>
+#endif
 #include <Time/event.hxx>
 #include <Time/fg_timer.hxx>
 #include <Time/light.hxx>
@@ -117,13 +121,8 @@ int objc=0;
 #include "fg_io.hxx"
 #include "globals.hxx"
 #include "keyboard.hxx"
-#include "morse.hxx"
 #include "splash.hxx"
 
-#ifdef ENABLE_AUDIO_SUPPORT
-#  include "soundmgr.hxx"
-#endif
-
 #ifdef macintosh
 #  include <console.h>         // -dw- for command line dialog
 #endif
@@ -1194,10 +1193,10 @@ static void fgIdleFunction ( void ) {
 
            // 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" );
+           // globals->get_soundmgr()->add( s2, "flaps" );
        }
 #endif
 
diff --git a/src/Main/morse.cxx b/src/Main/morse.cxx
deleted file mode 100644 (file)
index ceaa23c..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-// morse.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 "morse.hxx"
-
-
-// constructor
-FGMorse::FGMorse() {
-}
-
-// destructor
-FGMorse::~FGMorse() {
-}
-
-
-// allocate and initialize sound samples
-bool FGMorse::init() {
-    int i, j;
-
-    // Make DIT
-    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
-       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY)) )
-           * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
-
-       /* Convert to unsigned byte */
-       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) ) )
-           / 2.0 + 0.5;
-
-       /* Convert to unsigned byte */
-       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) ) )
-           * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
-       --j;
-
-       /* Convert to unsigned byte */
-       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 ) ;
-    }
-
-    // Make DAH
-    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
-       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY) ) )
-           * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
-
-       /* Convert to unsigned byte */
-       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) ) )
-           / 2.0 + 0.5;
-
-       /* Convert to unsigned byte */
-       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) ) )
-           * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
-       --j;
-
-       /* Convert to unsigned byte */
-       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 ) ;
-    }
-
-    // Make SPACE
-    for ( int i = 0; i < SPACE_SIZE; ++i ) {
-       space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
-    }
-
-    return true;
-}
-
-
-// make a FGSimpleSound morse code transmission for the specified string
-FGSimpleSound *FGMorse::make_ident( const string& id ) {
-    char *idptr = (char *)id.c_str();
-
-    int length = 0;
-    int i, j;
-
-    // 1. Determine byte length of message
-    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 ) {
-                   length += DIT_SIZE;
-               } else if ( alphabet[c][j] == DAH ) {
-                   length += DAH_SIZE;
-               }
-           }
-           length += SPACE_SIZE;
-       } else {
-           // skip unknown character
-       }
-    }
-
-    // 2. Allocate space for the message
-    unsigned char *buffer = new unsigned char[length];
-
-    // 3. Assemble the message;
-    unsigned char *bufptr = 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;
-               } else if ( alphabet[c][j] == DAH ) {
-                   memcpy( bufptr, dah, DAH_SIZE );
-                   bufptr += DAH_SIZE;
-               }
-           }
-           memcpy( bufptr, space, SPACE_SIZE );
-           bufptr += SPACE_SIZE;
-       } else {
-           // skip unknown character
-       }
-    }
-
-    // 4. create the simple sound and return
-    FGSimpleSound *sample = new FGSimpleSound( buffer, length );
-
-    return sample;
-}
diff --git a/src/Main/morse.hxx b/src/Main/morse.hxx
deleted file mode 100644 (file)
index 34426bd..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-// morse.hxx -- 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$
-
-
-#ifndef _MORSE_HXX
-#define _MORSE_HXX
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-
-#include <plib/sl.h>
-#include <plib/sm.h>
-
-#include "soundmgr.hxx"
-
-
-// Quoting from http://www.kluft.com/~ikluft/ham/morse-intro.html by
-// Ian Kluft KO6YQ <ikluft@kluft.com>
-//
-// [begin quote]
-//
-// What is the Standard for Measuring Morse Code Speed?
-// 
-// [This was adapted from the Ham Radio FAQ which used to be posted on UseNet.] 
-// 
-// The word PARIS was chosen as the standard length for CW code
-// speed. Each dit counts for one count, each dah counts for three
-// counts, intra-character spacing is one count, inter-character
-// spacing is three counts and inter-word spacing is seven counts, so
-// the word PARIS is exactly 50 counts:
-// 
-// PPPPPPPPPPPPPP    AAAAAA    RRRRRRRRRR    IIIIII    SSSSSSSSSS
-// di  da  da  di    di  da    di  da  di    di  di    di  di  di
-// 1 1 3 1 3 1 1  3  1 1 3  3  1 1 3 1 1  3  1 1 1  3  1 1 1 1 1  7 = 50
-//   ^                      ^                                     ^
-//   ^Intra-character       ^Inter-character            Inter-word^
-// 
-// So 5 words-per-minute = 250 counts-per-minute / 50 counts-per-word
-// or one count every 240 milliseconds. 13 words-per-minute is one
-// count every ~92.3 milliseconds. This method of sending code is
-// sometimes called "Slow Code", because at 5 wpm it sounds VERY SLOW.
-// 
-// The "Farnsworth" method is accomplished by sending the dits and
-// dahs and intra-character spacing at a higher speed, then increasing
-// the inter-character and inter-word spacing to slow the sending
-// speed down to the desired speed. For example, to send at 5 wpm with
-// 13 wpm characters in Farnsworth method, the dits and
-// intra-character spacing would be 92.3 milliseconds, the dah would
-// be 276.9 milliseconds, the inter-character spacing would be 1.443
-// seconds and inter-word spacing would be 3.367 seconds.
-//
-// [end quote]
-
-// Ok, back to Curt 
-
-// My formulation is based dit = 1 count, dah = 3 counts, 1 count for
-// intRA-character space, 3 counts for intER-character space.  Target
-// is 5 wpm which by the above means 1 count = 240 milliseconds.
-// 
-// AIM 1-1-7 (f) states that the frequency of the tone should be 1020
-// Hz for the VOR ident.
-
-
-static const char DI = '1';
-static const char DIT = '1';
-static const char DA = '2';
-static const char DAH = '2';
-static const char end = '0';
-
-static const int BYTES_PER_SECOND = 8000;
-static const int BEAT_LENGTH = 240; // milleseconds (5 wpm)
-static const int TRANSITION_BYTES = (int)(0.005 * BYTES_PER_SECOND);
-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 char alphabet[26][4] = {
-    { DI, DAH, end, end },     /* A */ 
-    { DA, DI, DI, DIT },       /* B */ 
-    { DA, DI, DA, DIT },       /* C */ 
-    { DA, DI, DIT, end },      /* D */ 
-    { DIT, end, end, end },    /* E */ 
-    { DI, DI, DA, DIT },       /* F */ 
-    { DA, DA, DIT, end },      /* G */ 
-    { DI, DI, DI, DIT },       /* H */ 
-    { DI, DIT, end, end },     /* I */ 
-    { DI, DA, DA, DAH },       /* J */ 
-    { DA, DI, DAH, end },      /* K */ 
-    { DI, DA, DI, DIT },       /* L */ 
-    { DA, DAH, end, end },     /* M */ 
-    { DA, DIT, end, end },     /* N */ 
-    { DA, DA, DAH, end },      /* O */ 
-    { DI, DA, DA, DIT },       /* P */ 
-    { DA, DA, DI, DAH },       /* Q */ 
-    { DI, DA, DIT, end },      /* R */ 
-    { DI, DI, DIT, end },      /* S */ 
-    { DAH, end, end, end },    /* T */ 
-    { DI, DI, DAH, end },      /* U */ 
-    { DI, DI, DI, DAH },       /* V */ 
-    { DI, DA, DAH, end },      /* W */ 
-    { DA, DI, DI, DAH },       /* X */ 
-    { DA, DI, DA, DAH },       /* Y */ 
-    { DA, DA, DI, DIT }                /* Z */ 
-};
-
-// manages everything we need to know for an individual sound sample
-class FGMorse {
-
-    unsigned char dit[ DIT_SIZE ] ;
-    unsigned char dah[ DAH_SIZE ] ;
-    unsigned char space[ SPACE_SIZE ] ;
-
-public:
-
-    FGMorse();
-    ~FGMorse();
-
-    // allocate and initialize sound samples
-    bool init();
-
-    // make a FGSimpleSound morse code transmission for the specified string
-    FGSimpleSound *make_ident( const string& id );
-};
-
-
-#endif // _MORSE_HXX
-
-
diff --git a/src/Main/soundmgr.cxx b/src/Main/soundmgr.cxx
deleted file mode 100644 (file)
index 2703698..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-// soundmgr.cxx -- Sound effect management class
-//
-// Sound manager initially written by David Findlay
-// <david_j_findlay@yahoo.com.au> 2001
-//
-// C++-ified 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 <simgear/debug/logstream.hxx>
-#include <simgear/misc/fgpath.hxx>
-
-#include "globals.hxx"
-#include "soundmgr.hxx"
-
-
-// constructor
-FGSimpleSound::FGSimpleSound( string file ) {
-    FGPath slfile( globals->get_fg_root() );
-    slfile.append( file );
-    sample = new slSample ( (char *)slfile.c_str() );
-    pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
-    volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
-    pitch_envelope->setStep ( 0, 0.01, 1.0 );
-    volume_envelope->setStep ( 0, 0.01, 1.0 );
-}
-
-FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) {
-    sample = new slSample ( buffer, len );
-    pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
-    volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
-    pitch_envelope->setStep ( 0, 0.01, 1.0 );
-    volume_envelope->setStep ( 0, 0.01, 1.0 );
-}
-
-// destructor
-FGSimpleSound::~FGSimpleSound() {
-    delete pitch_envelope;
-    delete volume_envelope;
-    delete sample;
-}
-
-
-// constructor
-FGSoundMgr::FGSoundMgr() {
-    audio_sched = new slScheduler( 8000 );
-    audio_mixer = new smMixer;
-
-    FG_LOG( FG_GENERAL, FG_INFO,
-           "Rate = " << audio_sched->getRate()
-           << "  Bps = " << audio_sched->getBps()
-           << "  Stereo = " << audio_sched->getStereo() );
-}
-
-// destructor
-FGSoundMgr::~FGSoundMgr() {
-    sound_map_iterator current = sounds.begin();
-    sound_map_iterator end = sounds.end();
-    for ( ; current != end; ++current ) {
-       FGSimpleSound *s = current->second;
-       delete s->get_sample();
-       delete s;
-    }
-
-    delete audio_sched;
-    delete audio_mixer;
-}
-
-
-// initialize the sound manager
-bool FGSoundMgr::init() {
-    audio_mixer -> setMasterVolume ( 80 ) ;  /* 80% of max volume. */
-    audio_sched -> setSafetyMargin ( 1.0 ) ;
-
-    sound_map_iterator current = sounds.begin();
-    sound_map_iterator end = sounds.end();
-    for ( ; current != end; ++current ) {
-       FGSimpleSound *s = current->second;
-       delete s->get_sample();
-       delete s;
-    }
-    sounds.clear();
-
-    if ( audio_sched->not_working() ) {
-       return false;
-    } else {
-       return true;
-    }
-}
-
-
-// run the audio scheduler
-bool FGSoundMgr::update() {
-    if ( !audio_sched->not_working() ) {
-       audio_sched -> update();
-       return true;
-    } else {
-       return false;
-    }
-}
-
-
-// add a sound effect
-bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname  ) {
-    sounds[refname] = sound;
-
-    return true;
-}
-
-
-// tell the scheduler to play the indexed sample in a continuous
-// loop
-bool FGSoundMgr::play_looped( const string& refname ) {
-    sound_map_iterator it = sounds.find( refname );
-    if ( it != sounds.end() ) {
-       FGSimpleSound *sample = it->second;
-       audio_sched->loopSample( sample->get_sample() );
-       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
-                                       sample->get_pitch_envelope(),
-                                       SL_PITCH_ENVELOPE );
-       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, 
-                                       sample->get_volume_envelope(),
-                                       SL_VOLUME_ENVELOPE );
-       
-       return true;
-    } else {
-       return false;
-    }
-}
-
-
-// tell the scheduler to play the indexed sample once
-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->playSample( sample->get_sample() );
-       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
-                                       sample->get_pitch_envelope(),
-                                       SL_PITCH_ENVELOPE );
-       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, 
-                                       sample->get_volume_envelope(),
-                                       SL_VOLUME_ENVELOPE );
-       
-       return true;
-    } else {
-       return false;
-    }
-}
diff --git a/src/Main/soundmgr.hxx b/src/Main/soundmgr.hxx
deleted file mode 100644 (file)
index 6b40459..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-// soundmgr.hxx -- Sound effect management class
-//
-// Sound manager initially written by David Findlay
-// <david_j_findlay@yahoo.com.au> 2001
-//
-// C++-ified 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 _SOUNDMGR_HXX
-#define _SOUNDMGR_HXX
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-
-#include STL_STRING
-#include <map>
-
-#include <plib/sl.h>
-#include <plib/sm.h>
-
-FG_USING_STD(map);
-FG_USING_STD(string);
-
-
-// manages everything we need to know for an individual sound sample
-class FGSimpleSound {
-
-    slSample *sample;
-    slEnvelope *pitch_envelope;
-    slEnvelope *volume_envelope;
-    double pitch;
-    double volume;
-
-public:
-
-    FGSimpleSound( string file );
-    FGSimpleSound( unsigned char *buffer, int len );
-    ~FGSimpleSound();
-
-    inline double get_pitch() const { return pitch; }
-    inline void set_pitch( double p ) {
-       pitch = p;
-       pitch_envelope->setStep( 0, 0.01, pitch );
-    }
-    inline double get_volume() const { return volume; }
-    inline void set_volume( double v ) {
-       volume = v;
-       volume_envelope->setStep( 0, 0.01, volume );
-    }
-
-    inline slSample *get_sample() { return sample; }
-    inline slEnvelope *get_pitch_envelope() { return pitch_envelope; }
-    inline slEnvelope *get_volume_envelope() { return volume_envelope; }
-};
-
-
-typedef map < string, FGSimpleSound * > sound_map;
-typedef sound_map::iterator sound_map_iterator;
-typedef sound_map::const_iterator const_sound_map_iterator;
-
-
-class FGSoundMgr {
-
-    slScheduler *audio_sched;
-    smMixer *audio_mixer;
-    sound_map sounds;
-
-public:
-
-    FGSoundMgr();
-    ~FGSoundMgr();
-
-    // initialize the sound manager
-    bool init();
-
-    // run the audio scheduler
-    bool update();
-
-    // is audio working?
-    inline bool is_working() const { return !audio_sched->not_working(); }
-
-    // add a sound effect, return the index of the sound
-    bool add( FGSimpleSound *sound, 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 );
-};
-
-
-#endif // _SOUNDMGR_HXX
-
-
index 826f93d0078eec9335e93744fe4e7fc0dafbd9b2..c3eac2460bf16bfb22616c260c4e4c1b9644be17 100644 (file)
@@ -24,6 +24,7 @@ SUBDIRS = \
         $(NETWORK_DIRS) \
         Objects \
         Scenery \
+       Sound \
         Time \
         $(WEATHER_DIR) \
         Main
diff --git a/src/Sound/Makefile.am b/src/Sound/Makefile.am
new file mode 100644 (file)
index 0000000..385d43c
--- /dev/null
@@ -0,0 +1,7 @@
+noinst_LIBRARIES = libSound.a
+
+libSound_a_SOURCES = \
+       morse.cxx morse.hxx \
+       soundmgr.cxx soundmgr.hxx
+
+INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src
diff --git a/src/Sound/morse.cxx b/src/Sound/morse.cxx
new file mode 100644 (file)
index 0000000..e4cf3ef
--- /dev/null
@@ -0,0 +1,197 @@
+// morse.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 "morse.hxx"
+
+
+static const char alphabet[26][4] = {
+    { DI, DAH, end, end },     /* A */ 
+    { DA, DI, DI, DIT },       /* B */ 
+    { DA, DI, DA, DIT },       /* C */ 
+    { DA, DI, DIT, end },      /* D */ 
+    { DIT, end, end, end },    /* E */ 
+    { DI, DI, DA, DIT },       /* F */ 
+    { DA, DA, DIT, end },      /* G */ 
+    { DI, DI, DI, DIT },       /* H */ 
+    { DI, DIT, end, end },     /* I */ 
+    { DI, DA, DA, DAH },       /* J */ 
+    { DA, DI, DAH, end },      /* K */ 
+    { DI, DA, DI, DIT },       /* L */ 
+    { DA, DAH, end, end },     /* M */ 
+    { DA, DIT, end, end },     /* N */ 
+    { DA, DA, DAH, end },      /* O */ 
+    { DI, DA, DA, DIT },       /* P */ 
+    { DA, DA, DI, DAH },       /* Q */ 
+    { DI, DA, DIT, end },      /* R */ 
+    { DI, DI, DIT, end },      /* S */ 
+    { DAH, end, end, end },    /* T */ 
+    { DI, DI, DAH, end },      /* U */ 
+    { DI, DI, DI, DAH },       /* V */ 
+    { DI, DA, DAH, end },      /* W */ 
+    { DA, DI, DI, DAH },       /* X */ 
+    { DA, DI, DA, DAH },       /* Y */ 
+    { DA, DA, DI, DIT }                /* Z */ 
+};
+
+
+// constructor
+FGMorse::FGMorse() {
+}
+
+// destructor
+FGMorse::~FGMorse() {
+}
+
+
+// allocate and initialize sound samples
+bool FGMorse::init() {
+    int i, j;
+
+    // Make DIT
+    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY)) )
+           * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
+
+       /* Convert to unsigned byte */
+       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) ) )
+           / 2.0 + 0.5;
+
+       /* Convert to unsigned byte */
+       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) ) )
+           * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
+       --j;
+
+       /* Convert to unsigned byte */
+       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 ) ;
+    }
+
+    // Make DAH
+    for ( i = 0; i < TRANSITION_BYTES; ++i ) {
+       float level = ( sin( (double) i * 2.0 * M_PI / (8000.0 / FREQUENCY) ) )
+           * ((double)i / TRANSITION_BYTES) / 2.0 + 0.5;
+
+       /* Convert to unsigned byte */
+       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) ) )
+           / 2.0 + 0.5;
+
+       /* Convert to unsigned byte */
+       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) ) )
+           * ((double)j / TRANSITION_BYTES) / 2.0 + 0.5;
+       --j;
+
+       /* Convert to unsigned byte */
+       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 ) ;
+    }
+
+    // Make SPACE
+    for ( int i = 0; i < SPACE_SIZE; ++i ) {
+       space[ i ] = (unsigned char) ( 0.5 * 255 ) ;
+    }
+
+    return true;
+}
+
+
+// make a FGSimpleSound morse code transmission for the specified string
+FGSimpleSound *FGMorse::make_ident( const string& id ) {
+    char *idptr = (char *)id.c_str();
+
+    int length = 0;
+    int i, j;
+
+    // 1. Determine byte length of message
+    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 ) {
+                   length += DIT_SIZE;
+               } else if ( alphabet[c][j] == DAH ) {
+                   length += DAH_SIZE;
+               }
+           }
+           length += SPACE_SIZE;
+       } else {
+           // skip unknown character
+       }
+    }
+
+    // 2. Allocate space for the message
+    unsigned char *buffer = new unsigned char[length];
+
+    // 3. Assemble the message;
+    unsigned char *bufptr = 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;
+               } else if ( alphabet[c][j] == DAH ) {
+                   memcpy( bufptr, dah, DAH_SIZE );
+                   bufptr += DAH_SIZE;
+               }
+           }
+           memcpy( bufptr, space, SPACE_SIZE );
+           bufptr += SPACE_SIZE;
+       } else {
+           // skip unknown character
+       }
+    }
+
+    // 4. create the simple sound and return
+    FGSimpleSound *sample = new FGSimpleSound( buffer, length );
+
+    return sample;
+}
diff --git a/src/Sound/morse.hxx b/src/Sound/morse.hxx
new file mode 100644 (file)
index 0000000..c4038fc
--- /dev/null
@@ -0,0 +1,124 @@
+// morse.hxx -- 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$
+
+
+#ifndef _MORSE_HXX
+#define _MORSE_HXX
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <plib/sl.h>
+#include <plib/sm.h>
+
+#include "soundmgr.hxx"
+
+
+// Quoting from http://www.kluft.com/~ikluft/ham/morse-intro.html by
+// Ian Kluft KO6YQ <ikluft@kluft.com>
+//
+// [begin quote]
+//
+// What is the Standard for Measuring Morse Code Speed?
+// 
+// [This was adapted from the Ham Radio FAQ which used to be posted on UseNet.] 
+// 
+// The word PARIS was chosen as the standard length for CW code
+// speed. Each dit counts for one count, each dah counts for three
+// counts, intra-character spacing is one count, inter-character
+// spacing is three counts and inter-word spacing is seven counts, so
+// the word PARIS is exactly 50 counts:
+// 
+// PPPPPPPPPPPPPP    AAAAAA    RRRRRRRRRR    IIIIII    SSSSSSSSSS
+// di  da  da  di    di  da    di  da  di    di  di    di  di  di
+// 1 1 3 1 3 1 1  3  1 1 3  3  1 1 3 1 1  3  1 1 1  3  1 1 1 1 1  7 = 50
+//   ^                      ^                                     ^
+//   ^Intra-character       ^Inter-character            Inter-word^
+// 
+// So 5 words-per-minute = 250 counts-per-minute / 50 counts-per-word
+// or one count every 240 milliseconds. 13 words-per-minute is one
+// count every ~92.3 milliseconds. This method of sending code is
+// sometimes called "Slow Code", because at 5 wpm it sounds VERY SLOW.
+// 
+// The "Farnsworth" method is accomplished by sending the dits and
+// dahs and intra-character spacing at a higher speed, then increasing
+// the inter-character and inter-word spacing to slow the sending
+// speed down to the desired speed. For example, to send at 5 wpm with
+// 13 wpm characters in Farnsworth method, the dits and
+// intra-character spacing would be 92.3 milliseconds, the dah would
+// be 276.9 milliseconds, the inter-character spacing would be 1.443
+// seconds and inter-word spacing would be 3.367 seconds.
+//
+// [end quote]
+
+// Ok, back to Curt 
+
+// My formulation is based dit = 1 count, dah = 3 counts, 1 count for
+// intRA-character space, 3 counts for intER-character space.  Target
+// is 5 wpm which by the above means 1 count = 240 milliseconds.
+// 
+// AIM 1-1-7 (f) states that the frequency of the tone should be 1020
+// Hz for the VOR ident.
+
+
+static const char DI = '1';
+static const char DIT = '1';
+static const char DA = '2';
+static const char DAH = '2';
+static const char end = '0';
+
+static const int BYTES_PER_SECOND = 8000;
+static const int BEAT_LENGTH = 240; // milleseconds (5 wpm)
+// static const int BEAT_LENGTH = 92;  // milleseconds (13 wpm)
+static const int TRANSITION_BYTES = (int)(0.005 * BYTES_PER_SECOND);
+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
+
+// manages everything we need to know for an individual sound sample
+class FGMorse {
+
+    unsigned char dit[ DIT_SIZE ] ;
+    unsigned char dah[ DAH_SIZE ] ;
+    unsigned char space[ SPACE_SIZE ] ;
+
+public:
+
+    FGMorse();
+    ~FGMorse();
+
+    // allocate and initialize sound samples
+    bool init();
+
+    // make a FGSimpleSound morse code transmission for the specified string
+    FGSimpleSound *make_ident( const string& id );
+};
+
+
+#endif // _MORSE_HXX
+
+
diff --git a/src/Sound/soundmgr.cxx b/src/Sound/soundmgr.cxx
new file mode 100644 (file)
index 0000000..8b3756a
--- /dev/null
@@ -0,0 +1,167 @@
+// soundmgr.cxx -- Sound effect management class
+//
+// Sound manager initially written by David Findlay
+// <david_j_findlay@yahoo.com.au> 2001
+//
+// C++-ified 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 <simgear/debug/logstream.hxx>
+#include <simgear/misc/fgpath.hxx>
+
+#include <Main/globals.hxx>
+
+#include "soundmgr.hxx"
+
+
+// constructor
+FGSimpleSound::FGSimpleSound( string file ) {
+    FGPath slfile( globals->get_fg_root() );
+    slfile.append( file );
+    sample = new slSample ( (char *)slfile.c_str() );
+    pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+    volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+    pitch_envelope->setStep ( 0, 0.01, 1.0 );
+    volume_envelope->setStep ( 0, 0.01, 1.0 );
+}
+
+FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) {
+    sample = new slSample ( buffer, len );
+    pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+    volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
+    pitch_envelope->setStep ( 0, 0.01, 1.0 );
+    volume_envelope->setStep ( 0, 0.01, 1.0 );
+}
+
+// destructor
+FGSimpleSound::~FGSimpleSound() {
+    delete pitch_envelope;
+    delete volume_envelope;
+    delete sample;
+}
+
+
+// constructor
+FGSoundMgr::FGSoundMgr() {
+    audio_sched = new slScheduler( 8000 );
+    audio_mixer = new smMixer;
+
+    FG_LOG( FG_GENERAL, FG_INFO,
+           "Rate = " << audio_sched->getRate()
+           << "  Bps = " << audio_sched->getBps()
+           << "  Stereo = " << audio_sched->getStereo() );
+}
+
+// destructor
+FGSoundMgr::~FGSoundMgr() {
+    sound_map_iterator current = sounds.begin();
+    sound_map_iterator end = sounds.end();
+    for ( ; current != end; ++current ) {
+       FGSimpleSound *s = current->second;
+       delete s->get_sample();
+       delete s;
+    }
+
+    delete audio_sched;
+    delete audio_mixer;
+}
+
+
+// initialize the sound manager
+bool FGSoundMgr::init() {
+    audio_mixer -> setMasterVolume ( 80 ) ;  /* 80% of max volume. */
+    audio_sched -> setSafetyMargin ( 1.0 ) ;
+
+    sound_map_iterator current = sounds.begin();
+    sound_map_iterator end = sounds.end();
+    for ( ; current != end; ++current ) {
+       FGSimpleSound *s = current->second;
+       delete s->get_sample();
+       delete s;
+    }
+    sounds.clear();
+
+    if ( audio_sched->not_working() ) {
+       return false;
+    } else {
+       return true;
+    }
+}
+
+
+// run the audio scheduler
+bool FGSoundMgr::update() {
+    if ( !audio_sched->not_working() ) {
+       audio_sched -> update();
+       return true;
+    } else {
+       return false;
+    }
+}
+
+
+// add a sound effect
+bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname  ) {
+    sounds[refname] = sound;
+
+    return true;
+}
+
+
+// tell the scheduler to play the indexed sample in a continuous
+// loop
+bool FGSoundMgr::play_looped( const string& refname ) {
+    sound_map_iterator it = sounds.find( refname );
+    if ( it != sounds.end() ) {
+       FGSimpleSound *sample = it->second;
+       audio_sched->loopSample( sample->get_sample() );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
+                                       sample->get_pitch_envelope(),
+                                       SL_PITCH_ENVELOPE );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, 
+                                       sample->get_volume_envelope(),
+                                       SL_VOLUME_ENVELOPE );
+       
+       return true;
+    } else {
+       return false;
+    }
+}
+
+
+// tell the scheduler to play the indexed sample once
+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->playSample( sample->get_sample() );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, 
+                                       sample->get_pitch_envelope(),
+                                       SL_PITCH_ENVELOPE );
+       audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, 
+                                       sample->get_volume_envelope(),
+                                       SL_VOLUME_ENVELOPE );
+       
+       return true;
+    } else {
+       return false;
+    }
+}