FlightGear next
beacon.cxx
Go to the documentation of this file.
1// beacon.cxx -- Morse code generation class
2//
3// Written by Curtis Olson, started March 2001.
4//
5// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21
22#include <cstdlib>
23#include <cstring>
24#include <utility>
25
26#include "beacon.hxx"
27
28#include <simgear/sound/sample.hxx>
29#include <simgear/structure/exception.hxx>
30#include <simgear/debug/logstream.hxx>
31
32// constructor
36
37// destructor
40
41
42// allocate and initialize sound samples
43bool FGBeacon::init() {
44 unsigned char *ptr;
45 size_t i, len;
46
47 auto inner_buf = std::unique_ptr<unsigned char, decltype(free)*>{
48 reinterpret_cast<unsigned char*>( malloc( INNER_SIZE ) ),
49 free
50 };
51 auto middle_buf = std::unique_ptr<unsigned char, decltype(free)*>{
52 reinterpret_cast<unsigned char*>( malloc( MIDDLE_SIZE ) ),
53 free
54 };
55 auto outer_buf = std::unique_ptr<unsigned char, decltype(free)*>{
56 reinterpret_cast<unsigned char*>( malloc( OUTER_SIZE ) ),
57 free
58 };
59
60 // Make inner marker beacon sound
61 len= (int)(INNER_DIT_LEN / 2.0 );
62 unsigned char inner_dit[INNER_DIT_LEN];
63 make_tone( inner_dit, INNER_FREQ, len, INNER_DIT_LEN, TRANSITION_BYTES );
64
65 ptr = inner_buf.get();
66 for ( i = 0; i < 6; ++i ) {
67 memcpy( ptr, inner_dit, INNER_DIT_LEN );
68 ptr += INNER_DIT_LEN;
69 }
70
71 try {
72 inner = new SGSoundSample( std::move(inner_buf),
73 INNER_SIZE, BYTES_PER_SECOND );
74 inner->set_reference_dist( 10.0 );
75 inner->set_max_dist( 20.0 );
76
77 // Make middle marker beacon sound
78 len= (int)(MIDDLE_DIT_LEN / 2.0 );
79 unsigned char middle_dit[MIDDLE_DIT_LEN];
80 make_tone( middle_dit, MIDDLE_FREQ, len, MIDDLE_DIT_LEN,
82
83 len= (int)(MIDDLE_DAH_LEN * 3 / 4.0 );
84 unsigned char middle_dah[MIDDLE_DAH_LEN];
85 make_tone( middle_dah, MIDDLE_FREQ, len, MIDDLE_DAH_LEN,
87
88 ptr = (unsigned char*)middle_buf.get();
89 memcpy( ptr, middle_dit, MIDDLE_DIT_LEN );
90 ptr += MIDDLE_DIT_LEN;
91 memcpy( ptr, middle_dah, MIDDLE_DAH_LEN );
92
93 middle = new SGSoundSample( std::move(middle_buf),
94 MIDDLE_SIZE, BYTES_PER_SECOND );
95 middle->set_reference_dist( 10.0 );
96 middle->set_max_dist( 20.0 );
97
98 // Make outer marker beacon sound
99 len= (int)(OUTER_DAH_LEN * 3.0 / 4.0 );
100 unsigned char outer_dah[OUTER_DAH_LEN];
101 make_tone( outer_dah, OUTER_FREQ, len, OUTER_DAH_LEN,
103
104 ptr = (unsigned char*)outer_buf.get();
105 memcpy( ptr, outer_dah, OUTER_DAH_LEN );
106 ptr += OUTER_DAH_LEN;
107 memcpy( ptr, outer_dah, OUTER_DAH_LEN );
108
109 outer = new SGSoundSample( std::move(outer_buf), OUTER_SIZE,
111 outer->set_reference_dist( 10.0 );
112 outer->set_max_dist( 20.0 );
113 } catch ( sg_io_exception &e ) {
114 SG_LOG(SG_SOUND, SG_ALERT, e.getFormattedMessage());
115 }
116
117 return true;
118}
119
120FGBeacon * FGBeacon::_instance = NULL;
121
123{
124 if( _instance == NULL ) {
125 _instance = new FGBeacon();
126 _instance->init();
127 }
128 return _instance;
129}
130
131static const uint64_t sizeToUSec = 1000000UL / FGBeacon::BYTES_PER_SECOND;
132
134{
135 BeaconTiming r;
136
137 const uint64_t ditLen = INNER_DIT_LEN * sizeToUSec;
138 r.durationUSec = ditLen;
139 r.periodsUSec[0] = ditLen / 2;
140 r.periodsUSec[1] = ditLen / 2;
141 return r;
142}
143
145{
146 BeaconTiming r;
147 const uint64_t ditLen = MIDDLE_DIT_LEN * sizeToUSec;
148 const uint64_t dahLen = MIDDLE_DAH_LEN * sizeToUSec;
149
150 r.durationUSec = MIDDLE_SIZE * sizeToUSec;
151 r.periodsUSec[0] = ditLen;
152 r.periodsUSec[1] = ditLen;
153 r.periodsUSec[2] = (dahLen * 3) / 4;
154 r.periodsUSec[3] = dahLen - r.periodsUSec[2];
155 return r;
156}
157
159{
160 BeaconTiming r;
161 const uint64_t dahLen = OUTER_DAH_LEN * sizeToUSec;
162
163 r.durationUSec = dahLen;
164 r.periodsUSec[0] = (dahLen * 3) / 4;
165 r.periodsUSec[1] = dahLen - r.periodsUSec[0];
166 return r;
167}
#define i(x)
static const uint64_t sizeToUSec
Definition beacon.cxx:131
-- Provides marker beacon audio generation.
BeaconTiming getTimingForOuter() const
Definition beacon.cxx:158
BeaconTiming getTimingForInner() const
Definition beacon.cxx:133
FGBeacon()
Definition beacon.cxx:33
static FGBeacon * instance()
Definition beacon.cxx:122
~FGBeacon()
Definition beacon.cxx:38
BeaconTiming getTimingForMiddle() const
Definition beacon.cxx:144
static const int TRANSITION_BYTES
static void make_tone(unsigned char *buf, int freq, int len, int total_len, int trans_len)
Make a tone of specified freq and total_len with trans_len ramp in and out and only the first len byt...
static const int BYTES_PER_SECOND
std::array< uint64_t, 4 > periodsUSec
Definition beacon.hxx:111