1 // Class Caudio_alert
2 //
3 // play various canned play_sounds or wav file using port audio interface
4
5 #include "audio_alert.h"
6 #include "configuration.h"
7 #include "confdialog.h"
8 #include "rxmon.h"
9
10 #define SC_RATE 8000
11 #define PHONERING 15000
12
13 int Caudio_alert::int_phone_ring[PHONERING];
14
15 #define BEEBOO 48000
16 int Caudio_alert::int_audio_beeboo[BEEBOO];
17
bark()18 void Caudio_alert::bark()
19 {
20 try {
21 sc_audio->play_sound(int_audio_bark, BARK_SIZE, SC_RATE);
22 sc_audio->silence(0.5, SC_RATE);
23 sc_audio->play_sound(int_audio_bark, BARK_SIZE, SC_RATE);
24 } catch (...) {
25 throw;
26 }
27 }
28
checkout()29 void Caudio_alert::checkout()
30 {
31 try {
32 sc_audio->play_sound(int_audio_checkout, CHECKOUT_SIZE, SC_RATE);
33 } catch (...) {
34 throw;
35 }
36 }
37
doesnot()38 void Caudio_alert::doesnot()
39 {
40 try {
41 sc_audio->play_sound(int_audio_doesnot, DOESNOT_SIZE, SC_RATE);
42 } catch (...) {
43 throw;
44 }
45 }
46
diesel()47 void Caudio_alert::diesel()
48 {
49 try {
50 sc_audio->play_sound(int_audio_diesel, DIESEL_SIZE, SC_RATE);
51 sc_audio->silence(0.5, SC_RATE);
52 sc_audio->play_sound(int_audio_diesel, DIESEL_SIZE, SC_RATE);
53 } catch (...) {
54 throw;
55 }
56 }
57
steam_train()58 void Caudio_alert::steam_train()
59 {
60 try {
61 sc_audio->play_sound(int_steam_train, STEAM_TRAIN_SIZE, SC_RATE);
62 } catch (...) {
63 throw;
64 }
65 }
66
beeboo()67 void Caudio_alert::beeboo()
68 {
69 try {
70 sc_audio->play_sound(int_audio_beeboo, BEEBOO, SC_RATE);
71 } catch (...) {
72 throw;
73 }
74 }
75
phone()76 void Caudio_alert::phone()
77 {
78 try {
79 sc_audio->play_sound(int_phone_ring, PHONERING, SC_RATE);
80 sc_audio->silence(1.0, SC_RATE);
81 sc_audio->play_sound(int_phone_ring, PHONERING, SC_RATE);
82 } catch (...) {
83 throw;
84 }
85 }
86
dinner_bell()87 void Caudio_alert::dinner_bell()
88 {
89 try {
90 sc_audio->play_sound(int_dinner_bell, DINNER_BELL, SC_RATE);
91 } catch (...) {
92 throw;
93 }
94 }
95
tty_bell()96 void Caudio_alert::tty_bell()
97 {
98 try {
99 sc_audio->play_sound(int_tty_bell, TTY_BELL, SC_RATE);
100 } catch (...) {
101 throw;
102 }
103 }
104
standard_tone()105 void Caudio_alert::standard_tone()
106 {
107 try{
108 float st[16000];
109 float mod;
110 for (int i = 0; i < 16000; i++) {
111 mod = i < 800 ? sin(M_PI*i/1600.0) :
112 i > 15200 ? (cos(M_PI*(i - 15200)/1600.0)) : 1.0;
113 st[i] = 0.9 * mod * sin(2.0*M_PI*i*440.0/8000.0);
114 }
115 sc_audio->play_sound(st, 16000, 8000.0);
116 } catch (...) {
117 throw;
118 }
119 }
120
file(std::string sndfile)121 void Caudio_alert::file(std::string sndfile)
122 {
123 try {
124 sc_audio->play_file(sndfile);
125 } catch (...) {
126 throw;
127 }
128 }
129
create_beeboo()130 void Caudio_alert::create_beeboo()
131 {
132 float bee = 800;
133 float boo = 500;
134 float val;
135 float sr = 8000;
136 for (int i = 0; i < BEEBOO; i++) {
137 val = sin( (2.0 * M_PI * i / sr) *
138 (i / 2000 % 2 == 0 ? bee : boo));
139 if (i < 500) val *= 1.0 * i / 500;
140 if (i > (BEEBOO-500)) val *= 1.0 * (BEEBOO - i) / 500;
141 int_audio_beeboo[i] = 32500 * val;
142 }
143 }
144
create_phonering()145 void Caudio_alert::create_phonering()
146 {
147 int ntones = 60;
148 float freq = 500;
149 float sr = 8000;
150 int mod = PHONERING/ntones;
151 memset(int_phone_ring, 0, sizeof(int_phone_ring));
152 for (int i = 0; i <= (PHONERING - mod); i++)
153 int_phone_ring[i] = 32000 * fabs(sin(M_PI * i / mod)) * sin(2.0 * M_PI * freq * i / sr);;
154 }
155
alert(std::string s)156 void Caudio_alert::alert(std::string s)
157 {
158 if (s.empty()) return;
159 if (s == "bark") bark();
160 else if (s == "checkout") checkout();
161 else if (s == "doesnot" ) doesnot();
162 else if (s == "diesel" ) diesel();
163 else if (s == "steam_train") steam_train();
164 else if (s == "beeboo") beeboo();
165 else if (s == "phone") phone();
166 else if (s == "dinner_bell") dinner_bell();
167 else if (s == "rtty_bell") tty_bell();
168 else if (s == "standard_tone") standard_tone();
169 else file(s);
170 }
171
monitor(double * buffer,int len,int _sr)172 void Caudio_alert::monitor(double *buffer, int len, int _sr)
173 {
174 if (progdefaults.mon_xcvr_audio)
175 sc_audio->mon_write(buffer, len, _sr);
176 }
177
Caudio_alert()178 Caudio_alert::Caudio_alert()
179 {
180 try {
181 sc_audio = new c_portaudio;
182 create_phonering();
183 create_beeboo();
184 } catch (...) {
185 throw;
186 }
187 }
188
~Caudio_alert()189 Caudio_alert::~Caudio_alert()
190 {
191 delete sc_audio;
192 }
193
194 Caudio_alert *audio_alert = 0;
195
center_rxfilt_at_track()196 void center_rxfilt_at_track()
197 {
198 progdefaults.RxFilt_mid = active_modem->get_freq();
199
200 int bw2 = progdefaults.RxFilt_bw / 2;
201 progdefaults.RxFilt_low = progdefaults.RxFilt_mid - bw2;
202 if (progdefaults.RxFilt_low < 100) progdefaults.RxFilt_low = 100;
203
204 progdefaults.RxFilt_high = progdefaults.RxFilt_mid + bw2;
205 if (progdefaults.RxFilt_high > 4000) progdefaults.RxFilt_high = 4000;
206
207 sldrRxFilt_mid->value(progdefaults.RxFilt_mid);
208 sldrRxFilt_mid->redraw();
209
210 sldrRxFilt_low->value(progdefaults.RxFilt_low);
211 sldrRxFilt_low->redraw();
212
213 sldrRxFilt_high->value(progdefaults.RxFilt_high);
214 sldrRxFilt_high->redraw();
215
216 progdefaults.changed = true;
217
218 if (audio_alert)
219 audio_alert->init_filter();
220 }
221
reset_audio_alerts()222 void reset_audio_alerts()
223 {
224 if (!audio_alert) return;
225
226 if (progdefaults.enable_audio_alerts && audio_alert) {
227 if (audio_alert->open())
228 LOG_INFO("Opened audio alert stream on %s", progdefaults.AlertDevice.c_str());
229 else {
230 progdefaults.enable_audio_alerts = 0;
231 btn_enable_audio_alerts->value(0);
232 LOG_ERROR("Open audio device %s FAILED", progdefaults.AlertDevice.c_str());
233 }
234 } else {
235 audio_alert->close();
236 LOG_INFO("Closed audio alert device %s", progdefaults.AlertDevice.c_str());
237 }
238 }
239