1 // ----------------------------------------------------------------------------
2 //
3 // sound.cxx
4 //
5 // Copyright (C) 2006-2013
6 // Dave Freese, W1HKJ
7 //
8 // Copyright (C) 2007-2010
9 // Stelios Bounanos, M0GLD
10 //
11 // This file is part of fldigi.
12 //
13 // Fldigi is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // Fldigi is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
25 // ----------------------------------------------------------------------------
26
27 #include <config.h>
28
29 #include <string>
30 #include <vector>
31 #include <map>
32 #include <sstream>
33 #include <algorithm>
34 #include <iterator>
35
36 #include <cstdio>
37 #include <cstdlib>
38 #include <cerrno>
39 #include <unistd.h>
40
41 #include <fcntl.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <semaphore.h>
45 #include <limits.h>
46
47 #if USE_OSS
48 # include <sys/ioctl.h>
49 # if defined(__OpenBSD__)
50 # include <soundcard.h>
51 # else
52 # include <sys/soundcard.h>
53 # endif
54 #endif
55 #include <math.h>
56
57 #if HAVE_DLOPEN
58 # include <dlfcn.h>
59 #endif
60
61 #include "gettext.h"
62 #include "sound.h"
63 #include "configuration.h"
64 #include "status.h"
65 #include "fileselect.h"
66 #include "trx.h"
67 #include "fl_digi.h"
68 #include "threads.h"
69 #include "timeops.h"
70 #include "ringbuffer.h"
71 #include "debug.h"
72 #include "qrunner.h"
73 #include "icons.h"
74 #include "macros.h"
75 #include "util.h"
76
77 #include "estrings.h"
78
79 #include "dr_mp3.h"
80
81 #define SND_BUF_LEN 65536
82 #define SND_RW_LEN (8 * SND_BUF_LEN)
83
84 #define SNDFILE_CHANNELS 2
85
86 int sndfile_samplerate[7] = {8000, 11025, 16000, 22050, 24000, 44100, 48000};
87
88 using namespace std;
89
90 LOG_FILE_SOURCE(debug::LOG_AUDIO);
91
92 namespace SND_SUPPORT {
format_supported(int format)93 bool format_supported(int format) {
94 SF_INFO info = {
95 0,
96 sndfile_samplerate[progdefaults.wavSampleRate],
97 progdefaults.record_both_channels ? 2 : 1,
98 format, 0, 0 };
99 SNDFILE* sndf = sf_open("temp.audio", SFM_WRITE, &info);
100 sf_close(sndf);
101 remove("temp.audio");
102 if (sndf) return true;
103 return false;
104 }
105
get_file_params(std::string def_fname,std::string & fname,int & format,bool check)106 void get_file_params(std::string def_fname, std::string &fname, int &format, bool check) {
107 bool isplayback = (def_fname.find("playback") != std::string::npos);
108 std::string filters;
109 if (isplayback)
110 filters = "Audio format\t*.{mp3,wav}\n";
111 else
112 filters = "Audio format\t*.wav\n";
113 format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
114 int fsel = 0;
115 const char *fn = 0;
116 if (isplayback)
117 fn = FSEL::select(_("Audio file"), filters.c_str(), def_fname.c_str(), &fsel);
118 else
119 fn = FSEL::saveas(_("Audio file"), filters.c_str(), def_fname.c_str(), &fsel);
120 if (!fn || !*fn) {
121 fname = "";
122 return;
123 }
124 fname = fn;
125
126 if (!isplayback && (fname.find(".wav") == std::string::npos))
127 fname.append(".wav");
128
129 if (check) {
130 FILE *f = fopen(fname.c_str(), "r");
131 if (f) {
132 fclose(f);
133 int ans = fl_choice("Replace %s?", "Yes", "No", 0, fname.c_str());
134 if ( ans == 1) fname = "";
135 }
136 }
137 }
138
tag_file(SNDFILE * sndfile,const char * title)139 void tag_file(SNDFILE *sndfile, const char *title) {
140 int err;
141 if ((err = sf_set_string(sndfile, SF_STR_TITLE, title)) != 0) {
142 LOG_VERBOSE("sf_set_string STR_TITLE: %s", sf_error_number(err));
143 return;
144 }
145 sf_set_string(sndfile, SF_STR_COPYRIGHT, progdefaults.myName.c_str());
146 sf_set_string(sndfile, SF_STR_SOFTWARE, PACKAGE_NAME "-" PACKAGE_VERSION);
147 sf_set_string(sndfile, SF_STR_ARTIST, progdefaults.myCall.c_str());
148 char s[64];
149 snprintf(s, sizeof(s), "%s freq=%s",
150 active_modem->get_mode_name(), inpFreq->value());
151 sf_set_string(sndfile, SF_STR_COMMENT, s);
152 time_t t = time(0);
153 struct tm zt;
154 (void)gmtime_r(&t, &zt);
155 if (strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%Sz", &zt) > 0)
156 sf_set_string(sndfile, SF_STR_DATE, s);
157 }
158
159 };
160
SoundBase()161 SoundBase::SoundBase()
162 : sample_frequency(0),
163 txppm(progdefaults.TX_corr), rxppm(progdefaults.RX_corr),
164 tx_src_state(0), rx_src_state(0),
165 wrt_buffer(new double[SND_BUF_LEN]),
166 ofCapture(0), ifPlayback(0), ofGenerate(0)
167 {
168 memset(wrt_buffer, 0, SND_BUF_LEN * sizeof(*wrt_buffer));
169
170 int err;
171 writ_src_data_left = new SRC_DATA;
172 writ_src_data_right = new SRC_DATA;
173 play_src_data = new SRC_DATA;
174
175 writ_src_state_left = src_new(progdefaults.sample_converter, 1, &err);
176 if (writ_src_state_left == 0)
177 throw SndException(src_strerror(err));
178
179 writ_src_state_right = src_new(progdefaults.sample_converter, 1, &err);
180 if (writ_src_state_right == 0)
181 throw SndException(src_strerror(err));
182
183 play_src_state = src_new(progdefaults.sample_converter, 1, &err);
184 if (play_src_state == 0)
185 throw SndException(src_strerror(err));
186
187 if (play_src_state == 0)
188 throw SndException(src_strerror(err));
189
190 src_write_buffer_left = new float [SND_RW_LEN];
191 if (!src_write_buffer_left)
192 throw SndException(src_strerror(err));
193
194 src_write_buffer_right = new float [SND_RW_LEN];
195 if (!src_write_buffer_right)
196 throw SndException(src_strerror(err));
197
198 src_rd_inp_buffer = new float [SND_RW_LEN];
199 if (!src_rd_inp_buffer)
200 throw SndException(src_strerror(err));
201
202 src_rd_out_buffer = new float [SND_RW_LEN];
203 if (!src_rd_out_buffer)
204 throw SndException(src_strerror(err));
205
206 modem_wr_sr = modem_play_sr = 0;
207 out_pointer = src_rd_out_buffer;
208 }
209
~SoundBase()210 SoundBase::~SoundBase()
211 {
212 delete [] wrt_buffer;
213
214 if (ofGenerate)
215 sf_close(ofGenerate);
216 if (ofCapture)
217 sf_close(ofCapture);
218 if (ifPlayback)
219 sf_close(ifPlayback);
220 delete writ_src_data_left;
221 delete writ_src_data_right;
222 delete play_src_data;
223 delete [] src_write_buffer_left;
224 delete [] src_write_buffer_right;
225 delete [] src_rd_inp_buffer;
226 delete [] src_rd_out_buffer;
227 }
228
stopCapture()229 void SoundBase::stopCapture()
230 {
231 if (ofCapture) {
232 int err;
233 if ((err = sf_close(ofCapture)) != 0)
234 LOG_ERROR("sf_close error: %s", sf_error_number(err));
235 ofCapture = 0;
236 }
237 }
238
startCapture(std::string fname,int format)239 int SoundBase::startCapture(std::string fname, int format)
240 {
241 // frames (ignored), freq, channels, format, sections (ignored), seekable (ignored)
242 SF_INFO info = { 0, sndfile_samplerate[progdefaults.wavSampleRate],
243 progdefaults.record_both_channels ? 2 : 1,
244 // SNDFILE_CHANNELS,
245 format, 0, 0 };
246 if ((ofCapture = sf_open(fname.c_str(), SFM_WRITE, &info)) == NULL) {
247 LOG_ERROR("Could not write %s:%s", fname.c_str(), sf_strerror(NULL) );
248 return 0;
249 }
250 if (sf_command(ofCapture, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) != SF_TRUE)
251 LOG_ERROR("ofCapture update header command failed: %s", sf_strerror(ofCapture));
252
253 SND_SUPPORT::tag_file(ofCapture, "Captured audio");
254
255 return 1;
256 }
257
stopGenerate()258 void SoundBase::stopGenerate()
259 {
260 if (ofGenerate) {
261 int err;
262 if ((err = sf_close(ofGenerate)) != 0)
263 LOG_ERROR("sf_close error: %s", sf_error_number(err));
264 ofGenerate = 0;
265 }
266 }
267
268 //int SoundBase::startGenerate(bool val, std::string fname, int format)
startGenerate(std::string fname,int format)269 int SoundBase::startGenerate(std::string fname, int format)
270 {
271 SF_INFO info = { 0, sndfile_samplerate[progdefaults.wavSampleRate],
272 progdefaults.record_both_channels ? 2 : 1,
273 // SNDFILE_CHANNELS,
274 format, 0, 0 };
275 if ((ofGenerate = sf_open(fname.c_str(), SFM_WRITE, &info)) == NULL) {
276 LOG_ERROR("Could not write %s", fname.c_str());
277 return 0;
278 }
279 if (sf_command(ofGenerate, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) != SF_TRUE)
280 LOG_ERROR("ofGenerate update header command failed: %s", sf_strerror(ofGenerate));
281
282 SND_SUPPORT::tag_file(ofGenerate, "Generated audio");
283
284 modem_wr_sr = sample_frequency;
285
286 writ_src_data_left->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
287 src_set_ratio(writ_src_state_left, writ_src_data_left->src_ratio);
288
289 writ_src_data_right->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
290 src_set_ratio(writ_src_state_right, writ_src_data_right->src_ratio);
291
292 return 1;
293 }
294
stopPlayback()295 void SoundBase::stopPlayback()
296 {
297 if (ifPlayback) {
298 int err;
299 if ((err = sf_close(ifPlayback)) != 0)
300 LOG_ERROR("sf_close error: %s", sf_error_number(err));
301 ifPlayback = 0;
302 }
303 progdefaults.loop_playback = false;
304 }
305
startPlayback(std::string fname,int format)306 int SoundBase::startPlayback(std::string fname, int format)
307 {
308 play_info.frames = 0;
309 play_info.samplerate = 0;
310 play_info.channels = 0;
311 play_info.format = 0;
312 play_info.sections = 0;
313 play_info.seekable = 0;
314
315 if ((ifPlayback = sf_open(fname.c_str(), SFM_READ, &play_info)) == NULL) {
316 LOG_ERROR("Could not open %s:%s", fname.c_str(), sf_strerror(NULL) );
317 return 1;
318 }
319
320 LOG_VERBOSE
321 ("wav file stats:\n\
322 frames : %d\n\
323 samplerate : %d\n\
324 channels : %d\n\
325 format : %d\n\
326 sections : %d\n\
327 seekable : %d",
328 static_cast<unsigned int>(play_info.frames),
329 play_info.samplerate,
330 play_info.channels,
331 play_info.format,
332 play_info.sections,
333 play_info.seekable);
334
335 modem_play_sr = sample_frequency;
336 play_src_data->src_ratio = 1.0 * modem_play_sr / play_info.samplerate;
337 src_set_ratio(play_src_state, play_src_data->src_ratio);
338
339 LOG_VERBOSE("src ratio %f", play_src_data->src_ratio);
340
341 new_playback = true;
342
343 return 0;
344 }
345
346 // ---------------------------------------------------------------------
347 // read_file
348 // can be simplified from the equivalent read audio stream
349 // source sr is arbitrary, requested is either 8000 or 11025 depending
350 // on the modem in use
351 // read from file and resample until a "count" number of converted samples
352 // is available, or until at the end of the input file
353 // ---------------------------------------------------------------------
354 extern int fmt_auto_record;
355
read_file(SNDFILE * file,float * buf,size_t count)356 sf_count_t SoundBase::read_file(SNDFILE* file, float* buf, size_t count)
357 {
358 sf_count_t r = 0, rd_count = 0;
359 int err = 0;
360
361 if (new_playback || modem_play_sr != sample_frequency) {
362 modem_play_sr = sample_frequency;
363 play_src_data->src_ratio = 1.0 * modem_play_sr / play_info.samplerate;
364 src_set_ratio(play_src_state, play_src_data->src_ratio);
365 LOG_VERBOSE("src ratio %f", play_src_data->src_ratio);
366 new_playback = true;
367 }
368 if (new_playback) {
369 fmt_auto_record = 1;
370 }
371
372 #define RDBLKSIZE 1024
373 float rdbuf[2 * RDBLKSIZE];
374 int ch = play_info.channels;
375 while ( static_cast<size_t>(out_pointer - src_rd_out_buffer) < count) {
376 memset(src_rd_inp_buffer, 0, RDBLKSIZE * sizeof(float));
377 if (new_playback) {
378 new_playback = false;
379 rd_count = RDBLKSIZE;
380 }
381 else {
382 memset(rdbuf, 0, 2 * RDBLKSIZE * sizeof(float));
383 rd_count = sf_readf_float(file, rdbuf, RDBLKSIZE);
384 if (!rd_count) break;
385 for (int i = 0; i < rd_count; i++)
386 src_rd_inp_buffer[i] = rdbuf[i * ch];
387 }
388
389 play_src_data->data_in = src_rd_inp_buffer;
390 play_src_data->input_frames = rd_count;
391 play_src_data->data_out = out_pointer;
392 play_src_data->output_frames = SND_RW_LEN - (out_pointer - src_rd_out_buffer);
393 play_src_data->end_of_input = 0;
394
395 if ((err = src_process(play_src_state, play_src_data)) != 0)
396 throw SndException(src_strerror(err));
397
398 out_pointer += play_src_data->output_frames_gen;
399
400 }
401
402 if ( static_cast<size_t>(out_pointer - src_rd_out_buffer) >= count) {
403 memcpy(buf, src_rd_out_buffer, count * sizeof(float));
404 memmove(src_rd_out_buffer, src_rd_out_buffer + count, (SND_RW_LEN - count) * sizeof(float));
405 out_pointer -= count;
406 r = count;
407 }
408
409 if (r == 0) {
410 src_reset (play_src_state);
411 out_pointer = src_rd_out_buffer;
412 if (!progdefaults.loop_playback) {
413 stopPlayback();
414 bHighSpeed = false;
415 REQ(reset_mnuPlayback);
416 } else {
417 memset(buf, count, sizeof(*buf));
418 sf_seek(file, 0, SEEK_SET);
419 }
420 }
421 return r;
422 }
423
424 //----------------------------------------------------------------------
425 // Audio
426 // Adds ability to transmit an audio file using new macro tag:
427 // <AUDIO:path-filename>
428 // macro editor opens an OS select file dialog when the tag is
429 // selected from the pick list.
430 // suggested use:
431 // <MODEM:NULL><TX>
432 // <AUDIO:path-filename-1>
433 // <AUDIO:path-filename-2>
434 // <RX><@MODEM:BPSK31>
435 // or modem type of choice
436 // Audio file may be either wav or mp3 format, either mono or stereo
437 // any sample rate
438 // Returning to Rx stops current and any pending audio playback. Post
439 // Tx macro tags are then executed.
440 // T/R button or Escape key will abort the playback.
441 // Please use responsibly - know and understand your license limitations
442 // for transmitting audio files, especially music and/or copyrighted
443 // material.
444 //----------------------------------------------------------------------
AudioMP3(std::string fname)445 int SoundBase::AudioMP3(std::string fname)
446 {
447 drmp3_config config;
448 drmp3_uint64 frame_count;
449
450 float* mp3_buffer = drmp3_open_file_and_read_f32(
451 fname.c_str(), &config, &frame_count );
452
453 if (!mp3_buffer) {
454 LOG_ERROR("File must be mp3 float format");
455 return 0;
456 }
457
458 LOG_INFO("\n\
459 MP3 parameters\n\
460 channels: %d\n\
461 sample rate: %d\n\
462 frame count: %ld\n",
463 config.outputChannels,
464 config.outputSampleRate,
465 long(frame_count));
466
467 float *buffer = new float[2 * frame_count];
468 if (!buffer) {
469 LOG_ERROR("Could not allocate audio buffer");
470 drmp3_free(mp3_buffer);
471 return 0;
472 }
473 if (config.outputChannels == 2) {
474 float maxval = 1.0;
475 for (unsigned int n = 0; n < frame_count; n++) {
476 buffer[2 * n] = mp3_buffer[2 * n] + mp3_buffer[2 * n + 1];
477 buffer[2 * n + 1] = 0;
478 if (fabs(buffer[2 * n]) > maxval) maxval = fabs(buffer[ 2 * n]);
479 }
480 for (unsigned int n = 0; n < frame_count; n++)
481 buffer[2 * n] /= maxval;
482 } else {
483 for (unsigned int n = frame_count - 1; n >= 0; n--) {
484 buffer[2 * n] = mp3_buffer[n];
485 buffer[2 * n + 1] = 0;
486 }
487 }
488 drmp3_free(mp3_buffer);
489
490 double save_sample_rate = req_sample_rate;
491 req_sample_rate = config.outputSampleRate;
492
493 unsigned int n = 0;
494 int incr = SCBLOCKSIZE;
495 while (n < frame_count) {
496 if (active_modem->get_stopflag()) {
497 Rx_queue_execute();
498 break;
499 }
500 if (n + incr < frame_count)
501 resample_write(&buffer[n*2], incr);
502 else
503 resample_write(&buffer[n*2], frame_count - n);
504 n += incr;
505 }
506
507 delete [] buffer;
508 req_sample_rate = save_sample_rate;
509 return n;
510
511 }
512
AudioWAV(std::string fname)513 int SoundBase::AudioWAV(std::string fname)
514 {
515 SNDFILE *playback;
516 play_info.frames = 0;
517 play_info.samplerate = 0;
518 play_info.channels = 0;
519 play_info.format = 0;
520 play_info.sections = 0;
521 play_info.seekable = 0;
522
523 if ((playback = sf_open(fname.c_str(), SFM_READ, &play_info)) == NULL) {
524 LOG_ERROR("Could not open %s", fname.c_str());
525 return 0;
526 }
527 LOG_INFO("\
528 \nAudio file: %s\
529 \nframes: %ld\
530 \nsamplerate: %d\
531 \nchannels: %d",
532 fname.c_str(), (long)play_info.frames, play_info.samplerate, play_info.channels);
533
534 int ch = play_info.channels;
535
536 if (ch > 2) return 0;
537
538 int fsize = play_info.frames * 2;
539
540 float *buffer = new float[fsize];
541 if (!buffer)
542 return 0;
543 memset(buffer, 0, fsize * sizeof(*buffer));
544
545 int ret = sf_readf_float( playback, buffer, play_info.frames);
546 if (!ret) {
547 sf_close(playback);
548 delete [] buffer;
549 return 0;
550 }
551
552 double save_sample_rate = req_sample_rate;
553 req_sample_rate = play_info.samplerate;
554 if (ch == 1) {
555 for (long int n = play_info.frames - 1; n >= 0; n--) {
556 buffer[2 * n] = buffer[n];
557 buffer[2 * n + 1] = 0;
558 }
559 } else {
560 float maxval = 1.0;
561 for (long int n = play_info.frames - 1; n >= 0; n--) {
562 buffer[2 * n] = buffer[2 * n] + buffer[2 * n + 1];
563 buffer[2 * n + 1] = 0;
564 if (fabs(buffer[2*n] > maxval)) maxval = fabs(buffer[2*n]);
565 }
566 for (long int n = 0; n < play_info.frames; n++)
567 buffer[2*n] /= maxval;
568 }
569
570 unsigned int n = 0;
571 int incr = SCBLOCKSIZE;
572 while (n < play_info.frames) {
573 if (active_modem->get_stopflag()) {
574 Rx_queue_execute();
575 break;
576 }
577 if (n + incr < play_info.frames)
578 resample_write(&buffer[n*2], incr);
579 else
580 resample_write(&buffer[n*2], play_info.frames - n);
581 n += incr;
582 }
583
584 sf_close(playback);
585 delete [] buffer;
586 req_sample_rate = save_sample_rate;
587 return play_info.frames;
588 }
589
Audio(std::string fname)590 int SoundBase::Audio(std::string fname)
591 {
592 if (fname.empty())
593 return 0;
594 if ((fname.find("mp3") != std::string::npos) ||
595 (fname.find("MP3") != std::string::npos ))
596 return AudioMP3(fname);
597 else
598 return AudioWAV(fname);
599 }
600 // ---------------------------------------------------------------------
601 // write_file
602 // All sound buffer data is resampled to a specified sample rate
603 // progdefaults.wavSampleRate
604 // resultant data (left channel only) is written to a wav file
605 //----------------------------------------------------------------------
write_file(SNDFILE * file,float * bufleft,float * bufright,size_t count)606 void SoundBase::write_file(SNDFILE* file, float* bufleft, float* bufright, size_t count)
607 {
608 bool must_delete = false;
609 if (bufright == NULL || !progdefaults.record_both_channels) {
610 bufright = new float[count];
611 memset(bufright, 0, count * sizeof(float));
612 must_delete = true;
613 }
614
615 int err;
616 size_t output_size = count;
617 float *bufl = bufleft;
618 float *bufr = bufright;
619
620 if (modem_wr_sr != sample_frequency) {
621 modem_wr_sr = sample_frequency;
622 writ_src_data_left->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
623 writ_src_data_left->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
624 src_set_ratio(writ_src_state_left, writ_src_data_left->src_ratio);
625
626 writ_src_data_right->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
627 writ_src_data_right->src_ratio = 1.0 * sndfile_samplerate[progdefaults.wavSampleRate] / modem_wr_sr;
628 src_set_ratio(writ_src_state_right, writ_src_data_right->src_ratio);
629 }
630 writ_src_data_left->data_in = bufleft;
631 writ_src_data_left->input_frames = count;
632 writ_src_data_left->data_out = src_write_buffer_left;
633 writ_src_data_left->output_frames = SND_RW_LEN;
634 writ_src_data_left->end_of_input = 0;
635
636 writ_src_data_right->data_in = bufright;
637 writ_src_data_right->input_frames = count;
638 writ_src_data_right->data_out = src_write_buffer_right;
639 writ_src_data_right->output_frames = SND_RW_LEN;
640 writ_src_data_right->end_of_input = 0;
641
642 if ((err = src_process(writ_src_state_left, writ_src_data_left)) != 0) {
643 if (must_delete) {
644 delete [] bufright;
645 }
646 throw SndException(src_strerror(err));
647 }
648 if ((err = src_process(writ_src_state_right, writ_src_data_right)) != 0) {
649 if (must_delete) {
650 delete [] bufright;
651 }
652 throw SndException(src_strerror(err));
653 }
654
655 output_size = writ_src_data_left->output_frames_gen;
656 bufl = src_write_buffer_left;
657 bufr = src_write_buffer_right;
658
659 if (output_size) {
660 if (progdefaults.record_both_channels) {
661 float buffer[2*output_size];
662 memset(buffer, 0, 2 * output_size * sizeof(float));
663 for (size_t i = 0; i < output_size; i++) {
664 buffer[2*i] = bufl[i];//0.9 * bufl[i];
665 buffer[2*i + 1] = bufr[i];//0.9 * bufr[i];
666 }
667 sf_write_float(file, buffer, 2 * output_size);
668 } else {
669 sf_write_float(file, bufl, output_size);
670 }
671 }
672
673 if (must_delete) {
674 delete [] bufright;
675 }
676
677 return;
678 }
679
write_file(SNDFILE * file,double * bufleft,double * bufright,size_t count)680 void SoundBase::write_file(SNDFILE* file, double* bufleft, double *bufright, size_t count)
681 {
682 float *outbuf_l = new float[count];
683 float *outbuf_r = new float[count];
684
685 for (size_t i = 0; i < count; i++) {
686 outbuf_l[i] = bufleft[i];
687 outbuf_r[i] = (bufright ? bufright[i] : 0);
688 }
689 write_file(file, outbuf_l, outbuf_r, count);
690 delete [] outbuf_l;
691 delete [] outbuf_r;
692 return;
693 }
694
695 #if USE_OSS
696
697 #define MAXSC 32767.0f
698 #define maxsc 32000.0
699
SoundOSS(const char * dev)700 SoundOSS::SoundOSS(const char *dev ) {
701 device = dev;
702 cbuff = 0;
703 try {
704 Open(O_RDONLY);
705 getVersion();
706 getCapabilities();
707 getFormats();
708 Close();
709 }
710 catch (const SndException& e) {
711 LOG_ERROR("device %s error: %s", device.c_str(), e.what());
712 }
713
714 snd_buffer = new float [2 * SND_BUF_LEN];
715 src_buffer = new float [2 * SND_BUF_LEN];
716 cbuff = new unsigned char [4 * SND_BUF_LEN];
717
718 memset(snd_buffer, 0, 2 * SND_BUF_LEN * sizeof(*snd_buffer));
719 memset(src_buffer, 0, 2 * SND_BUF_LEN * sizeof(*src_buffer));
720 memset(cbuff, 0, 4 * SND_BUF_LEN * sizeof(*cbuff));
721
722 tx_src_data = new SRC_DATA;
723 rx_src_data = new SRC_DATA;
724
725 int err;
726 rx_src_state = src_new(progdefaults.sample_converter, 2, &err);
727 if (rx_src_state == 0)
728 throw SndException(src_strerror(err));
729
730 tx_src_state = src_new(progdefaults.sample_converter, 2, &err);
731 if (tx_src_state == 0)
732 throw SndException(src_strerror(err));
733
734 rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6);
735 src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6));
736
737 tx_src_data->src_ratio = 1.0 + txppm/1e6;
738 src_set_ratio ( tx_src_state, 1.0 + txppm/1e6);
739 }
740
~SoundOSS()741 SoundOSS::~SoundOSS()
742 {
743 Close();
744
745 delete tx_src_data;
746 delete rx_src_data;
747
748 if (rx_src_state)
749 src_delete(rx_src_state);
750 if (tx_src_state)
751 src_delete(tx_src_state);
752
753 delete [] snd_buffer;
754 delete [] src_buffer;
755 delete [] cbuff;
756 }
757
setfragsize()758 void SoundOSS::setfragsize()
759 {
760 int sndparam;
761 // Try to get ~100ms worth of samples per fragment
762 sndparam = (int)log2(sample_frequency * 0.1);
763 // double since we are using 16 bit samples
764 sndparam += 1;
765 // Unlimited amount of buffers for RX, four for TX
766 if (mode == O_RDONLY)
767 sndparam |= 0x7FFF0000;
768 else
769 sndparam |= 0x00040000;
770
771 if (ioctl(device_fd, SNDCTL_DSP_SETFRAGMENT, &sndparam) < 0)
772 throw SndException(errno);
773 }
774
Open(int md,int freq)775 int SoundOSS::Open(int md, int freq)
776 {
777 Close();
778
779 mode = md;
780 try {
781 int oflags = md;
782 # ifdef HAVE_O_CLOEXEC
783 oflags = oflags | O_CLOEXEC;
784 # endif
785
786 #ifdef __FreeBSD__
787 /*
788 * In FreeBSD sound devices e.g. /dev/dsp0.0 can only be open once
789 * whereas /dev/dsp0 can be open multiple times. fldigi tries
790 * to open /dev/dsp0.0 multiple times which fails. Also see man 4 sound.
791 * "For specific sound card access, please instead use /dev/dsp or /dev/dsp%d"
792 * This is a hack. XXX - db VA3DB
793 */
794 char *fixed_name;
795 char *p;
796 /* Look for a '.' if found, blow it away */
797 fixed_name = strdup(device.c_str());
798 p = strchr(fixed_name, '.');
799 if(p != NULL)
800 *p = '\0';
801 device_fd = fl_open(fixed_name, oflags, 0);
802 free(fixed_name);
803 #else
804 device_fd = fl_open(device.c_str(), oflags, 0);
805 #endif
806 if (device_fd == -1)
807 throw SndException(errno);
808
809 Format(AFMT_S16_LE); // default: 16 bit little endian
810 Channels(2); // 2 channels
811 Frequency(freq);
812 setfragsize();
813 }
814 catch (...) {
815 throw;
816 }
817 return 0;
818 }
819
Close(unsigned dir)820 void SoundOSS::Close(unsigned dir)
821 {
822 if (device_fd == -1)
823 return;
824 close(device_fd);
825 device_fd = -1;
826 }
827
getVersion()828 void SoundOSS::getVersion()
829 {
830 version = 0;
831
832 if (ioctl(device_fd, OSS_GETVERSION, &version) == -1) {
833 version = -1;
834 throw SndException("OSS Version");
835 }
836 }
837
getCapabilities()838 void SoundOSS::getCapabilities()
839 {
840 capability_mask = 0;
841 if (ioctl(device_fd, SNDCTL_DSP_GETCAPS, &capability_mask) == -1) {
842 capability_mask = 0;
843 throw SndException("OSS capabilities");
844 }
845 }
846
getFormats()847 void SoundOSS::getFormats()
848 {
849 format_mask = 0;
850 if (ioctl(device_fd, SNDCTL_DSP_GETFMTS, &format_mask) == -1) {
851 format_mask = 0;
852 throw SndException("OSS formats");
853 }
854 }
855
Format(int format)856 void SoundOSS::Format(int format)
857 {
858 play_format = format;
859 if (ioctl(device_fd, SNDCTL_DSP_SETFMT, &play_format) == -1) {
860 device_fd = -1;
861 formatok = false;
862 throw SndException("Unsupported snd card format");
863 }
864 formatok = true;
865 }
866
Channels(int nuchannels)867 void SoundOSS::Channels(int nuchannels)
868 {
869 channels = nuchannels;
870 if (ioctl(device_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
871 device_fd = -1;
872 throw "Snd card channel request failed";
873 }
874 }
875
Frequency(int frequency)876 void SoundOSS::Frequency(int frequency)
877 {
878 sample_frequency = frequency;
879 if (ioctl(device_fd, SNDCTL_DSP_SPEED, &sample_frequency) == -1) {
880 device_fd = -1;
881 throw SndException("Cannot set frequency");
882 }
883 }
884
BufferSize(int seconds)885 int SoundOSS::BufferSize( int seconds )
886 {
887 int bytes_per_channel = 0;
888 switch (play_format) {
889 case AFMT_MU_LAW:
890 case AFMT_A_LAW:
891 case AFMT_IMA_ADPCM:
892 bytes_per_channel = 0; /* format not supported by this program */
893 break;
894 case AFMT_S16_BE:
895 case AFMT_U16_LE:
896 case AFMT_U16_BE:
897 case AFMT_MPEG:
898 case AFMT_S16_LE:
899 bytes_per_channel = 2;
900 break;
901 case AFMT_U8:
902 case AFMT_S8:
903 bytes_per_channel = 1;
904 break;
905 }
906 return seconds * sample_frequency * bytes_per_channel * channels;
907 }
908
wait_till_finished()909 bool SoundOSS::wait_till_finished()
910 {
911 if (ioctl(device_fd, SNDCTL_DSP_POST, (void*)1) == -1 )
912 return false;
913 if (ioctl(device_fd, SNDCTL_DSP_SYNC, (void*)0) == -1)
914 return false; /* format (or ioctl()) not supported by device */
915 return true; /* all sound has been played */
916 }
917
reset_device()918 bool SoundOSS::reset_device()
919 {
920 if (ioctl(device_fd, SNDCTL_DSP_RESET, 0) == -1) {
921 device_fd = -1;
922 return false; /* format (or ioctl()) not supported by device */
923 }
924 return 1; /* sounddevice has been reset */
925 }
926
Read(float * buffer,size_t buffersize)927 size_t SoundOSS::Read(float *buffer, size_t buffersize)
928 {
929 short int *ibuff = (short int *)cbuff;
930 int numread;
931
932 numread = read(device_fd, cbuff, buffersize * 4);
933 if (numread == -1)
934 throw SndException(errno);
935
936 for (size_t i = 0; i < buffersize * 2; i++)
937 src_buffer[i] = ibuff[i] / MAXSC;
938
939 for (size_t i = 0; i < buffersize; i++)
940 buffer[i] = src_buffer[2*i + (progdefaults.ReverseRxAudio ? 1 : 0)];
941
942 if (ofCapture)
943 write_file(ofCapture, buffer, NULL, buffersize);
944 if (ifPlayback) {
945 read_file(ifPlayback, buffer, buffersize);
946 return buffersize;
947 }
948
949 if (rxppm != progdefaults.RX_corr) {
950 rxppm = progdefaults.RX_corr;
951 rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6);
952 src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6));
953 }
954
955 if (rxppm == 0)
956 return buffersize;
957
958 // process using samplerate library
959
960 rx_src_data->data_in = src_buffer;
961 rx_src_data->input_frames = buffersize;
962 rx_src_data->data_out = snd_buffer;
963 rx_src_data->output_frames = SND_BUF_LEN;
964 rx_src_data->end_of_input = 0;
965
966 if ((numread = src_process(rx_src_state, rx_src_data)) != 0)
967 throw SndException(src_strerror(numread));
968
969 numread = rx_src_data->output_frames_gen;
970
971 for (int i = 0; i < numread; i++)
972 buffer[i] = snd_buffer[2*i + (progdefaults.sig_on_right_channel ? 1 : 0)];
973
974 return numread;
975
976 }
977
Write(double * buf,size_t count)978 size_t SoundOSS::Write(double *buf, size_t count)
979 {
980 int retval;
981 short int *wbuff;
982 unsigned char *p;
983
984 if (ofGenerate)
985 write_file(ofGenerate, buf, NULL, count);
986
987 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
988 return count;
989 }
990
991
992 if (txppm != progdefaults.TX_corr) {
993 txppm = progdefaults.TX_corr;
994 tx_src_data->src_ratio = 1.0 + txppm/1e6;
995 src_set_ratio ( tx_src_state, 1.0 + txppm/1e6);
996 }
997
998 if (txppm == 0) {
999 wbuff = new short int[2*count];
1000 p = (unsigned char *)wbuff;
1001 for (size_t i = 0; i < count; i++) {
1002 wbuff[2*i] = wbuff[2*i+1] = (short int)(buf[i] * maxsc);
1003 }
1004 count *= sizeof(short int);
1005 retval = write(device_fd, p, 2*count);
1006 delete [] wbuff;
1007 if (retval == -1)
1008 throw SndException(errno);
1009 }
1010 else {
1011 float *inbuf;
1012 inbuf = new float[2*count];
1013 size_t bufsize;
1014 for (size_t i = 0; i < count; i++)
1015 inbuf[2*i] = inbuf[2*i+1] = buf[i];
1016 tx_src_data->data_in = inbuf;
1017 tx_src_data->input_frames = count;
1018 tx_src_data->data_out = src_buffer;
1019 tx_src_data->output_frames = SND_BUF_LEN;
1020 tx_src_data->end_of_input = 0;
1021
1022 retval = src_process(tx_src_state, tx_src_data);
1023 delete [] inbuf;
1024 if (retval != 0)
1025 throw SndException(src_strerror(retval));
1026
1027 bufsize = tx_src_data->output_frames_gen;
1028 wbuff = new short int[2*bufsize];
1029 p = (unsigned char *)wbuff;
1030
1031 for (size_t i = 0; i < 2*bufsize; i++)
1032 wbuff[i] = (short int)(src_buffer[i] * maxsc);
1033 int num2write = bufsize * 2 * sizeof(short int);
1034
1035 retval = write(device_fd, p, num2write);
1036 delete [] wbuff;
1037 if (retval != num2write)
1038 throw SndException(errno);
1039 retval = count;
1040 }
1041
1042 return retval;
1043 }
1044
resample_write(float * buf,size_t count)1045 size_t SoundOSS::resample_write(float *buf, size_t count)
1046 {
1047 double *samples = new double[2*count];
1048 Write(samples, count);
1049 delete [] samples;
1050 return 0;
1051 }
1052
Write_stereo(double * bufleft,double * bufright,size_t count)1053 size_t SoundOSS::Write_stereo(double *bufleft, double *bufright, size_t count)
1054 {
1055 int retval;
1056 short int *wbuff;
1057 unsigned char *p;
1058
1059 if (ofGenerate)
1060 write_file(ofGenerate, bufleft, bufright, count);
1061
1062 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
1063 return count;
1064 }
1065
1066 if (txppm != progdefaults.TX_corr) {
1067 txppm = progdefaults.TX_corr;
1068 tx_src_data->src_ratio = 1.0 + txppm/1e6;
1069 src_set_ratio ( tx_src_state, 1.0 + txppm/1e6);
1070 }
1071
1072 if (txppm == 0) {
1073 wbuff = new short int[2*count];
1074 p = (unsigned char *)wbuff;
1075 for (size_t i = 0; i < count; i++) {
1076 if (progdefaults.ReverseAudio) {
1077 wbuff[2*i+1] = (short int)(bufleft[i] * maxsc);
1078 wbuff[2*i] = (short int)(bufright[i] * maxsc);
1079 } else {
1080 wbuff[2*i] = (short int)(bufleft[i] * maxsc);
1081 wbuff[2*i+1] = (short int)(bufright[i] * maxsc);
1082 }
1083 }
1084 count *= sizeof(short int);
1085 retval = write(device_fd, p, 2*count);
1086 delete [] wbuff;
1087 if (retval == -1)
1088 throw SndException(errno);
1089 }
1090 else {
1091 float *inbuf;
1092 inbuf = new float[2*count];
1093 size_t bufsize;
1094 for (size_t i = 0; i < count; i++) {
1095 if (progdefaults.ReverseAudio) {
1096 inbuf[2*i+1] = bufleft[i];
1097 inbuf[2*i] = bufright[i];
1098 } else {
1099 inbuf[2*i] = bufleft[i];
1100 inbuf[2*i+1] = bufright[i];
1101 }
1102 }
1103 tx_src_data->data_in = inbuf;
1104 tx_src_data->input_frames = count;
1105 tx_src_data->data_out = src_buffer;
1106 tx_src_data->output_frames = SND_BUF_LEN;
1107 tx_src_data->end_of_input = 0;
1108
1109 retval = src_process(tx_src_state, tx_src_data);
1110 delete [] inbuf;
1111 if (retval != 0)
1112 throw SndException(src_strerror(retval));
1113
1114 bufsize = tx_src_data->output_frames_gen;
1115 wbuff = new short int[2*bufsize];
1116 p = (unsigned char *)wbuff;
1117
1118 for (size_t i = 0; i < 2*bufsize; i++)
1119 wbuff[i] = (short int)(src_buffer[i] * maxsc);
1120
1121 int num2write = bufsize * 2 * sizeof(short int);
1122 retval = write(device_fd, p, num2write);
1123 delete [] wbuff;
1124 if (retval != num2write)
1125 throw SndException(errno);
1126 retval = count;
1127 }
1128
1129 return retval;
1130 }
1131 #endif // USE_OSS
1132
1133
1134 #if USE_PORTAUDIO
1135
1136 bool SoundPort::pa_init = false;
1137 std::vector<const PaDeviceInfo*> SoundPort::devs;
1138
1139 static ostringstream device_text[2];
1140 static pthread_mutex_t device_mutex = PTHREAD_MUTEX_INITIALIZER;
1141
1142 map<string, vector<double> > supported_rates[2];
1143
initialize(void)1144 void SoundPort::initialize(void)
1145 {
1146 if (pa_init)
1147 return;
1148
1149 init_hostapi_ext();
1150
1151 int err;
1152 if ((err = Pa_Initialize()) != paNoError) {
1153 #if __WIN32__
1154 LOG_PERROR(win_error_string(err).c_str());
1155 #else
1156 LOG_PERROR("Portaudio Initialize error");
1157 #endif
1158 throw SndPortException(err);
1159 }
1160 pa_init = true;
1161
1162 PaDeviceIndex ndev;
1163 if ((ndev = Pa_GetDeviceCount()) < 0) {
1164 LOG_PERROR("Portaudio device count error");
1165 throw SndPortException(ndev);
1166 }
1167 if (ndev == 0) {
1168 LOG_PERROR("Portaudio, no audio devices");
1169 throw SndException(ENODEV, "No available audio devices");
1170 }
1171
1172 devs.reserve(ndev);
1173 for (PaDeviceIndex i = 0; i < ndev; i++)
1174 devs.push_back(Pa_GetDeviceInfo(i));
1175 }
terminate(void)1176 void SoundPort::terminate(void)
1177 {
1178 if (!pa_init)
1179 return;
1180 static_cast<void>(Pa_Terminate());
1181 pa_init = false;
1182 devs.clear();
1183 supported_rates[0].clear();
1184 supported_rates[1].clear();
1185 }
devices(void)1186 const std::vector<const PaDeviceInfo*>& SoundPort::devices(void)
1187 {
1188 return devs;
1189 }
devices_info(string & in,string & out)1190 void SoundPort::devices_info(string& in, string& out)
1191 {
1192 guard_lock devices_lock(&device_mutex);
1193 in = device_text[0].str();
1194 out = device_text[1].str();
1195 }
1196
get_supported_rates(const string & name,unsigned dir)1197 const vector<double>& SoundPort::get_supported_rates(const string& name, unsigned dir)
1198 {
1199 return supported_rates[dir][name];
1200 }
1201
1202
SoundPort(const char * in_dev,const char * out_dev)1203 SoundPort::SoundPort(const char *in_dev, const char *out_dev)
1204 {
1205 req_sample_rate = 0;
1206
1207 sd[0].device = in_dev;
1208 sd[0].params.channelCount = 2; // init_stream can change this to 0 or 1
1209 sd[0].stream = 0;
1210 sd[0].frames_per_buffer = paFramesPerBufferUnspecified;
1211 sd[0].dev_sample_rate = 0;
1212 sd[0].state = spa_continue;
1213 sd[0].rb = 0;
1214 sd[0].advance = 0;
1215
1216 sd[1].device = out_dev;
1217 sd[1].params.channelCount = 2;
1218 sd[1].stream = 0;
1219 sd[1].frames_per_buffer = paFramesPerBufferUnspecified;
1220 sd[1].dev_sample_rate = 0;
1221 sd[1].state = spa_continue;
1222 sd[1].rb = 0;
1223 sd[1].advance = 0;
1224
1225 sem_t** sems[] = { &sd[0].rwsem, &sd[1].rwsem };
1226 #if USE_NAMED_SEMAPHORES
1227 char sname[32];
1228 #endif
1229 for (size_t i = 0; i < sizeof(sems)/sizeof(*sems); i++) {
1230 #if USE_NAMED_SEMAPHORES
1231 unsigned int un = i;
1232 snprintf(sname, sizeof(sname), "%u-%u-%s", un, getpid(), PACKAGE_TARNAME);
1233 if ((*sems[i] = sem_open(sname, O_CREAT | O_EXCL, 0600, 0)) == (sem_t*)SEM_FAILED) {
1234 pa_perror(errno, sname);
1235 throw SndException(errno);
1236 }
1237 # if HAVE_SEM_UNLINK
1238 if (sem_unlink(sname) == -1) {
1239 pa_perror(errno, sname);
1240 throw SndException(errno);
1241 }
1242 # endif
1243 #else
1244 *sems[i] = new sem_t;
1245 if (sem_init(*sems[i], 0, 0) == -1) {
1246 #if __WIN32__
1247 int err = GetLastError();
1248 LOG_PERROR(win_error_string(err).c_str());
1249 #endif
1250 pa_perror(errno, "sem_init error");
1251 throw SndException(errno);
1252 }
1253 #endif // USE_NAMED_SEMAPHORES
1254 }
1255
1256 for (size_t i = 0; i < 2; i++) {
1257 sd[i].cmutex = new pthread_mutex_t;
1258 pthread_mutex_init(sd[i].cmutex, NULL);
1259 sd[i].ccond = new pthread_cond_t;
1260 pthread_cond_init(sd[i].ccond, NULL);
1261 }
1262
1263 tx_src_data = new SRC_DATA;
1264 src_buffer = new float[sd[1].params.channelCount * SND_BUF_LEN];
1265 fbuf = new float[2 * SND_BUF_LEN];
1266
1267 memset(src_buffer, 0, sd[1].params.channelCount * SND_BUF_LEN * sizeof(*src_buffer));
1268 memset(fbuf, 0, 2 * SND_BUF_LEN * sizeof(*fbuf));
1269 }
1270
~SoundPort()1271 SoundPort::~SoundPort()
1272 {
1273 Close();
1274
1275 sem_t* sems[] = { sd[0].rwsem, sd[1].rwsem };
1276 for (size_t i = 0; i < sizeof(sems)/sizeof(*sems); i++) {
1277 #if USE_NAMED_SEMAPHORES
1278 if (sem_close(sems[i]) == -1)
1279 LOG_PERROR("sem_close");
1280 #else
1281 if (sem_destroy(sems[i]) == -1)
1282 LOG_PERROR("sem_destroy");
1283 delete sems[i];
1284 #endif
1285 }
1286
1287 for (size_t i = 0; i < 2; i++) {
1288 if (pthread_mutex_destroy(sd[i].cmutex) == -1) {
1289 pa_perror(errno, "pthread mutex destroy");
1290 terminate(); //throw SndException(errno);
1291 }
1292 delete sd[i].cmutex;
1293 if (pthread_cond_destroy(sd[i].ccond) == -1) {
1294 pa_perror(errno, "pthread cond destroy");
1295 terminate(); //throw SndException(errno);
1296 }
1297 delete sd[i].ccond;
1298 }
1299
1300 delete sd[0].rb;
1301 delete sd[1].rb;
1302
1303 if (rx_src_state)
1304 src_delete(rx_src_state);
1305 if (tx_src_state)
1306 src_delete(tx_src_state);
1307
1308 delete tx_src_data;
1309 delete [] src_buffer;
1310 delete [] fbuf;
1311 }
1312
Open(int mode,int freq)1313 int SoundPort::Open(int mode, int freq)
1314 {
1315 int old_sample_rate = (int)req_sample_rate;
1316 req_sample_rate = sample_frequency = freq;
1317
1318 // do we need to (re)initialise the streams?
1319 int ret = 1;
1320 int sr[2] = { progdefaults.in_sample_rate, progdefaults.out_sample_rate };
1321
1322 // initialize stream if it is a JACK device, regardless of mode
1323 device_iterator idev;
1324 int device_type = 0;
1325 if (mode == O_WRONLY && (idev = name_to_device(sd[0].device, 0)) != devs.end() &&
1326 (device_type = Pa_GetHostApiInfo((*idev)->hostApi)->type) == paJACK)
1327 mode = O_RDWR;
1328 if (mode == O_RDONLY && (idev = name_to_device(sd[1].device, 1)) != devs.end() &&
1329 (device_type = Pa_GetHostApiInfo((*idev)->hostApi)->type) == paJACK)
1330 mode = O_RDWR;
1331
1332 size_t start = (mode == O_RDONLY || mode == O_RDWR) ? 0 : 1,
1333 end = (mode == O_WRONLY || mode == O_RDWR) ? 1 : 0;
1334 for (size_t i = start; i <= end; i++) {
1335 if ( !(stream_active(i) && (Pa_GetHostApiInfo((*sd[i].idev)->hostApi)->type == paJACK ||
1336 old_sample_rate == freq ||
1337 sr[i] != SAMPLE_RATE_AUTO)) ) {
1338 Close(i);
1339 try {
1340 init_stream(i);
1341 } catch (const SndException& e) {
1342 LOG_ERROR("SndException: %s", e.what());
1343 throw SndPortException(paDeviceUnavailable);
1344 }
1345 src_data_reset(i);
1346
1347 // reset the semaphore
1348 while (sem_trywait(sd[i].rwsem) == 0);
1349 if (errno && errno != EAGAIN) {
1350 pa_perror(errno, "open failed");
1351 throw SndException(errno);
1352 }
1353 start_stream(i);
1354
1355 ret = 0;
1356 }
1357 else {
1358 pause_stream(i);
1359 src_data_reset(i);
1360 sd[i].state = spa_continue;
1361 }
1362 }
1363
1364 static char pa_open_str[500];
1365 snprintf(pa_open_str, sizeof(pa_open_str),
1366 "\
1367 Port Audio open mode = %s\n\
1368 device type = %s\n\
1369 device name = %s\n\
1370 # input channels %d\n\
1371 # output channels %d",
1372 mode == O_WRONLY ? "Write" :
1373 mode == O_RDONLY ? "Read" :
1374 mode == O_RDWR ? "Read/Write" : "unknown",
1375 device_type == 0 ? "paInDevelopment" :
1376 device_type == 1 ? "paDirectSound" :
1377 device_type == 2 ? "paMME" :
1378 device_type == 3 ? "paASIO" :
1379 device_type == 4 ? "paSoundManager" :
1380 device_type == 5 ? "paCoreAudio" :
1381 device_type == 7 ? "paOSS" :
1382 device_type == 8 ? "paALSA" :
1383 device_type == 9 ? "paAL" :
1384 device_type == 10 ? "paBeOS" :
1385 device_type == 11 ? "paWDMKS" :
1386 device_type == 12 ? "paJACK" :
1387 device_type == 13 ? "paWASAPI" :
1388 device_type == 14 ? "paAudioScienceHPI" : "unknown",
1389 mode == O_WRONLY ? sd[1].device.c_str() :
1390 mode == O_RDONLY ? sd[0].device.c_str() : "unknown",
1391 sd[0].params.channelCount,
1392 sd[1].params.channelCount );
1393 LOG_INFO( "%s", pa_open_str);
1394
1395 return ret;
1396 }
1397
pause_stream(unsigned dir)1398 void SoundPort::pause_stream(unsigned dir)
1399 {
1400 if (sd[dir].stream == 0 || !stream_active(dir))
1401 return;
1402
1403 pthread_mutex_lock(sd[dir].cmutex);
1404 sd[dir].state = spa_pause;
1405 if (pthread_cond_timedwait_rel(sd[dir].ccond, sd[dir].cmutex, 5.0) == -1 && errno == ETIMEDOUT)
1406 LOG_ERROR("stream %u wedged", dir);
1407 pthread_mutex_unlock(sd[dir].cmutex);
1408 }
1409
Close(unsigned dir)1410 void SoundPort::Close(unsigned dir)
1411 {
1412 unsigned start, end;
1413 if (dir == UINT_MAX) {
1414 start = 0;
1415 end = 1;
1416 }
1417 else
1418 start = end = dir;
1419
1420 for (unsigned i = start; i <= end; i++) {
1421 if (!stream_active(i))
1422 continue;
1423
1424 pthread_mutex_lock(sd[i].cmutex);
1425 sd[i].state = spa_complete;
1426 // first wait for buffers to be drained and for the
1427 // stop callback to signal us that the stream has
1428 // been stopped
1429 if (pthread_cond_timedwait_rel(sd[i].ccond, sd[i].cmutex, 5.0) == -1 &&
1430 errno == ETIMEDOUT)
1431 LOG_ERROR("stream %u wedged", i);
1432 pthread_mutex_unlock(sd[i].cmutex);
1433 sd[i].state = spa_continue;
1434
1435 int err;
1436 if ((err = Pa_CloseStream(sd[i].stream)) != paNoError)
1437 pa_perror(err, "Pa_CloseStream");
1438
1439 sd[i].stream = 0;
1440 }
1441 }
1442
Abort(unsigned dir)1443 void SoundPort::Abort(unsigned dir)
1444 {
1445 unsigned start, end;
1446 if (dir == UINT_MAX) {
1447 start = 0;
1448 end = 1;
1449 }
1450 else
1451 start = end = dir;
1452
1453 int err;
1454 for (unsigned i = start; i <= end; i++) {
1455 if (!stream_active(i))
1456 continue;
1457 if ((err = Pa_AbortStream(sd[i].stream)) != paNoError)
1458 #if __WIN32__
1459 LOG_PERROR(win_error_string(err).c_str());
1460 #endif
1461 pa_perror(err, "Pa_AbortStream");
1462 sd[i].stream = 0;
1463 }
1464 }
1465
1466
1467 #define WAIT_FOR_COND(cond, s, t) \
1468 do { \
1469 while (!(cond)) { \
1470 if (sem_timedwait_rel(s, t) == -1) { \
1471 if (errno == ETIMEDOUT) { \
1472 timeout = true; \
1473 break; \
1474 } else if (errno == EINTR) { \
1475 continue; \
1476 } \
1477 LOG_PERROR("sem_timedwait"); \
1478 throw SndException(errno); \
1479 } \
1480 } \
1481 } while (0)
1482
1483
Read(float * buf,size_t count)1484 size_t SoundPort::Read(float *buf, size_t count)
1485 {
1486 if (ifPlayback) {
1487 read_file(ifPlayback, buf, count);
1488 if (!ofCapture) {
1489 if (!bHighSpeed)
1490 MilliSleep((long)ceil((1e3 * count) / req_sample_rate));
1491 return count;
1492 }
1493 }
1494
1495 if (rxppm != progdefaults.RX_corr)
1496 rxppm = progdefaults.RX_corr;
1497
1498 sd[0].src_ratio = req_sample_rate / (sd[0].dev_sample_rate * (1.0 + rxppm / 1e6));
1499 src_set_ratio(rx_src_state, sd[0].src_ratio);
1500
1501 size_t maxframes = (size_t)floor(sd[0].rb->length() * sd[0].src_ratio / sd[0].params.channelCount);
1502
1503 if (unlikely(count > maxframes)) {
1504 size_t n = 0;
1505 #define PA_TIMEOUT_TRIES 10
1506 int pa_timeout = PA_TIMEOUT_TRIES;
1507 // possible to lock up in this while block if the Read(...) fails
1508 while (count > maxframes) {
1509 n += Read(buf, maxframes);
1510 buf += maxframes * sd[0].params.channelCount;
1511 count -= n;//maxframes;
1512 pa_timeout--;
1513 if (pa_timeout == 0) {
1514 #if __WIN32__
1515 int err = GetLastError();
1516 LOG_PERROR(win_error_string(err).c_str());
1517 #endif
1518 pa_perror(1, "Portaudio read error #1");
1519 throw SndException("Portaudio read error 1");
1520 }
1521 }
1522 if (count > 0)
1523 n += Read(buf, count);
1524 return n;
1525 }
1526
1527 float* rbuf = fbuf;
1528 if (req_sample_rate != sd[0].dev_sample_rate || rxppm != 0) {
1529 long r;
1530 size_t n = 0;
1531 sd[0].blocksize = SCBLOCKSIZE;
1532 while (n < count) {
1533 if ((r = src_callback_read(rx_src_state, sd[0].src_ratio,
1534 count - n, rbuf + n * sd[0].params.channelCount)) == 0) {
1535 pa_perror(2, "Portaudio read error #2");
1536 throw SndException("Portaudio read error 2");
1537 }
1538 n += r;
1539 }
1540 }
1541 else {
1542 bool timeout = false;
1543 WAIT_FOR_COND( (sd[0].rb->read_space() >= count * sd[0].params.channelCount / sd[0].src_ratio), sd[0].rwsem,
1544 (MAX(1.0, 2 * count * sd[0].params.channelCount / sd->dev_sample_rate)) );
1545 if (timeout) {
1546 pa_perror(3, "Portaudio read error #3");
1547 throw SndException("Portaudio read error 3");
1548 }
1549 ringbuffer<float>::vector_type vec[2];
1550 sd[0].rb->get_rv(vec);
1551 if (vec[0].len >= count * sd[0].params.channelCount) {
1552 rbuf = vec[0].buf;
1553 sd[0].advance = vec[0].len;
1554 }
1555 else
1556 sd[0].rb->read(rbuf, count * sd[0].params.channelCount);
1557 }
1558 if (sd[0].advance) {
1559 sd[0].rb->read_advance(sd[0].advance);
1560 sd[0].advance = 0;
1561 }
1562
1563 // transfer active input channel; left == 0, right == 1
1564 size_t n;
1565 for (size_t i = 0; i < count; i++) {
1566 n = sd[0].params.channelCount * i;
1567 if (sd[0].params.channelCount == 2)
1568 n += progdefaults.ReverseRxAudio;
1569 buf[i] = rbuf[n];
1570 }
1571
1572 if (ofCapture)
1573 write_file(ofCapture, buf, NULL, count);
1574
1575 return count;
1576 }
1577
Write(double * buf,size_t count)1578 size_t SoundPort::Write(double *buf, size_t count)
1579 {
1580 if (ofGenerate)
1581 write_file(ofGenerate, buf, NULL, count);
1582
1583 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
1584 return count;
1585 }
1586
1587 // copy input to both channels if right channel enabled
1588 for (size_t i = 0; i < count; i++)
1589 if (progdefaults.sig_on_right_channel)
1590 fbuf[sd[1].params.channelCount * i] = fbuf[sd[1].params.channelCount * i + 1] = buf[i];
1591 else if (progdefaults.ReverseAudio) {
1592 fbuf[sd[1].params.channelCount * i + 1] = buf[i];
1593 fbuf[sd[1].params.channelCount * i] = 0;
1594 } else {
1595 fbuf[sd[1].params.channelCount * i] = buf[i];
1596 fbuf[sd[1].params.channelCount * i + 1] = 0;
1597 }
1598
1599 return resample_write(fbuf, count);
1600 }
1601
Write_stereo(double * bufleft,double * bufright,size_t count)1602 size_t SoundPort::Write_stereo(double *bufleft, double *bufright, size_t count)
1603 {
1604 if (sd[1].params.channelCount != 2)
1605 return Write(bufleft, count);
1606
1607 if (ofGenerate)
1608 write_file(ofCapture, bufleft, bufright, count);
1609
1610 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
1611 return count;
1612 }
1613
1614 // interleave into fbuf
1615 for (size_t i = 0; i < count; i++) {
1616 if (progdefaults.ReverseAudio) {
1617 fbuf[sd[1].params.channelCount * i + 1] = bufleft[i];
1618 fbuf[sd[1].params.channelCount * i] = bufright[i];
1619 } else {
1620 fbuf[sd[1].params.channelCount * i] = bufleft[i];
1621 fbuf[sd[1].params.channelCount * i + 1] = bufright[i];
1622 }
1623 }
1624
1625 return resample_write(fbuf, count);
1626 }
1627
1628
resample_write(float * buf,size_t count)1629 size_t SoundPort::resample_write(float* buf, size_t count)
1630 {
1631 size_t maxframes = (size_t)floor((sd[1].rb->length() / sd[1].params.channelCount) / tx_src_data->src_ratio);
1632 maxframes /= 2; // don't fill the buffer
1633
1634 if (unlikely(count > maxframes)) {
1635 size_t n = 0;
1636 #define PA_TIMEOUT_TRIES 10
1637 int pa_timeout = PA_TIMEOUT_TRIES;
1638 // possible to lock up in this while block if the resample_write(...) fails
1639 while (count > maxframes) {
1640 n += resample_write(buf, maxframes);
1641 buf += sd[1].params.channelCount * maxframes;
1642 count -= maxframes;
1643 pa_timeout--;
1644 if (pa_timeout == 0) {
1645 pa_perror(1, "Portaudio write error #1");
1646 throw SndException("Portaudio write error 1");
1647 }
1648 }
1649 if (count > 0)
1650 n += resample_write(buf, count);
1651 return n;
1652 }
1653
1654 assert(count * sd[1].params.channelCount * tx_src_data->src_ratio <= sd[1].rb->length());
1655
1656 ringbuffer<float>::vector_type vec[2];
1657 sd[1].rb->get_wv(vec);
1658 float* wbuf = buf;
1659 if (req_sample_rate != sd[1].dev_sample_rate || progdefaults.TX_corr != 0) {
1660 if (vec[0].len >= sd[1].params.channelCount * (size_t)ceil(count * tx_src_data->src_ratio))
1661 wbuf = vec[0].buf; // direct write in the rb
1662 else
1663 wbuf = src_buffer;
1664
1665 if (txppm != progdefaults.TX_corr)
1666 txppm = progdefaults.TX_corr;
1667
1668 tx_src_data->src_ratio = sd[1].dev_sample_rate * (1.0 + txppm / 1e6) / req_sample_rate;
1669 src_set_ratio(tx_src_state, tx_src_data->src_ratio);
1670
1671 tx_src_data->data_in = buf;
1672 tx_src_data->input_frames = count;
1673 tx_src_data->data_out = wbuf;
1674 tx_src_data->output_frames = (wbuf == vec[0].buf ? vec[0].len : SND_BUF_LEN);
1675 tx_src_data->end_of_input = 0;
1676 int r;
1677 if ((r = src_process(tx_src_state, tx_src_data)) != 0) {
1678 pa_perror(2, "Portaudio write error #2");
1679 throw SndException("Portaudio write error 2");
1680 }
1681 if (tx_src_data->output_frames_gen == 0) // input was too small
1682 return count;
1683
1684 count = tx_src_data->output_frames_gen;
1685 if (wbuf == vec[0].buf) { // advance write pointer and return
1686 sd[1].rb->write_advance(sd[1].params.channelCount * count);
1687 sem_trywait(sd[1].rwsem);
1688 return count;
1689 }
1690 }
1691
1692 // if we didn't do a direct resample into the rb, or didn't resample at all,
1693 // we must now copy buf into the ringbuffer, possibly waiting for space first
1694 bool timeout = false;
1695 WAIT_FOR_COND( (sd[1].rb->write_space() >= sd[1].params.channelCount * count), sd[1].rwsem,
1696 (MAX(1.0, 2 * sd[1].params.channelCount * count / sd[1].dev_sample_rate)) );
1697 if (timeout) {
1698 pa_perror(3, "Portaudio write error #3");
1699 throw SndException("Portaudio write error 3");
1700 }
1701
1702 sd[1].rb->write(wbuf, sd[1].params.channelCount * count);
1703
1704 return count;
1705 }
1706
flush(unsigned dir)1707 void SoundPort::flush(unsigned dir)
1708 {
1709 unsigned start, end;
1710 if (dir == UINT_MAX) {
1711 start = 0;
1712 end = 1;
1713 }
1714 else
1715 start = end = dir;
1716
1717 for (unsigned i = start; i <= end; i++) {
1718 if (!stream_active(i))
1719 continue;
1720
1721 pthread_mutex_lock(sd[i].cmutex);
1722 sd[i].state = spa_drain;
1723 if (pthread_cond_timedwait_rel(sd[i].ccond, sd[i].cmutex, 5.0) == -1
1724 && errno == ETIMEDOUT)
1725 LOG_ERROR("stream %u wedged", i);
1726 pthread_mutex_unlock(sd[i].cmutex);
1727 sd[i].state = spa_continue;
1728 }
1729 }
1730
src_data_reset(unsigned dir)1731 void SoundPort::src_data_reset(unsigned dir)
1732 {
1733 size_t rbsize;
1734
1735 int err;
1736 if (dir == 0) {
1737 if (rx_src_state)
1738 src_delete(rx_src_state);
1739 rx_src_state = src_callback_new(src_read_cb, progdefaults.sample_converter,
1740 sd[0].params.channelCount, &err, &sd[0]);
1741 if (!rx_src_state) {
1742 pa_perror(err, src_strerror(err));
1743 throw SndException(src_strerror(err));
1744 }
1745 sd[0].src_ratio = req_sample_rate / (sd[0].dev_sample_rate * (1.0 + rxppm / 1e6));
1746 }
1747 else if (dir == 1) {
1748 if (tx_src_state)
1749 src_delete(tx_src_state);
1750 tx_src_state = src_new(progdefaults.sample_converter, sd[1].params.channelCount, &err);
1751 if (!tx_src_state) {
1752 pa_perror(err, src_strerror(err));
1753 throw SndException(src_strerror(err));
1754 }
1755 tx_src_data->src_ratio = sd[1].dev_sample_rate * (1.0 + txppm / 1e6) / req_sample_rate;
1756 }
1757
1758 rbsize = 2 * MAX(ceil2(
1759 (unsigned)(2 * sd[dir].params.channelCount * SCBLOCKSIZE *
1760 MAX(req_sample_rate, sd[dir].dev_sample_rate) /
1761 MIN(req_sample_rate, sd[dir].dev_sample_rate))),
1762 8192);
1763 stringstream info;
1764 info << "rbsize = " << rbsize;
1765 LOG_VERBOSE("%s", info.str().c_str());
1766 if (sd[dir].rb) delete sd[dir].rb;
1767 sd[dir].rb = new ringbuffer<float>(rbsize);
1768 }
1769
src_read_cb(void * arg,float ** data)1770 long SoundPort::src_read_cb(void* arg, float** data)
1771 {
1772 struct stream_data* sd = reinterpret_cast<stream_data*>(arg);
1773
1774 // advance read pointer for previous read
1775 if (sd->advance) {
1776 sd->rb->read_advance(sd->advance);
1777 sd->advance = 0;
1778 }
1779
1780 // wait for data
1781 bool timeout = false;
1782 WAIT_FOR_COND( (sd->rb->read_space() >= (size_t)sd[0].params.channelCount * SCBLOCKSIZE), sd->rwsem,
1783 (MAX(1.0, 2 * sd[0].params.channelCount * SCBLOCKSIZE / sd->dev_sample_rate)) );
1784 if (timeout) {
1785 *data = 0;
1786 return 0;
1787 }
1788
1789 ringbuffer<float>::vector_type vec[2];
1790 sd->rb->get_rv(vec);
1791
1792 *data = vec[0].buf;
1793 sd->advance = vec[0].len;
1794
1795 return vec[0].len / sd[0].params.channelCount;
1796 }
1797
name_to_device(std::string & name,unsigned dir)1798 SoundPort::device_iterator SoundPort::name_to_device(std::string &name, unsigned dir)
1799 {
1800 device_iterator i;
1801 for (i = devs.begin(); i != devs.end(); ++i)
1802 if (name == (*i)->name && (dir ? (*i)->maxOutputChannels : (*i)->maxInputChannels))
1803 break;
1804 return i;
1805 }
1806
init_stream(unsigned dir)1807 void SoundPort::init_stream(unsigned dir)
1808 {
1809 const char* dir_str[2] = { "input", "output" };
1810 PaDeviceIndex idx = paNoDevice;
1811
1812 LOG_DEBUG("looking for device \"%s\"", sd[dir].device.c_str());
1813
1814 if ((sd[dir].idev = name_to_device(sd[dir].device, dir)) != devs.end())
1815 idx = sd[dir].idev - devs.begin();
1816 if (idx == paNoDevice) { // no match
1817 LOG_ERROR("Could not find device \"%s\", using default device", sd[dir].device.c_str());
1818 PaDeviceIndex def = (dir == 0 ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice());
1819 if (def == paNoDevice) {
1820 pa_perror(paDeviceUnavailable, "Portaudio device unavailable");
1821 throw SndPortException(paDeviceUnavailable);
1822 }
1823 sd[dir].idev = devs.begin() + def;
1824 idx = def;
1825 }
1826 else if (sd[dir].idev == devs.end()) // if we only found a near-match point the idev iterator to it
1827 sd[dir].idev = devs.begin() + idx;
1828
1829 const PaHostApiInfo* host_api = Pa_GetHostApiInfo((*sd[dir].idev)->hostApi);
1830 int max_channels = dir ? (*sd[dir].idev)->maxOutputChannels :
1831 (*sd[dir].idev)->maxInputChannels;
1832 if ((host_api->type == paALSA || host_api->type == paOSS) && max_channels == 0) {
1833 pa_perror(EBUSY, "Portaudio device busy");
1834 throw SndException(EBUSY);
1835 }
1836
1837 if (dir == 0) {
1838 sd[0].params.device = idx;
1839 sd[0].params.sampleFormat = paFloat32;
1840 sd[0].params.suggestedLatency = (*sd[dir].idev)->defaultHighInputLatency;
1841 sd[0].params.hostApiSpecificStreamInfo = NULL;
1842 if (max_channels < 2)
1843 sd[0].params.channelCount = max_channels;
1844 if (max_channels == 0) {
1845 pa_perror(EBUSY, "Portaudio device cannot open for read");
1846 throw SndException(EBUSY);
1847 }
1848 }
1849 else {
1850 sd[1].params.device = idx;
1851 sd[1].params.sampleFormat = paFloat32;
1852 if (host_api->type == paMME)
1853 sd[1].params.suggestedLatency = (*sd[dir].idev)->defaultLowOutputLatency;
1854 else
1855 sd[1].params.suggestedLatency = (*sd[dir].idev)->defaultHighOutputLatency;
1856 sd[1].params.hostApiSpecificStreamInfo = NULL;
1857 if (max_channels < 2)
1858 sd[1].params.channelCount = max_channels;
1859 }
1860
1861 const vector<double>& rates = supported_rates[dir][(*sd[dir].idev)->name];
1862 if (rates.size() <= 1)
1863 probe_supported_rates(sd[dir].idev);
1864 ostringstream ss;
1865 if (rates.size() > 1)
1866 copy(rates.begin() + 1, rates.end(), ostream_iterator<double>(ss, " "));
1867 else
1868 ss << "Unknown";
1869
1870 {
1871 guard_lock devices_lock(&device_mutex);
1872
1873 device_text[dir].str("");
1874 device_text[dir]
1875 << "index: " << idx
1876 << "\nname: " << (*sd[dir].idev)->name
1877 << "\nhost API: " << host_api->name
1878 << "\nmax input channels: " << (*sd[dir].idev)->maxInputChannels
1879 << "\nmax output channels: " << (*sd[dir].idev)->maxOutputChannels
1880 << "\ndefault sample rate: " << (*sd[dir].idev)->defaultSampleRate
1881 << "\nsupported sample rates: " << ss.str()
1882 << boolalpha
1883 << "\ninput only: " << ((*sd[dir].idev)->maxOutputChannels == 0)
1884 << "\noutput only: " << ((*sd[dir].idev)->maxInputChannels == 0)
1885 << "\nfull duplex: " << full_duplex_device(*sd[dir].idev)
1886 << "\nsystem default input: " << (idx == Pa_GetDefaultInputDevice())
1887 << "\nsystem default output: " << (idx == Pa_GetDefaultOutputDevice())
1888 << "\nhost API default input: " << (idx == host_api->defaultInputDevice)
1889 << "\nhost API default output: " << (idx == host_api->defaultOutputDevice)
1890 << "\ndefault low input latency: " << (*sd[dir].idev)->defaultLowInputLatency
1891 << "\ndefault high input latency: " << (*sd[dir].idev)->defaultHighInputLatency
1892 << "\ndefault low output latency: " << (*sd[dir].idev)->defaultLowOutputLatency
1893 << "\ndefault high output latency: " << (*sd[dir].idev)->defaultHighOutputLatency
1894 << "\n";
1895 }
1896
1897 LOG_VERBOSE("using %s (%d ch) device \"%s\":\n%s", dir_str[dir], sd[dir].params.channelCount,
1898 sd[dir].device.c_str(), device_text[dir].str().c_str());
1899
1900 sd[dir].dev_sample_rate = find_srate(dir);
1901 if (sd[dir].dev_sample_rate != req_sample_rate)
1902 LOG_DEBUG("%s: resampling %f <=> %f", dir_str[dir],
1903 sd[dir].dev_sample_rate, req_sample_rate);
1904
1905 if (progdefaults.PortFramesPerBuffer > 0) {
1906 sd[dir].frames_per_buffer = progdefaults.PortFramesPerBuffer;
1907 LOG_DEBUG("%s: frames_per_buffer=%u", dir_str[dir], sd[dir].frames_per_buffer);
1908 }
1909 }
1910
start_stream(unsigned dir)1911 void SoundPort::start_stream(unsigned dir)
1912 {
1913 int err;
1914
1915 PaStreamParameters* sp[2];
1916 sp[dir] = &sd[dir].params;
1917 sp[!dir] = NULL;
1918
1919 LOG_INFO("\n\
1920 open pa stream for %s:\n\
1921 samplerate : %.0f\n\
1922 device number : %d\n\
1923 # channels : %d\n\
1924 latency : %f\n\
1925 sample Format : paFloat32",
1926 (dir == 1 ? "write" : "read"),
1927 sd[dir].dev_sample_rate,
1928 sp[dir]->device,
1929 sp[dir]->channelCount,
1930 sp[dir]->suggestedLatency);
1931
1932 err = Pa_OpenStream(&sd[dir].stream, sp[0], sp[1],
1933 sd[dir].dev_sample_rate, sd[dir].frames_per_buffer,
1934 paNoFlag,
1935 stream_process, &sd[dir]);
1936 if (err != paNoError) {
1937 throw SndPortException(err);
1938 }
1939
1940 if ((err = Pa_SetStreamFinishedCallback(sd[dir].stream, stream_stopped)) != paNoError)
1941 throw SndPortException(err);
1942
1943 if ((err = Pa_StartStream(sd[dir].stream)) != paNoError) {
1944 pa_perror(err, "Portaudio stream start stream error");
1945 Close();
1946 throw SndPortException(err);
1947 }
1948 }
1949
1950
stream_process(const void * in,void * out,unsigned long nframes,const PaStreamCallbackTimeInfo * time_info,PaStreamCallbackFlags flags,void * data)1951 int SoundPort::stream_process(
1952 const void* in, void* out, unsigned long nframes,
1953 const PaStreamCallbackTimeInfo *time_info,
1954 PaStreamCallbackFlags flags, void* data)
1955 {
1956 struct stream_data* sd = reinterpret_cast<struct stream_data*>(data);
1957
1958 #ifndef NDEBUG
1959 struct {
1960 PaStreamCallbackFlags f;
1961 const char* s;
1962 } fa[] = { { paInputUnderflow, "Input underflow" },
1963 { paInputOverflow, "Input overflow" },
1964 { paOutputUnderflow, "Output underflow" },
1965 { paOutputOverflow, "Output overflow" }
1966 };
1967 for (size_t i = 0; i < sizeof(fa)/sizeof(*fa); i++)
1968 if (flags & fa[i].f)
1969 LOG_DEBUG("%s", fa[i].s);
1970 #endif
1971
1972 if (unlikely(sd->state == spa_abort || sd->state == spa_complete)) // finished
1973 return sd->state;
1974
1975 if (in) {
1976 switch (sd->state) {
1977 case spa_continue: // write into the rb, post rwsem if we wrote anything
1978 if (sd->rb->write(reinterpret_cast<const float*>(in), sd->params.channelCount * nframes))
1979 sem_post(sd->rwsem);
1980 break;
1981 case spa_drain: case spa_pause: // signal the cv
1982 pthread_mutex_lock(sd->cmutex);
1983 pthread_cond_signal(sd->ccond);
1984 pthread_mutex_unlock(sd->cmutex);
1985 }
1986 }
1987 else if (out) {
1988 float* outf = reinterpret_cast<float*>(out);
1989 // if we are paused just pretend that the rb was empty
1990 size_t nread = (sd->state == spa_pause) ? 0 : sd->rb->read(outf, sd->params.channelCount * nframes);
1991 memset(outf + nread, 0, (sd->params.channelCount * nframes - nread) * sizeof(float)); // fill rest with 0
1992
1993 switch (sd->state) {
1994 case spa_continue: // post rwsem if we read anything
1995 if (nread > 0)
1996 sem_post(sd->rwsem);
1997 break;
1998 case spa_drain: // signal the cv when we have emptied the buffer
1999 if (nread > 0)
2000 break;
2001 // else fall through
2002 case spa_pause:
2003 pthread_mutex_lock(sd->cmutex);
2004 pthread_cond_signal(sd->ccond);
2005 pthread_mutex_unlock(sd->cmutex);
2006 break;
2007 }
2008 }
2009
2010 return paContinue;
2011 }
2012
stream_stopped(void * data)2013 void SoundPort::stream_stopped(void* data)
2014 {
2015 struct stream_data* sd = reinterpret_cast<struct stream_data*>(data);
2016
2017 if (sd->rb)
2018 sd->rb->reset();
2019 pthread_mutex_lock(sd->cmutex);
2020 pthread_cond_signal(sd->ccond);
2021 pthread_mutex_unlock(sd->cmutex);
2022 }
2023
2024
stream_active(unsigned dir)2025 bool SoundPort::stream_active(unsigned dir)
2026 {
2027 if (!sd[dir].stream)
2028 return false;
2029
2030 int err;
2031 if ((err = Pa_IsStreamActive(sd[dir].stream)) < 0) {
2032 pa_perror(err, "Portaudio stream active error");
2033 throw SndPortException(err);
2034 }
2035 return err == 1;
2036 }
2037
full_duplex_device(const PaDeviceInfo * dev)2038 bool SoundPort::full_duplex_device(const PaDeviceInfo* dev)
2039 {
2040 return dev->maxInputChannels > 0 && dev->maxOutputChannels > 0;
2041 }
2042
must_close(int dir)2043 bool SoundPort::must_close(int dir)
2044 {
2045 return Pa_GetHostApiInfo((*sd[dir].idev)->hostApi)->type != paJACK;
2046 }
2047
find_srate(unsigned dir)2048 double SoundPort::find_srate(unsigned dir)
2049 {
2050 int sr = (dir == 0 ? progdefaults.in_sample_rate : progdefaults.out_sample_rate);
2051 switch (sr) {
2052 case SAMPLE_RATE_UNSET: case SAMPLE_RATE_AUTO:
2053 break;
2054 case SAMPLE_RATE_NATIVE:
2055 return (*sd[dir].idev)->defaultSampleRate;
2056 default:
2057 return sr;
2058 }
2059
2060 const vector<double>& rates = supported_rates[dir][(*sd[dir].idev)->name];
2061 for (vector<double>::const_iterator i = rates.begin(); i != rates.end(); i++)
2062 if (req_sample_rate == *i || (*sd[dir].idev)->defaultSampleRate == *i)
2063 return *i;
2064
2065 pa_perror(0, "Portaudio - no supported sample rate found");
2066 throw SndException("No supported sample rate found");
2067 }
2068
probe_supported_rates(const device_iterator & idev)2069 void SoundPort::probe_supported_rates(const device_iterator& idev)
2070 {
2071 PaStreamParameters params[2];
2072 params[0].device = params[1].device = idev - devs.begin();
2073 params[0].channelCount = 2;
2074 params[1].channelCount = 2;
2075 params[0].sampleFormat = params[1].sampleFormat = paFloat32;
2076 params[0].suggestedLatency = (*idev)->defaultHighInputLatency;
2077 params[1].suggestedLatency = (*idev)->defaultHighOutputLatency;
2078 params[0].hostApiSpecificStreamInfo = params[1].hostApiSpecificStreamInfo = NULL;
2079
2080 supported_rates[0][(*idev)->name].clear();
2081 supported_rates[1][(*idev)->name].clear();
2082 supported_rates[0][(*idev)->name].push_back((*idev)->defaultSampleRate);
2083 supported_rates[1][(*idev)->name].push_back((*idev)->defaultSampleRate);
2084 extern double std_sample_rates[];
2085 for (const double* r = std_sample_rates; *r > 0.0; r++) {
2086 if (Pa_IsFormatSupported(¶ms[0], NULL, *r) == paFormatIsSupported)
2087 supported_rates[0][(*idev)->name].push_back(*r);
2088 if (Pa_IsFormatSupported(NULL, ¶ms[1], *r) == paFormatIsSupported)
2089 supported_rates[1][(*idev)->name].push_back(*r);
2090 }
2091 }
2092
pa_perror(int err,const char * str)2093 void SoundPort::pa_perror(int err, const char* str)
2094 {
2095 if (str)
2096 LOG_ERROR("%s: %s", str, Pa_GetErrorText(err));
2097
2098 if (err == paUnanticipatedHostError) {
2099 const PaHostErrorInfo* hosterr = Pa_GetLastHostErrorInfo();
2100 PaHostApiIndex i = Pa_HostApiTypeIdToHostApiIndex(hosterr->hostApiType);
2101
2102 if (i < 0) { // PA failed without setting its "last host error" info. Sigh...
2103 LOG_ERROR("Host API error info not available");
2104 if ( ((sd[0].stream && Pa_GetHostApiInfo((*sd[0].idev)->hostApi)->type == paOSS) ||
2105 (sd[1].stream && Pa_GetHostApiInfo((*sd[1].idev)->hostApi)->type == paOSS)) &&
2106 errno )
2107 LOG_ERROR("Possible OSS error %d: %s", errno, strerror(errno));
2108 }
2109 else
2110 LOG_ERROR("%s error %ld: %s", Pa_GetHostApiInfo(i)->name,
2111 hosterr->errorCode, hosterr->errorText);
2112 }
2113 }
2114
init_hostapi_ext(void)2115 void SoundPort::init_hostapi_ext(void)
2116 {
2117 #if HAVE_DLOPEN && !defined(__WOE32__)
2118 void* handle = dlopen(NULL, RTLD_LAZY);
2119 if (!handle)
2120 return;
2121
2122 PaError (*set_jack_client_name)(const char*);
2123 const char* err = dlerror();
2124 set_jack_client_name = (PaError (*)(const char*))dlsym(handle, "PaJack_SetClientName");
2125 if (!(err = dlerror()))
2126 set_jack_client_name(main_window_title.c_str());
2127 # ifndef NDEBUG
2128 else
2129 LOG_VERBOSE("dlsym(PaJack_SetClientName) error: %s", err);
2130 # endif
2131 #endif
2132 }
2133
2134 #endif // USE_PORTAUDIO
2135
2136
2137 #if USE_PULSEAUDIO
2138
SoundPulse(const char * dev)2139 SoundPulse::SoundPulse(const char *dev)
2140 {
2141 sd[0].stream = 0;
2142 sd[0].stream_params.channels = 2;
2143 sd[0].dir = PA_STREAM_RECORD;
2144 sd[0].stream_params.format = PA_SAMPLE_FLOAT32LE;
2145 sd[0].buffer_attrs.maxlength = (uint32_t)-1;
2146 sd[0].buffer_attrs.minreq = (uint32_t)-1;
2147 sd[0].buffer_attrs.prebuf = (uint32_t)-1;
2148 sd[0].buffer_attrs.fragsize = SCBLOCKSIZE * sizeof(float);
2149 sd[0].buffer_attrs.tlength = (uint32_t)-1;
2150
2151 sd[1].stream = 0;
2152 sd[1].dir = PA_STREAM_PLAYBACK;
2153 sd[1].stream_params.format = PA_SAMPLE_FLOAT32LE;
2154 sd[1].stream_params.channels = 2;
2155 sd[1].buffer_attrs.maxlength = (uint32_t)-1;
2156 sd[1].buffer_attrs.minreq = (uint32_t)-1;
2157 sd[1].buffer_attrs.prebuf = (uint32_t)-1;
2158 sd[1].buffer_attrs.fragsize = (uint32_t)-1;
2159 sd[1].buffer_attrs.tlength = SCBLOCKSIZE * sizeof(float);
2160
2161 tx_src_data = new SRC_DATA;
2162
2163 snd_buffer = new float[sd[0].stream_params.channels * SND_BUF_LEN];
2164 rbuf = new float[sd[0].stream_params.channels * SND_BUF_LEN];
2165
2166 src_buffer = new float[sd[1].stream_params.channels * SND_BUF_LEN];
2167 fbuf = new float[sd[1].stream_params.channels * SND_BUF_LEN];
2168
2169 memset(snd_buffer, 0, sd[0].stream_params.channels * SND_BUF_LEN * sizeof(*snd_buffer));
2170 memset(rbuf, 0, sd[0].stream_params.channels * SND_BUF_LEN * sizeof(*rbuf));
2171
2172 memset(src_buffer, 0, sd[1].stream_params.channels * SND_BUF_LEN * sizeof(*src_buffer));
2173 memset(fbuf, 0, sd[1].stream_params.channels * SND_BUF_LEN * sizeof(*fbuf));
2174 }
2175
~SoundPulse()2176 SoundPulse::~SoundPulse()
2177 {
2178 Close();
2179
2180 delete tx_src_data;
2181 if (rx_src_state)
2182 src_delete(rx_src_state);
2183 if (tx_src_state)
2184 src_delete(tx_src_state);
2185
2186 delete [] snd_buffer;
2187 delete [] src_buffer;
2188 delete [] fbuf;
2189 delete [] rbuf;
2190 }
2191
Open(int dir,int freq)2192 int SoundPulse::Open(int dir, int freq)
2193 {
2194 const char* server = (progdefaults.PulseServer.length() ?
2195 progdefaults.PulseServer.c_str() : NULL);
2196 char sname[32];
2197 int err;
2198
2199 sample_frequency = freq;
2200
2201 src_data_reset(1 << O_RDONLY | 1 << O_WRONLY);
2202 if ((unsigned)freq != sd[dir].stream_params.rate)
2203 Close(dir);
2204
2205 sd[dir].stream_params.rate = freq;
2206 snprintf(sname, sizeof(sname), "%s (%u)", (dir ? "playback" : "capture"), getpid());
2207 setenv("PULSE_PROP_application.icon_name", PACKAGE_TARNAME, 1);
2208 sd[dir].stream = pa_simple_new(
2209 server, // server address
2210 main_window_title.c_str(), // application name
2211 sd[dir].dir, // playback / record
2212 NULL, // device (default)
2213 sname, // system description
2214 &sd[dir].stream_params, // sample format
2215 NULL, // channel map (default)
2216 &sd[dir].buffer_attrs, // buffering attributes
2217 &err); // return address for error code
2218 if (!sd[dir].stream)
2219 throw SndPulseException(err);
2220
2221 return 0;
2222 }
2223
Close(unsigned dir)2224 void SoundPulse::Close(unsigned dir)
2225 {
2226 if (dir == 1 || dir == UINT_MAX)
2227 flush(1);
2228 Abort(dir);
2229 }
2230
Abort(unsigned dir)2231 void SoundPulse::Abort(unsigned dir)
2232 {
2233 unsigned start, end;
2234 if (dir == UINT_MAX) {
2235 start = 0;
2236 end = 1;
2237 }
2238 else
2239 start = end = dir;
2240
2241 for (unsigned i = start; i <= end; i++) {
2242 if (sd[i].stream) {
2243 pa_simple_free(sd[i].stream);
2244 sd[i].stream = 0;
2245 }
2246 }
2247
2248 }
2249
flush(unsigned dir)2250 void SoundPulse::flush(unsigned dir)
2251 {
2252 int err = PA_OK;
2253 if ((dir == 1 || dir == UINT_MAX) && sd[1].stream) {
2254 // wait for audio to finish playing
2255 MilliSleep(SCBLOCKSIZE * 1000 / sd[1].stream_params.rate);
2256 pa_simple_flush(sd[1].stream, &err);
2257 }
2258
2259 if ((dir == 0 || dir == UINT_MAX) && sd[0].stream) {
2260 // We need to flush the captured audio that PA has been
2261 // buffering for us while we were transmitting. We will use
2262 // pa_simple_get_latency() which, contrary to the docs, also
2263 // works for capture streams. It tells us how much earlier the
2264 // data that would be returned by pa_simple_read() was actually
2265 // captured, and we read and discard all that data.
2266 pa_usec_t t = pa_simple_get_latency(sd[0].stream, &err);
2267 if (t && err == PA_OK) {
2268 size_t bytes = pa_usec_to_bytes(t, &sd[0].stream_params);
2269 while (bytes > SND_BUF_LEN) {
2270 pa_simple_read(sd[0].stream, snd_buffer, SND_BUF_LEN, &err);
2271 if (err != PA_OK)
2272 break;
2273 bytes -= SND_BUF_LEN;
2274 }
2275 if (bytes)
2276 pa_simple_read(sd[0].stream, snd_buffer, bytes, &err);
2277 }
2278 }
2279 }
2280
Write(double * buf,size_t count)2281 size_t SoundPulse::Write(double* buf, size_t count)
2282 {
2283 if (ofGenerate)
2284 write_file(ofGenerate, buf, NULL, count);
2285
2286 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
2287 return count;
2288 }
2289
2290 // copy input to both channels
2291 for (size_t i = 0; i < count; i++)
2292 if (progdefaults.sig_on_right_channel)
2293 fbuf[sd[1].stream_params.channels * i] = fbuf[sd[1].stream_params.channels * i + 1] = buf[i];
2294 else if (progdefaults.ReverseAudio) {
2295 fbuf[sd[1].stream_params.channels * i + 1] = buf[i];
2296 fbuf[sd[1].stream_params.channels * i] = 0;
2297 } else {
2298 fbuf[sd[1].stream_params.channels * i] = buf[i];
2299 fbuf[sd[1].stream_params.channels * i + 1] = 0;
2300 }
2301
2302 return resample_write(fbuf, count);
2303 }
2304
Write_stereo(double * bufleft,double * bufright,size_t count)2305 size_t SoundPulse::Write_stereo(double* bufleft, double* bufright, size_t count)
2306 {
2307 if (sd[1].stream_params.channels != 2)
2308 return Write(bufleft, count);
2309
2310 if (ofGenerate)
2311 write_file(ofGenerate, bufleft, bufright, count);
2312
2313 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
2314 return count;
2315 }
2316
2317 for (size_t i = 0; i < count; i++) {
2318 if (progdefaults.ReverseAudio) {
2319 fbuf[sd[1].stream_params.channels * i + 1] = bufleft[i];
2320 fbuf[sd[1].stream_params.channels * i] = bufright[i];
2321 } else {
2322 fbuf[sd[1].stream_params.channels * i] = bufleft[i];
2323 fbuf[sd[1].stream_params.channels * i + 1] = bufright[i];
2324 }
2325 }
2326
2327 return resample_write(fbuf, count);
2328 }
2329
resample_write(float * buf,size_t count)2330 size_t SoundPulse::resample_write(float* buf, size_t count)
2331 {
2332 int err;
2333 float *wbuf = buf;
2334
2335 if (progdefaults.TX_corr != 0) {
2336 if (txppm != progdefaults.TX_corr) {
2337 txppm = progdefaults.TX_corr;
2338 tx_src_data->src_ratio = 1.0 + txppm / 1e6;
2339 src_set_ratio(tx_src_state, tx_src_data->src_ratio);
2340 }
2341 tx_src_data->data_in = wbuf;
2342 tx_src_data->input_frames = count;
2343 tx_src_data->data_out = src_buffer;
2344 tx_src_data->output_frames = SND_BUF_LEN;
2345 tx_src_data->end_of_input = 0;
2346 if ((err = src_process(tx_src_state, tx_src_data)) != 0)
2347 throw SndException(src_strerror(err));
2348 if (tx_src_data->output_frames_gen == 0) // input was too small
2349 return count;
2350
2351 wbuf = tx_src_data->data_out;
2352 count = tx_src_data->output_frames_gen;
2353 }
2354
2355 if (!active_modem) return count;
2356
2357 if (pa_simple_write(sd[1].stream, wbuf, count * sd[1].stream_params.channels * sizeof(float), &err) == -1)
2358 throw SndPulseException(err);
2359
2360 return count;
2361 }
2362
src_read_cb(void * arg,float ** data)2363 long SoundPulse::src_read_cb(void* arg, float** data)
2364 {
2365 SoundPulse* p = reinterpret_cast<SoundPulse*>(arg);
2366
2367 int err;
2368 int nread = 0;
2369 if ((nread = pa_simple_read(p->sd[0].stream, p->snd_buffer,
2370 p->sd[0].stream_params.channels * sizeof(float) * p->sd[0].blocksize, &err)) == -1) {
2371 LOG_ERROR("%s", pa_strerror(err));
2372 *data = 0;
2373 return 0;
2374 }
2375
2376 *data = p->snd_buffer;
2377 return p->sd[0].blocksize;
2378 }
2379
Read(float * buf,size_t count)2380 size_t SoundPulse::Read(float *buf, size_t count)
2381 {
2382 if (ifPlayback) {
2383 read_file(ifPlayback, buf, count);
2384 if (!ofCapture) {
2385 flush(0);
2386 if (!bHighSpeed)
2387 MilliSleep((long)ceil((1e3 * count) / sample_frequency));
2388 return count;
2389 }
2390 }
2391
2392 size_t n = 0;
2393 long r = 0;
2394
2395 if (progdefaults.RX_corr != 0) {
2396 if (rxppm != progdefaults.RX_corr) {
2397 rxppm = progdefaults.RX_corr;
2398 sd[0].src_ratio = 1.0 / (1.0 + rxppm / 1e6);
2399 src_set_ratio(rx_src_state, sd[0].src_ratio);
2400 }
2401 sd[0].blocksize = SCBLOCKSIZE;
2402 while (n < count) {
2403 if ((r = src_callback_read(rx_src_state, sd[0].src_ratio, count - n, rbuf + n)) == 0)
2404 break;
2405 n += r;
2406 }
2407 }
2408 else {
2409 int err;
2410 if ((r = pa_simple_read(sd[0].stream, rbuf,
2411 sd[0].stream_params.channels * sizeof(float) * count, &err)) == -1)
2412 throw SndPulseException(err);
2413 }
2414
2415 // transfer active input channel; left == 0, right == 1
2416 size_t i = 0;
2417 if (sd[0].stream_params.channels == 2) n = progdefaults.ReverseRxAudio;
2418 else n = 0;
2419 while (i < count) {
2420 buf[i] = rbuf[n];
2421 i++;
2422 n += sd[0].stream_params.channels;
2423 }
2424
2425 if (ofCapture)
2426 write_file(ofCapture, buf, NULL, count);
2427
2428 return count;
2429 }
2430
src_data_reset(int mode)2431 void SoundPulse::src_data_reset(int mode)
2432 {
2433 int err;
2434 if (mode & 1 << O_RDONLY) {
2435 if (rx_src_state)
2436 src_delete(rx_src_state);
2437 rx_src_state = src_callback_new(src_read_cb, progdefaults.sample_converter,
2438 sd[0].stream_params.channels, &err, this);
2439 if (!rx_src_state)
2440 throw SndException(src_strerror(err));
2441 sd[0].src_ratio = 1.0 / (1.0 + rxppm / 1e6);
2442 }
2443 if (mode & 1 << O_WRONLY) {
2444 if (tx_src_state)
2445 src_delete(tx_src_state);
2446 tx_src_state = src_new(progdefaults.sample_converter, sd[1].stream_params.channels, &err);
2447 if (!tx_src_state)
2448 throw SndException(src_strerror(err));
2449 tx_src_data->src_ratio = 1.0 + txppm / 1e6;
2450 }
2451 }
2452
2453 #endif // USE_PULSEAUDIO
2454
2455
Write(double * buf,size_t count)2456 size_t SoundNull::Write(double* buf, size_t count)
2457 {
2458 if (ofGenerate)
2459 write_file(ofGenerate, buf, NULL, count);
2460
2461 if (PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST) {
2462 return count;
2463 }
2464
2465 MilliSleep((long)ceil((1e3 * count) / sample_frequency));
2466
2467 return count;
2468 }
2469
Write_stereo(double * bufleft,double * bufright,size_t count)2470 size_t SoundNull::Write_stereo(double* bufleft, double* bufright, size_t count)
2471 {
2472 if (ofGenerate)
2473 write_file(ofGenerate, bufleft, bufright, count);
2474
2475 MilliSleep((long)ceil((1e3 * count) / sample_frequency));
2476
2477 return count ? count : 1;
2478 }
2479
Read(float * buf,size_t count)2480 size_t SoundNull::Read(float *buf, size_t count)
2481 {
2482 if (ifPlayback)
2483 read_file(ifPlayback, buf, count);
2484 else
2485 memset(buf, 0, count * sizeof(*buf));
2486 if (ofCapture)
2487 write_file(ofCapture, buf, NULL, count);
2488 if (!bHighSpeed)
2489 MilliSleep((long)ceil((1e3 * count) / sample_frequency));
2490
2491 return count;
2492
2493 }
2494
flush(unsigned)2495 void SoundNull::flush(unsigned)
2496 {
2497 if (ofGenerate)
2498 sf_close(ofGenerate);
2499 }
2500
2501