Add echo test feature to check mobile phone's mic + speaker
Add '-e' to command line option, but do not select MNCC nor call device
This commit is contained in:
@@ -203,9 +203,10 @@ typedef struct call {
|
|||||||
int test_audio_pos; /* position for test tone toward mobile */
|
int test_audio_pos; /* position for test tone toward mobile */
|
||||||
int dial_digits; /* number of digits to be dialed */
|
int dial_digits; /* number of digits to be dialed */
|
||||||
int loopback; /* loopback test for echo */
|
int loopback; /* loopback test for echo */
|
||||||
int use_mncc_sock;
|
int echo_test; /* send echo back to mobile phone */
|
||||||
int send_patterns;
|
int use_mncc_sock; /* use MNCC socket instead of built-in call control */
|
||||||
int release_on_disconnect;
|
int send_patterns; /* send patterns towards fixed network */
|
||||||
|
int release_on_disconnect; /* release towards mobile phone, if MNCC call disconnects, don't send disconnect tone */
|
||||||
|
|
||||||
} call_t;
|
} call_t;
|
||||||
|
|
||||||
@@ -486,7 +487,7 @@ static void process_timeout(struct timer *timer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect)
|
int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect, int echo_test)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
@@ -497,13 +498,30 @@ int call_init(const char *station_id, const char *audiodev, int samplerate, int
|
|||||||
call.latspl = latency * samplerate / 1000;
|
call.latspl = latency * samplerate / 1000;
|
||||||
call.dial_digits = dial_digits;
|
call.dial_digits = dial_digits;
|
||||||
call.loopback = loopback;
|
call.loopback = loopback;
|
||||||
|
call.echo_test = echo_test;
|
||||||
call.use_mncc_sock = use_mncc_sock;
|
call.use_mncc_sock = use_mncc_sock;
|
||||||
call.send_patterns = send_patterns;
|
call.send_patterns = send_patterns;
|
||||||
call.release_on_disconnect = release_on_disconnect;
|
call.release_on_disconnect = release_on_disconnect;
|
||||||
call.samplerate = samplerate;
|
call.samplerate = samplerate;
|
||||||
strncpy(call.audiodev, audiodev, sizeof(call.audiodev) - 1);
|
strncpy(call.audiodev, audiodev, sizeof(call.audiodev) - 1);
|
||||||
|
|
||||||
if (call.use_mncc_sock)
|
if (use_mncc_sock && audiodev[0]) {
|
||||||
|
PDEBUG(DSENDER, DEBUG_ERROR, "You selected MNCC interface, but it cannot be used with call device (headset).\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (use_mncc_sock && echo_test) {
|
||||||
|
PDEBUG(DSENDER, DEBUG_ERROR, "You selected MNCC interface, but it cannot be used with echo test.\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (audiodev[0] && echo_test) {
|
||||||
|
PDEBUG(DSENDER, DEBUG_ERROR, "You selected call device (headset), but it cannot be used with echo test.\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_mncc_sock)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!audiodev[0])
|
if (!audiodev[0])
|
||||||
@@ -963,6 +981,7 @@ void call_tx_audio(int callref, sample_t *samples, int count)
|
|||||||
if (!callref)
|
if (!callref)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* is MNCC us used, forward audio */
|
||||||
if (call.use_mncc_sock) {
|
if (call.use_mncc_sock) {
|
||||||
uint8_t buf[sizeof(struct gsm_data_frame) + count * sizeof(int16_t)];
|
uint8_t buf[sizeof(struct gsm_data_frame) + count * sizeof(int16_t)];
|
||||||
struct gsm_data_frame *data = (struct gsm_data_frame *)buf;
|
struct gsm_data_frame *data = (struct gsm_data_frame *)buf;
|
||||||
@@ -981,15 +1000,17 @@ void call_tx_audio(int callref, sample_t *samples, int count)
|
|||||||
samples_to_int16((int16_t *)data->data, samples, count);
|
samples_to_int16((int16_t *)data->data, samples, count);
|
||||||
|
|
||||||
mncc_write(buf, sizeof(buf));
|
mncc_write(buf, sizeof(buf));
|
||||||
return;
|
} else
|
||||||
}
|
/* else, save audio from transceiver to jitter buffer */
|
||||||
|
|
||||||
/* save audio from transceiver to jitter buffer */
|
|
||||||
if (call.sound) {
|
if (call.sound) {
|
||||||
sample_t up[(int)((double)count * call.srstate.factor + 0.5) + 10];
|
sample_t up[(int)((double)count * call.srstate.factor + 0.5) + 10];
|
||||||
count = samplerate_upsample(&call.srstate, samples, count, up);
|
count = samplerate_upsample(&call.srstate, samples, count, up);
|
||||||
jitter_save(&call.dejitter, up, count);
|
jitter_save(&call.dejitter, up, count);
|
||||||
} else
|
} else
|
||||||
|
/* else, if echo test is used, send echo back to mobile */
|
||||||
|
if (call.echo_test) {
|
||||||
|
call_rx_audio(callref, samples, count);
|
||||||
|
} else
|
||||||
/* else, if no sound is used, send test tone to mobile */
|
/* else, if no sound is used, send test tone to mobile */
|
||||||
if (call.state == CALL_CONNECT) {
|
if (call.state == CALL_CONNECT) {
|
||||||
int16_t spl[count];
|
int16_t spl[count];
|
||||||
@@ -1162,7 +1183,7 @@ void call_mncc_recv(uint8_t *buf, int length)
|
|||||||
PDEBUG(DMNCC, DEBUG_INFO, "Received MNCC disconnect from Network with cause %d\n", mncc->cause.value);
|
PDEBUG(DMNCC, DEBUG_INFO, "Received MNCC disconnect from Network with cause %d\n", mncc->cause.value);
|
||||||
|
|
||||||
if (is_process_state(callref) == CALL_CONNECT && call.release_on_disconnect) {
|
if (is_process_state(callref) == CALL_CONNECT && call.release_on_disconnect) {
|
||||||
PDEBUG(DCALL, DEBUG_INFO, "Releaseing, because we don't send disconnect tones to mobile phone\n");
|
PDEBUG(DCALL, DEBUG_INFO, "Releasing, because we don't send disconnect tones to mobile phone\n");
|
||||||
|
|
||||||
PDEBUG(DMNCC, DEBUG_INFO, "Releasing MNCC call towards Network\n");
|
PDEBUG(DMNCC, DEBUG_INFO, "Releasing MNCC call towards Network\n");
|
||||||
mncc->msg_type = MNCC_REL_IND;
|
mncc->msg_type = MNCC_REL_IND;
|
||||||
|
@@ -9,7 +9,7 @@ enum number_type {
|
|||||||
TYPE_INTERNATIONAL,
|
TYPE_INTERNATIONAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect);
|
int call_init(const char *station_id, const char *audiodev, int samplerate, int latency, int dial_digits, int loopback, int use_mncc_sock, int send_patterns, int release_on_disconnect, int echo_test);
|
||||||
void call_cleanup(void);
|
void call_cleanup(void);
|
||||||
int call_open_audio(int latspl);
|
int call_open_audio(int latspl);
|
||||||
int call_start_audio(void);
|
int call_start_audio(void);
|
||||||
|
@@ -49,19 +49,20 @@ int kanal[MAX_SENDER];
|
|||||||
int num_audiodev = 0;
|
int num_audiodev = 0;
|
||||||
const char *audiodev[MAX_SENDER] = { "hw:0,0" };
|
const char *audiodev[MAX_SENDER] = { "hw:0,0" };
|
||||||
int use_sdr = 0;
|
int use_sdr = 0;
|
||||||
const char *call_audiodev = "";
|
static const char *call_audiodev = "";
|
||||||
int samplerate = 48000;
|
int samplerate = 48000;
|
||||||
int call_samplerate = 48000;
|
static int call_samplerate = 48000;
|
||||||
int interval = 1;
|
int interval = 1;
|
||||||
int latency = 50;
|
int latency = 50;
|
||||||
int uses_emphasis = 1;
|
int uses_emphasis = 1;
|
||||||
int do_pre_emphasis = 0;
|
int do_pre_emphasis = 0;
|
||||||
int do_de_emphasis = 0;
|
int do_de_emphasis = 0;
|
||||||
double rx_gain = 1.0;
|
double rx_gain = 1.0;
|
||||||
int use_mncc_sock = 0;
|
static int echo_test = 0;
|
||||||
|
static int use_mncc_sock = 0;
|
||||||
const char *mncc_name = "";
|
const char *mncc_name = "";
|
||||||
int send_patterns = 1;
|
static int send_patterns = 1;
|
||||||
int release_on_disconnect = 1;
|
static int release_on_disconnect = 1;
|
||||||
int loopback = 0;
|
int loopback = 0;
|
||||||
int rt_prio = 0;
|
int rt_prio = 0;
|
||||||
const char *write_tx_wave = NULL;
|
const char *write_tx_wave = NULL;
|
||||||
@@ -115,15 +116,18 @@ void main_mobile_print_help(const char *arg0, const char *ext_usage)
|
|||||||
printf(" Raise receiver RX level by given gain in dB. This is useful if input\n");
|
printf(" Raise receiver RX level by given gain in dB. This is useful if input\n");
|
||||||
printf(" level of the sound device is too low, even after setting maximum level\n");
|
printf(" level of the sound device is too low, even after setting maximum level\n");
|
||||||
printf(" with the mixer settings. (Works with sound card only.)\n");
|
printf(" with the mixer settings. (Works with sound card only.)\n");
|
||||||
|
printf(" -e --echo-test\n");
|
||||||
|
printf(" Use echo test, to send back audio from mobile phone's microphone to\n");
|
||||||
|
printf(" the speaker. (German: 'Blasprobe').\n");
|
||||||
|
printf(" -c --call-device hw:<card>,<device>\n");
|
||||||
|
printf(" Sound card and device number for headset (default = '%s')\n", call_audiodev);
|
||||||
|
printf(" --call-samplerate <rate>\n");
|
||||||
|
printf(" Sample rate of sound device for headset (default = '%d')\n", call_samplerate);
|
||||||
printf(" -m --mncc-sock\n");
|
printf(" -m --mncc-sock\n");
|
||||||
printf(" Disable built-in call contol and offer socket (to LCR)\n");
|
printf(" Disable built-in call contol and offer socket (to LCR)\n");
|
||||||
printf(" --mncc-name <name>\n");
|
printf(" --mncc-name <name>\n");
|
||||||
printf(" '/tmp/bsc_mncc' is used by default, give name to change socket to\n");
|
printf(" '/tmp/bsc_mncc' is used by default, give name to change socket to\n");
|
||||||
printf(" '/tmp/bsc_mncc_<name>'. (Useful to run multiple networks.)\n");
|
printf(" '/tmp/bsc_mncc_<name>'. (Useful to run multiple networks.)\n");
|
||||||
printf(" -c --call-device hw:<card>,<device>\n");
|
|
||||||
printf(" Sound card and device number for headset (default = '%s')\n", call_audiodev);
|
|
||||||
printf(" --call-samplerate <rate>\n");
|
|
||||||
printf(" Sample rate of sound device for headset (default = '%d')\n", call_samplerate);
|
|
||||||
printf(" -t --tones 0 | 1\n");
|
printf(" -t --tones 0 | 1\n");
|
||||||
printf(" Connect call on setup/release to provide classic tones towards fixed\n");
|
printf(" Connect call on setup/release to provide classic tones towards fixed\n");
|
||||||
printf(" network (default = '%d')\n", send_patterns);
|
printf(" network (default = '%d')\n", send_patterns);
|
||||||
@@ -177,6 +181,7 @@ static struct option main_mobile_long_options[] = {
|
|||||||
{"pre-emphasis", 0, 0, 'p'},
|
{"pre-emphasis", 0, 0, 'p'},
|
||||||
{"de-emphasis", 0, 0, 'd'},
|
{"de-emphasis", 0, 0, 'd'},
|
||||||
{"rx-gain", 1, 0, 'g'},
|
{"rx-gain", 1, 0, 'g'},
|
||||||
|
{"echo-test", 0, 0, 'e'},
|
||||||
{"mncc-sock", 0, 0, 'm'},
|
{"mncc-sock", 0, 0, 'm'},
|
||||||
{"mncc-name", 1, 0, OPT_MNCC_NAME},
|
{"mncc-name", 1, 0, OPT_MNCC_NAME},
|
||||||
{"call-device", 1, 0, 'c'},
|
{"call-device", 1, 0, 'c'},
|
||||||
@@ -191,7 +196,7 @@ static struct option main_mobile_long_options[] = {
|
|||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *main_mobile_optstring = "hv:k:a:s:i:b:pdg:mc:t:l:r:";
|
static const char *main_mobile_optstring = "hv:k:a:s:i:b:pdg:mec:t:l:r:";
|
||||||
|
|
||||||
struct option *long_options;
|
struct option *long_options;
|
||||||
char *optstring;
|
char *optstring;
|
||||||
@@ -309,6 +314,10 @@ void main_mobile_opt_switch(int c, char *arg0, int *skip_args)
|
|||||||
rx_gain = pow(10, gain_db / 20.0);
|
rx_gain = pow(10, gain_db / 20.0);
|
||||||
*skip_args += 2;
|
*skip_args += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
echo_test = 1;
|
||||||
|
*skip_args += 1;
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
use_mncc_sock = 1;
|
use_mncc_sock = 1;
|
||||||
*skip_args += 1;
|
*skip_args += 1;
|
||||||
@@ -431,7 +440,7 @@ void main_mobile(int *quit, int latency, int interval, void (*myhandler)(void),
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* init call device */
|
/* init call device */
|
||||||
rc = call_init(station_id, call_audiodev, call_samplerate, latency, station_id_digits, loopback, use_mncc_sock, send_patterns, release_on_disconnect);
|
rc = call_init(station_id, call_audiodev, call_samplerate, latency, station_id_digits, loopback, use_mncc_sock, send_patterns, release_on_disconnect, echo_test);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to create call control instance. Quitting!\n");
|
fprintf(stderr, "Failed to create call control instance. Quitting!\n");
|
||||||
return;
|
return;
|
||||||
|
@@ -5,7 +5,6 @@ extern int swap_links;
|
|||||||
extern int num_audiodev;
|
extern int num_audiodev;
|
||||||
extern const char *audiodev[];
|
extern const char *audiodev[];
|
||||||
extern int use_sdr;
|
extern int use_sdr;
|
||||||
extern const char *call_audiodev;
|
|
||||||
extern int samplerate;
|
extern int samplerate;
|
||||||
extern int interval;
|
extern int interval;
|
||||||
extern int latency;
|
extern int latency;
|
||||||
@@ -13,8 +12,6 @@ extern int uses_emphasis;
|
|||||||
extern int do_pre_emphasis;
|
extern int do_pre_emphasis;
|
||||||
extern int do_de_emphasis;
|
extern int do_de_emphasis;
|
||||||
extern double rx_gain;
|
extern double rx_gain;
|
||||||
extern int use_mncc_sock;
|
|
||||||
extern int send_patterns;
|
|
||||||
extern int loopback;
|
extern int loopback;
|
||||||
extern int rt_prio;
|
extern int rt_prio;
|
||||||
extern const char *write_rx_wave;
|
extern const char *write_rx_wave;
|
||||||
|
Reference in New Issue
Block a user