Browse Source

Beeps

master
Jeroen Vreeken 3 years ago
parent
commit
2854ef29ec
7 changed files with 210 additions and 25 deletions
  1. +25
    -0
      beacon.c
  2. +7
    -0
      beacon.h
  3. +5
    -5
      fprs2aprs.c
  4. +37
    -19
      freedv_eth.c
  5. +78
    -1
      freedv_eth_txa.c
  6. +51
    -0
      io.c
  7. +7
    -0
      io.h

+ 25
- 0
beacon.c View File

@ -332,3 +332,28 @@ int beacon_generate_add(struct beacon *beacon, int16_t *sound, int nr)
return 0;
}
struct beacon_sample *beacon_beep_create(int rate, double f, double t_off, double t_on, double amp)
{
size_t nr_off = rate * t_off;
size_t nr_on = rate * t_on;
size_t nr = nr_on + nr_off;
int i;
struct beacon_sample *bs = calloc(sizeof(struct beacon_sample), 1);
if (!bs)
return NULL;
bs->samples = calloc(sizeof(int16_t), nr);
bs->nr = nr;
if (!bs->samples) {
free(bs);
return NULL;
}
for (i = 0; i < nr_on; i++) {
bs->samples[nr_off + i] = double2int16(sin((M_PI*2*i)/(rate/f))*(amp * 16384));
}
return bs;
}

+ 7
- 0
beacon.h View File

@ -30,4 +30,11 @@ bool beacon_state_check(struct beacon *beacon);
int beacon_generate(struct beacon *beacon, int16_t *sound, int nr);
int beacon_generate_add(struct beacon *beacon, int16_t *sound, int nr);
struct beacon_sample {
size_t nr;
int16_t *samples;
};
struct beacon_sample *beacon_beep_create(int rate, double f, double t_off, double t_on, double amp);
#endif /* _INCLUDE_BEACON_H_ */

+ 5
- 5
fprs2aprs.c View File

@ -44,7 +44,7 @@ struct fprs_frame *aprs2fprs(char *aprs)
from_call[i] = 0;
uint8_t from_ar[6];
printf("call: %s\n", from_call);
// printf("call: %s\n", from_call);
if (eth_ar_callssid2mac(from_ar, from_call, false))
goto err_ar;
@ -71,7 +71,7 @@ struct fprs_frame *aprs2fprs(char *aprs)
dest_call[9] = 0;
uint8_t dest_ar[6];
printf("to : %s\n", dest_call);
// printf("to : %s\n", dest_call);
if (eth_ar_callssid2mac(dest_ar, dest_call, false))
goto err_ar_dest;
@ -86,11 +86,11 @@ struct fprs_frame *aprs2fprs(char *aprs)
int msg_end = i;
int msg_len = (msg_end - msg_start);
printf("MSG len: %d\n", msg_len);
// printf("MSG len: %d\n", msg_len);
if (!memcmp(aprs + msg_start, "ack", 3)) {
fprs_frame_add_messageid(frame,
(uint8_t *)aprs + msg_start + 3, msg_len - 3);
printf("ACK size: %d\n", msg_len - 3);
// printf("ACK size: %d\n", msg_len - 3);
} else if (!memcmp(aprs + msg_start, "rej", 3)) {
/* No reject yet */
} else {
@ -100,7 +100,7 @@ struct fprs_frame *aprs2fprs(char *aprs)
if (aprs[msg_end] == '{') {
int id_size = (strlen(aprs) - msg_end) -1;
printf("ID size: %d\n", id_size);
// printf("ID size: %d\n", id_size);
fprs_frame_add_messageid(frame,
(uint8_t *)aprs +msg_end + 1, id_size);
}


+ 37
- 19
freedv_eth.c View File

@ -122,26 +122,44 @@ static int cb_int_tx(uint8_t to[6], uint8_t from[6], uint16_t eth_type, uint8_t
freedv_eth_transcode(packet, tx_codecmode, eth_type);
enqueue_voice(packet);
} else if (tx_mode == TX_MODE_FREEDV) {
// printf("Data: %d %x\n", eth_type, eth_type);
/* TODO: send control as DTMF in analog mode */
if (eth_type == ETH_P_AR_CONTROL && vc_control) {
packet = tx_packet_alloc();
memcpy(packet->data, data, len);
packet->len = len;
packet->off = 0;
} else {
if (eth_type == ETH_P_FPRS && !memcmp(mac, from, 6)) {
struct fprs_frame *frame = fprs_frame_create();
fprs_frame_data_set(frame, data, len);
struct fprs_element *el = NULL;
el = fprs_frame_element_by_type(frame, FPRS_DMLASSOC);
if (el) {
bool assoc = false;
if (fprs_element_size(el)) {
assoc = true;
}
io_dmlassoc_set(assoc);
printf("DMLASSOC state: %d", assoc);
}
fprs_frame_destroy(frame);
}
if (tx_mode == TX_MODE_FREEDV) {
// printf("Data: %d %x\n", eth_type, eth_type);
/* TODO: send control as DTMF in analog mode */
if (eth_type == ETH_P_AR_CONTROL && vc_control) {
packet = tx_packet_alloc();
memcpy(packet->data, data, len);
packet->len = len;
packet->off = 0;
enqueue_control(packet);
} else if (freedv_hasdata) {
packet = tx_packet_alloc();
packet->len = len + 6 + 6 + 2;
memcpy(packet->data + 0, to, 6);
memcpy(packet->data + 6, from, 6);
packet->data[12] = eth_type >> 8;
packet->data[13] = eth_type & 0xff;
memcpy(packet->data + 14, data, len);
enqueue_data(packet);
enqueue_control(packet);
} else if (freedv_hasdata) {
packet = tx_packet_alloc();
packet->len = len + 6 + 6 + 2;
memcpy(packet->data + 0, to, 6);
memcpy(packet->data + 6, from, 6);
packet->data[12] = eth_type >> 8;
packet->data[13] = eth_type & 0xff;
memcpy(packet->data + 14, data, len);
enqueue_data(packet);
}
}
}


+ 78
- 1
freedv_eth_txa.c View File

@ -30,6 +30,9 @@ enum tx_state {
TX_STATE_OFF,
TX_STATE_ON,
TX_STATE_TAIL,
TX_STATE_BEEP1,
TX_STATE_BEEP2,
TX_STATE_BEEPD,
};
@ -47,6 +50,10 @@ static bool output_bb = false;
static bool output_tone = false;
static enum io_hl_ptt ptt = IO_HL_PTT_OFF;
struct beacon_sample *beep_1k;
struct beacon_sample *beep_1k2;
struct beacon_sample *beep_2k;
static int tx_sound_out(int16_t *samples, int16_t *samples_bb, int nr)
{
if (!sr_l) {
@ -83,6 +90,31 @@ static void tx_silence(void)
tx_sound_out(buffer, buffer_bb, nr_samples);
}
static void tx_beep(void)
{
struct beacon_sample *bs;
if (tx_state == TX_STATE_BEEP1)
bs = beep_1k;
if (tx_state == TX_STATE_BEEP2)
bs = beep_1k2;
if (tx_state == TX_STATE_BEEPD)
bs = beep_2k;
int16_t buffer[nr_samples];
int16_t buffer_bb[nr_samples];
memcpy(buffer, bs->samples + tx_state_cnt * nr_samples, sizeof(int16_t)*nr_samples);
memset(buffer_bb, 0, sizeof(int16_t)*nr_samples);
if (ctcss) {
if (output_tone)
ctcss_add(ctcss, buffer_bb, nr_samples);
else
ctcss_add(ctcss, buffer, nr_samples);
}
if (emphasis_p)
emphasis_pre(emphasis_p, buffer, nr_samples);
tx_sound_out(buffer, buffer_bb, nr_samples);
}
static void tx_voice(void)
{
struct tx_packet *packet = peek_voice();
@ -163,12 +195,52 @@ void freedv_eth_txa_state_machine(void)
}
case TX_STATE_ON:
if (!queue_voice_filled() && !bcn) {
tx_state = TX_STATE_TAIL;
tx_state_cnt = 0;
if (io_hl_aux2_get()) {
tx_state = TX_STATE_BEEP1;
} if (io_dmlassoc_get()) {
tx_state = TX_STATE_BEEPD;
} else {
tx_state = TX_STATE_TAIL;
}
} else {
tx_voice();
break;
}
case TX_STATE_BEEP1:
case TX_STATE_BEEP2:
case TX_STATE_BEEPD:
if (tx_state == TX_STATE_BEEP1) {
if (tx_state_cnt >= beep_1k->nr / nr_samples) {
tx_state_cnt = 0;
if (io_hl_aux3_get()) {
tx_state = TX_STATE_BEEP2;
} else {
tx_state = TX_STATE_TAIL;
}
} else {
tx_beep();
break;
}
}
if (tx_state == TX_STATE_BEEP2) {
if (tx_state_cnt >= beep_1k2->nr / nr_samples) {
tx_state_cnt = 0;
tx_state = TX_STATE_TAIL;
} else {
tx_beep();
break;
}
}
if (tx_state == TX_STATE_BEEPD) {
if (tx_state_cnt >= beep_2k->nr / nr_samples) {
tx_state_cnt = 0;
tx_state = TX_STATE_TAIL;
} else {
tx_beep();
break;
}
}
case TX_STATE_TAIL:
if (tx_state_cnt >= tx_tail) {
tx_state = TX_STATE_OFF;
@ -187,6 +259,7 @@ void freedv_eth_txa_state_machine(void)
tx_silence();
}
}
break;
}
if (new_ptt != IO_HL_PTT_OFF && tx_hadvoice)
@ -212,6 +285,10 @@ int freedv_eth_txa_init(bool init_fullduplex, int hw_rate,
{
int a_rate = FREEDV_ALAW_RATE;
beep_1k = beacon_beep_create(a_rate, 1000.0, 0.2, 0.3, 0.25);
beep_1k2 = beacon_beep_create(a_rate, 1200.0, 0.2, 0.3, 0.25);
beep_2k = beacon_beep_create(a_rate, 2000.0, 0.2, 0.3, 0.25);
fullduplex = init_fullduplex;
output_bb = init_output_bb;
output_tone = init_output_tone;


+ 51
- 0
io.c View File

@ -32,9 +32,15 @@ static int dcd_level = 0;
static int dcd_threshold = 1;
static ptt_type_t ptt_type = RIG_PTT_NONE;
static dcd_type_t dcd_type = RIG_DCD_NONE;
static long token_aux1 = -1;
static long token_aux2 = -1;
static long token_aux3 = -1;
static volatile ptt_t rig_thread_ptt = RIG_PTT_OFF;
static volatile dcd_t rig_thread_dcd = RIG_DCD_OFF;
static volatile bool rig_thread_aux1 = false;
static volatile bool rig_thread_aux2 = false;
static volatile bool rig_thread_aux3 = false;
static bool toggle;
static bool input_state = false;
@ -160,6 +166,19 @@ bool io_hl_dcd_get(void)
return dcd_level >= dcd_threshold;
}
bool io_hl_aux1_get(void)
{
return rig_thread_aux1;
}
bool io_hl_aux2_get(void)
{
return rig_thread_aux2;
}
bool io_hl_aux3_get(void)
{
return rig_thread_aux3;
}
void io_hl_ptt_set(enum io_hl_ptt state)
{
ptt_t pstate;
@ -191,6 +210,7 @@ void *io_hl_rig_thread(void *arg)
{
dcd_t cur_dcd = rig_thread_dcd;
ptt_t cur_ptt = rig_thread_ptt;
value_t cur_value;
struct timespec t_cycle_start;
struct timespec t_cycle_end;
struct timespec t_wait;
@ -204,6 +224,18 @@ void *io_hl_rig_thread(void *arg)
rig_set_ptt(rig, RIG_VFO_CURR, cur_ptt);
}
rig_get_dcd(rig, RIG_VFO_CURR, &cur_dcd);
if (token_aux1 >= 0) {
if (rig_get_ext_parm(rig, token_aux1, &cur_value) == RIG_OK)
rig_thread_aux1 = cur_value.i;
}
if (token_aux2 >= 0) {
if (rig_get_ext_parm(rig, token_aux2, &cur_value) == RIG_OK)
rig_thread_aux2 = cur_value.i;
}
if (token_aux3 >= 0) {
if (rig_get_ext_parm(rig, token_aux3, &cur_value) == RIG_OK)
rig_thread_aux3 = cur_value.i;
}
rig_thread_dcd = cur_dcd;
__sync_synchronize();
clock_gettime(CLOCK_MONOTONIC, &t_cycle_end);
@ -259,8 +291,15 @@ int io_hl_init(rig_model_t rig_model, int dcd_th, ptt_type_t ptt, char *ptt_file
return -2;
}
/* Init to sane status */
rig_set_ptt(rig, RIG_VFO_CURR, RIG_PTT_OFF);
rig_get_dcd(rig, RIG_VFO_CURR, (dcd_t*)&rig_thread_dcd);
token_aux1 = rig_ext_token_lookup(rig, "AUX1");
token_aux2 = rig_ext_token_lookup(rig, "AUX2");
token_aux3 = rig_ext_token_lookup(rig, "AUX3");
printf("rig AUX tokens: %ld %ld %ld\n", token_aux1, token_aux2, token_aux3);
pthread_t rig_thread;
pthread_create(&rig_thread, NULL, io_hl_rig_thread, NULL);
@ -296,3 +335,15 @@ int io_poll_fill(struct pollfd *fds, int count)
return 0;
}
static bool io_dmlassoc = false;
bool io_dmlassoc_get(void)
{
return io_dmlassoc;
}
void io_dmlassoc_set(bool val)
{
io_dmlassoc = val;
}

+ 7
- 0
io.h View File

@ -44,4 +44,11 @@ enum io_hl_ptt {
void io_hl_ptt_set(enum io_hl_ptt state);
bool io_hl_aux1_get(void);
bool io_hl_aux2_get(void);
bool io_hl_aux3_get(void);
bool io_dmlassoc_get(void);
void io_dmlassoc_set(bool val);
#endif /* _INCLUDE_INPUT_H_ */

Loading…
Cancel
Save