diff options
Diffstat (limited to 'src/common')
32 files changed, 257 insertions, 207 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 8c70533..ce8bba1 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -4,6 +4,7 @@ AM_CPPFLAGS = -Wall -Wextra -g $(all_includes) $(UHD_CFLAGS) noinst_LIBRARIES = libcommon.a libcommon_a_SOURCES = \ + ../common/sample.c \ ../common/debug.c \ ../common/timer.c \ ../common/sound_alsa.c \ diff --git a/src/common/call.c b/src/common/call.c index 72ff516..f816417 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <errno.h> #include <sys/time.h> +#include "sample.h" #include "debug.h" #include "sender.h" #include "cause.h" @@ -640,8 +641,7 @@ void process_call(int c) return; /* handle audio, if sound device is used */ - - int16_t samples[call.latspl], *spl_list[1]; + sample_t samples[call.latspl + 10], *samples_list[1]; int count; int rc; @@ -653,28 +653,33 @@ void process_call(int c) return; } if (count < call.latspl) { - int16_t up[count + 10]; count = call.latspl - count; + int16_t spl[count + 10]; /* more than enough, count will be reduced by scaling with factor */ switch(call.state) { case CALL_ALERTING: + /* the count will be an approximation that will be upsampled */ count = (int)((double)count / call.srstate.factor + 0.5); - get_call_patterns(samples, count, PATTERN_RINGBACK); - count = samplerate_upsample(&call.srstate, samples, count, up); + get_call_patterns(spl, count, PATTERN_RINGBACK); + int16_to_samples(samples, spl, count); + count = samplerate_upsample(&call.srstate, samples, count, samples); /* prevent click after hangup */ jitter_clear(&call.dejitter); break; case CALL_DISCONNECTED: + /* the count will be an approximation that will be upsampled */ count = (int)((double)count / call.srstate.factor + 0.5); - get_call_patterns(samples, count, cause2pattern(call.disc_cause)); - count = samplerate_upsample(&call.srstate, samples, count, up); + get_call_patterns(spl, count, cause2pattern(call.disc_cause)); + int16_to_samples(samples, spl, count); + count = samplerate_upsample(&call.srstate, samples, count, samples); /* prevent click after hangup */ jitter_clear(&call.dejitter); break; default: - jitter_load(&call.dejitter, up, count); + jitter_load(&call.dejitter, samples, count); } - spl_list[0] = up; - rc = sound_write(call.sound, spl_list, count, NULL, NULL, 1); + samples_to_int16(spl, samples, count); + samples_list[0] = samples; + rc = sound_write(call.sound, samples_list, count, NULL, NULL, 1); if (rc < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc); if (rc == -EPIPE) @@ -682,8 +687,8 @@ void process_call(int c) return; } } - spl_list[0] = samples; - count = sound_read(call.sound, spl_list, call.latspl, 1); + samples_list[0] = samples; + count = sound_read(call.sound, samples_list, call.latspl, 1); if (count < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to read from sound device (rc = %d)!\n", count); if (count == -EPIPE) @@ -691,12 +696,10 @@ void process_call(int c) return; } if (count) { - int16_t down[count]; /* more than enough */ - if (call.loopback == 3) jitter_save(&call.dejitter, samples, count); - count = samplerate_downsample(&call.srstate, samples, count, down); - call_rx_audio(call.callref, down, count); + count = samplerate_downsample(&call.srstate, samples, count); + call_rx_audio(call.callref, samples, count); } } @@ -899,8 +902,10 @@ void call_in_release(int callref, int cause) } /* forward audio to MNCC or call instance */ -void call_tx_audio(int callref, int16_t *samples, int count) +void call_tx_audio(int callref, sample_t *samples, int count) { + int16_t spl[count]; + if (!callref) return; @@ -915,7 +920,7 @@ void call_tx_audio(int callref, int16_t *samples, int count) /* forward audio */ data->msg_type = ANALOG_8000HZ; data->callref = callref; - memcpy(data->data, samples, count * sizeof(int16_t)); + samples_to_int16((int16_t *)data->data, samples, count); mncc_write(buf, sizeof(buf)); return; @@ -923,13 +928,14 @@ void call_tx_audio(int callref, int16_t *samples, int count) /* save audio from transceiver to jitter buffer */ if (call.sound) { - int16_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); jitter_save(&call.dejitter, up, count); } else /* else, if no sound is used, send test tone to mobile */ if (call.state == CALL_CONNECT) { - get_test_patterns(samples, count); + get_test_patterns(spl, count); + int16_to_samples(samples, spl, count); call_rx_audio(callref, samples, count); } } @@ -966,10 +972,13 @@ void call_mncc_recv(uint8_t *buf, int length) if (mncc->msg_type == ANALOG_8000HZ) { struct gsm_data_frame *data = (struct gsm_data_frame *)buf; int count = (length - sizeof(struct gsm_data_frame)) / 2; + sample_t samples[count]; + /* if we are disconnected, ignore audio */ if (is_process_pattern(data->callref)) return; - call_rx_audio(data->callref, (int16_t *)data->data, count); + int16_to_samples(samples, (int16_t *)data->data, count); + call_rx_audio(data->callref, samples, count); return; } diff --git a/src/common/call.h b/src/common/call.h index 63719f4..fe3a32a 100644 --- a/src/common/call.h +++ b/src/common/call.h @@ -27,8 +27,8 @@ void call_out_disconnect(int callref, int cause); void call_out_release(int callref, int cause); /* send and receive audio */ -void call_rx_audio(int callref, int16_t *samples, int count); -void call_tx_audio(int callref, int16_t *samples, int count); +void call_rx_audio(int callref, sample_t *samples, int count); +void call_tx_audio(int callref, sample_t *samples, int count); /* receive from mncc */ void call_mncc_recv(uint8_t *buf, int length); diff --git a/src/common/compandor.c b/src/common/compandor.c index 9aacbf6..8db2f87 100644 --- a/src/common/compandor.c +++ b/src/common/compandor.c @@ -21,6 +21,7 @@ #include <stdint.h> #include <string.h> #include <math.h> +#include "sample.h" #include "compandor.h" //#define db2level(db) pow(10, (double)db / 20.0) @@ -64,9 +65,8 @@ void init_compandor(compandor_t *state, int samplerate, double attack_ms, double sqrt_tab[i] = sqrt(i * 0.001); } -void compress_audio(compandor_t *state, int16_t *samples, int num) +void compress_audio(compandor_t *state, sample_t *samples, int num) { - int32_t sample; double value, peak, envelope, step_up, step_down, unaffected; int i; @@ -79,7 +79,7 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) // printf("envelope=%.4f\n", envelope); for (i = 0; i < num; i++) { /* normalize sample value to unaffected level */ - value = (double)(*samples) / unaffected; + value = *samples / unaffected; /* 'peak' is the level that raises directly with the signal * level, but falls with specified recovery rate. */ @@ -100,13 +100,7 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) //if (i > 47000.0 && i < 48144) //printf("time=%.4f envelope=%.4fdb, value=%.4f\n", (double)i/48000.0, 20*log10(envelope), value); - /* convert back from 0 DB level to sample value */ - sample = (int)(value * unaffected); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = value * unaffected; } //exit(0); @@ -114,9 +108,8 @@ void compress_audio(compandor_t *state, int16_t *samples, int num) state->c.peak = peak; } -void expand_audio(compandor_t *state, int16_t *samples, int num) +void expand_audio(compandor_t *state, sample_t *samples, int num) { - int32_t sample; double value, peak, envelope, step_up, step_down, unaffected; int i; @@ -128,7 +121,7 @@ void expand_audio(compandor_t *state, int16_t *samples, int num) for (i = 0; i < num; i++) { /* normalize sample value to 0 DB level */ - value = (double)(*samples) / unaffected; + value = *samples / unaffected; /* for comments: see compress_audio() */ if (fabs(value) > peak) @@ -144,13 +137,7 @@ void expand_audio(compandor_t *state, int16_t *samples, int num) value = value * envelope; - /* convert back from 0 DB level to sample value */ - sample = (int)(value * unaffected); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = value * unaffected; } state->e.envelope = envelope; diff --git a/src/common/compandor.h b/src/common/compandor.h index df7dbc2..1d027dd 100644 --- a/src/common/compandor.h +++ b/src/common/compandor.h @@ -16,6 +16,6 @@ typedef struct compandor { } compandor_t; void init_compandor(compandor_t *state, int samplerate, double attack_ms, double recovery_ms, int unaffected_level); -void compress_audio(compandor_t *state, int16_t *samples, int num); -void expand_audio(compandor_t *state, int16_t *samples, int num); +void compress_audio(compandor_t *state, sample_t *samples, int num); +void expand_audio(compandor_t *state, sample_t *samples, int num); diff --git a/src/common/debug.c b/src/common/debug.c index b1b6e5d..e4677e7 100644 --- a/src/common/debug.c +++ b/src/common/debug.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <stdint.h> #include <errno.h> +#include "sample.h" #include "debug.h" #include "display.h" #include "call.h" diff --git a/src/common/display.h b/src/common/display.h index 2c07bb8..7b1c2e9 100644 --- a/src/common/display.h +++ b/src/common/display.h @@ -6,7 +6,7 @@ typedef struct display_wave { int interval_pos; int interval_max; int offset; - int16_t buffer[MAX_DISPLAY_WIDTH]; + sample_t buffer[MAX_DISPLAY_WIDTH]; } dispwav_t; #define MAX_DISPLAY_IQ 256 @@ -23,7 +23,7 @@ void get_win_size(int *w, int *h); void display_wave_init(sender_t *sender, int samplerate); void display_wave_on(int on); void display_wave_limit_scroll(int on); -void display_wave(sender_t *sender, int16_t *samples, int length); +void display_wave(sender_t *sender, sample_t *samples, int length); void display_iq_init(int samplerate); void display_iq_on(int on); diff --git a/src/common/display_iq.c b/src/common/display_iq.c index 2e1bd52..1d77c56 100644 --- a/src/common/display_iq.c +++ b/src/common/display_iq.c @@ -21,6 +21,7 @@ #include <stdint.h> #include <string.h> #include <math.h> +#include "sample.h" #include "sender.h" #define DISPLAY_INTERVAL 0.04 diff --git a/src/common/display_wave.c b/src/common/display_wave.c index 677e119..38a74c7 100644 --- a/src/common/display_wave.c +++ b/src/common/display_wave.c @@ -21,6 +21,7 @@ #include <stdint.h> #include <string.h> #include <sys/ioctl.h> +#include "sample.h" #include "sender.h" #define DISPLAY_INTERVAL 0.04 @@ -112,11 +113,11 @@ void display_wave_limit_scroll(int on) * y is in range of 0..5, so these are 5 steps, where 2 to 2.999 is the * center line. this is calculated by (HEIGHT * 2 - 1) */ -void display_wave(sender_t *sender, int16_t *samples, int length) +void display_wave(sender_t *sender, sample_t *samples, int length) { dispwav_t *disp = &sender->dispwav; int pos, max; - int16_t *buffer; + sample_t *buffer; int i, j, k, y; int color = 9; /* default color */ int center_line; @@ -146,11 +147,10 @@ void display_wave(sender_t *sender, int16_t *samples, int length) if (pos == width) { memset(&screen, ' ', sizeof(screen)); for (j = 0; j < width; j++) { - /* 32767 - buffer[j] never reaches 65536, so - * the result is below HEIGHT * 2 - 1 - */ - y = (32767 - (int)buffer[j]) * (HEIGHT * 2 - 1) / 65536; - screen[y >> 1][j] = (y & 1) ? '_' : '-'; + y = (32767 - (int32_t)buffer[j]) * (HEIGHT * 2 - 1) / 65536; + /* only display level, if it is in range */ + if (y >= 0 && y < HEIGHT * 2) + screen[y >> 1][j] = (y & 1) ? '_' : '-'; } sprintf(screen[0], "(chan %d", sender->kanal); *strchr(screen[0], '\0') = ')'; diff --git a/src/common/dtmf.c b/src/common/dtmf.c index b052fd5..b9870a1 100644 --- a/src/common/dtmf.c +++ b/src/common/dtmf.c @@ -20,6 +20,7 @@ #include <stdint.h> #include <string.h> #include <math.h> +#include "sample.h" #include "dtmf.h" #define PI M_PI @@ -27,7 +28,7 @@ #define TX_PEAK_DTMF 7000 /* single dtmf tone peak (note this is half to total peak) */ #define DTMF_DURATION 0.100 /* duration in seconds */ -int dsp_sine_dtmf[256]; +static double dsp_sine_dtmf[256]; void dtmf_init(dtmf_t *dtmf, int samplerate) { @@ -75,7 +76,7 @@ void dtmf_set_tone(dtmf_t *dtmf, char tone) } /* Generate audio stream from DTMF tone. Keep phase for next call of function. */ -void dtmf_tone(dtmf_t *dtmf, int16_t *samples, int length) +void dtmf_tone(dtmf_t *dtmf, sample_t *samples, int length) { double *phaseshift, *phase; int i, pos, max; diff --git a/src/common/dtmf.h b/src/common/dtmf.h index a0120db..477affd 100644 --- a/src/common/dtmf.h +++ b/src/common/dtmf.h @@ -10,5 +10,5 @@ typedef struct dtmf { void dtmf_init(dtmf_t *dtmf, int samplerate); void dtmf_set_tone(dtmf_t *dtmf, char tone); -void dtmf_tone(dtmf_t *dtmf, int16_t *samples, int length); +void dtmf_tone(dtmf_t *dtmf, sample_t *samples, int length); diff --git a/src/common/emphasis.c b/src/common/emphasis.c index c4a8242..57273d4 100644 --- a/src/common/emphasis.c +++ b/src/common/emphasis.c @@ -55,9 +55,8 @@ int init_emphasis(emphasis_t *state, int samplerate, double cut_off) return 0; } -void pre_emphasis(emphasis_t *state, int16_t *samples, int num) +void pre_emphasis(emphasis_t *state, double *samples, int num) { - int32_t sample; double x, y, x_last, factor, amp; int i; @@ -66,26 +65,20 @@ void pre_emphasis(emphasis_t *state, int16_t *samples, int num) amp = state->p.amp; for (i = 0; i < num; i++) { - x = (double)(*samples) / 32768.0; + x = *samples / 32768.0; y = x - factor * x_last; x_last = x; - sample = (int)(amp * y * 32768.0); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = (int)(amp * y * 32768.0); } state->p.x_last = x_last; } -void de_emphasis(emphasis_t *state, int16_t *samples, int num) +void de_emphasis(emphasis_t *state, double *samples, int num) { - int32_t sample; double x, y, z, y_last, z_last, d_factor, h_factor, amp; int i; @@ -96,7 +89,7 @@ void de_emphasis(emphasis_t *state, int16_t *samples, int num) amp = state->d.amp; for (i = 0; i < num; i++) { - x = (double)(*samples) / 32768.0; + x = *samples / 32768.0; /* de-emphasis */ y = x + d_factor * y_last; @@ -107,12 +100,7 @@ void de_emphasis(emphasis_t *state, int16_t *samples, int num) y_last = y; z_last = z; - sample = (int)(amp * z * 32768.0); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; + *samples++ = (int)(amp * z * 32768.0); } state->d.y_last = y_last; diff --git a/src/common/emphasis.h b/src/common/emphasis.h index 8a631e4..39d5246 100644 --- a/src/common/emphasis.h +++ b/src/common/emphasis.h @@ -16,6 +16,6 @@ typedef struct emphasis { #define CUT_OFF_EMPHASIS_DEFAULT 300.0 int init_emphasis(emphasis_t *state, int samplerate, double cut_off); -void pre_emphasis(emphasis_t *state, int16_t *samples, int num); -void de_emphasis(emphasis_t *state, int16_t *samples, int num); +void pre_emphasis(emphasis_t *state, double *samples, int num); +void de_emphasis(emphasis_t *state, double *samples, int num); diff --git a/src/common/goertzel.c b/src/common/goertzel.c index 5a89165..eaa7f99 100644 --- a/src/common/goertzel.c +++ b/src/common/goertzel.c @@ -22,7 +22,8 @@ #include <string.h> #include <errno.h> #include <math.h> -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "goertzel.h" /* @@ -30,9 +31,9 @@ */ /* return average value (rectified value), that can be 0..1 */ -double audio_level(int16_t *samples, int length) +double audio_level(sample_t *samples, int length) { - int32_t bias; + double bias; double level; int sk; int n; @@ -57,6 +58,12 @@ double audio_level(int16_t *samples, int length) return level; } +void audio_goertzel_init(goertzel_t *goertzel, double freq, int samplerate) +{ + memset(goertzel, 0, sizeof(*goertzel)); + goertzel->coeff = 2.0 * cos(2.0 * M_PI * freq / (double)samplerate); +} + /* * goertzel filter */ @@ -70,11 +77,11 @@ double audio_level(int16_t *samples, int length) * result: array of result levels (average value of the sine, that is 1 / (PI/2) of the sine's peak) * k: number of frequencies to check */ -void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double *result, int k) +void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int offset, double *result, int k) { - int32_t bias; - int32_t sk, sk1, sk2; - int64_t cos2pik; + double bias; + double sk, sk1, sk2; + double cos2pik; int i, n; /* calculate bias to remove DC */ @@ -88,10 +95,10 @@ void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double sk = 0; sk1 = 0; sk2 = 0; - cos2pik = coeff[i]; + cos2pik = goertzel[i].coeff; /* note: after 'length' cycles, offset is restored to its initial value */ for (n = 0; n < length; n++) { - sk = ((cos2pik * sk1) >> 15) - sk2 + samples[offset++] - bias; + sk = (cos2pik * sk1) - sk2 + samples[offset++] - bias; sk2 = sk1; sk1 = sk; if (offset == length) @@ -99,10 +106,10 @@ void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double } /* compute level of signal */ result[i] = sqrt( - ((double)sk * (double)sk) - - ((double)((cos2pik * sk) >> 15) * (double)sk2) + - ((double)sk2 * (double)sk2) - ) / (double)length / 32767.0 * 2.0 * 0.63662; /* 1 / (PI/2) */ + (sk * sk) - + (cos2pik * sk * sk2) + + (sk2 * sk2) + ) / (double)length * 2.0 * 0.63662; /* 1 / (PI/2) */ } } diff --git a/src/common/goertzel.h b/src/common/goertzel.h index 7feba16..58fcbb8 100644 --- a/src/common/goertzel.h +++ b/src/common/goertzel.h @@ -1,5 +1,10 @@ -double audio_level(int16_t *samples, int length); +double audio_level(sample_t *samples, int length); -void audio_goertzel(int16_t *samples, int length, int offset, int *coeff, double *result, int k); +typedef struct goertzel { + double coeff; +} goertzel_t; + +void audio_goertzel_init(goertzel_t *goertzel, double freq, int samplerate); +void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int offset, double *result, int k); diff --git a/src/common/jitter.c b/src/common/jitter.c index 9f171a0..865438b 100644 --- a/src/common/jitter.c +++ b/src/common/jitter.c @@ -22,14 +22,15 @@ #include <string.h> #include <errno.h> #include <math.h> -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "jitter.h" /* create jitter buffer */ int jitter_create(jitter_t *jitter, int length) { memset(jitter, 0, sizeof(*jitter)); - jitter->spl = calloc(length * sizeof(int16_t), 1); + jitter->spl = calloc(length * sizeof(sample_t), 1); if (!jitter->spl) { PDEBUG(DDSP, DEBUG_ERROR, "No memory for jitter buffer.\n"); return -ENOMEM; @@ -51,9 +52,9 @@ void jitter_destroy(jitter_t *jitter) * * stop if buffer is completely filled */ -void jitter_save(jitter_t *jb, int16_t *samples, int length) +void jitter_save(jitter_t *jb, sample_t *samples, int length) { - int16_t *spl; + sample_t *spl; int inptr, outptr, len, space; int i; @@ -76,9 +77,9 @@ void jitter_save(jitter_t *jb, int16_t *samples, int length) /* get audio from jitterbuffer */ -void jitter_load(jitter_t *jb, int16_t *samples, int length) +void jitter_load(jitter_t *jb, sample_t *samples, int length) { - int16_t *spl; + sample_t *spl; int inptr, outptr, len, fill; int i, ii; diff --git a/src/common/jitter.h b/src/common/jitter.h index 6d8d432..658da19 100644 --- a/src/common/jitter.h +++ b/src/common/jitter.h @@ -1,13 +1,13 @@ typedef struct jitter { - int16_t *spl; /* pointer to sample buffer */ + sample_t *spl; /* pointer to sample buffer */ int len; /* buffer size: number of samples */ int inptr, outptr; /* write pointer and read pointer */ } jitter_t; int jitter_create(jitter_t *jitter, int length); void jitter_destroy(jitter_t *jitter); -void jitter_save(jitter_t *jb, int16_t *samples, int length); -void jitter_load(jitter_t *jb, int16_t *samples, int length); +void jitter_save(jitter_t *jb, sample_t *samples, int length); +void jitter_load(jitter_t *jb, sample_t *samples, int length); void jitter_clear(jitter_t *jb); diff --git a/src/common/main_common.c b/src/common/main_common.c index b11d497..7a0cd52 100644 --- a/src/common/main_common.c +++ b/src/common/main_common.c @@ -27,6 +27,7 @@ #include <unistd.h> #include <math.h> #include <termios.h> +#include "sample.h" #include "main.h" #include "debug.h" #include "sender.h" diff --git a/src/common/mncc_sock.c b/src/common/mncc_sock.c index 1a2c5ae..437dec1 100644 --- a/src/common/mncc_sock.c +++ b/src/common/mncc_sock.c @@ -26,7 +26,8 @@ #include <sys/un.h> #include <stddef.h> #include <unistd.h> -#include "../common/debug.h" +#include "sample.h" +#include "debug.h" #include "call.h" #include "mncc_sock.h" diff --git a/src/common/sample.c b/src/common/sample.c new file mode 100644 index 0000000..107c8e0 --- /dev/null +++ b/src/common/sample.c @@ -0,0 +1,27 @@ + +#include <stdint.h> +#include "sample.h" + +void samples_to_int16(int16_t *spl, sample_t *samples, int length) +{ + while (length--) { + if (*samples > 32767.0) + *spl = 32767; + else if (*samples < -32767.0) + *spl = -32767; + else + *spl = (uint16_t)(*samples); + samples++; + spl++; + } +} + +void int16_to_samples(sample_t *samples, int16_t *spl, int length) +{ + while (length--) { + *samples = (double)(*spl); + samples++; + spl++; + } +} + diff --git a/src/common/sample.h b/src/common/sample.h new file mode 100644 index 0000000..fb578eb --- /dev/null +++ b/src/common/sample.h @@ -0,0 +1,6 @@ + +typedef double sample_t; + +void samples_to_int16(int16_t *spl, sample_t *samples, int length); +void int16_to_samples(sample_t *samples, int16_t *spl, int length); + diff --git a/src/common/samplerate.c b/src/common/samplerate.c index f554cf0..18e039e 100644 --- a/src/common/samplerate.c +++ b/src/common/samplerate.c @@ -22,6 +22,7 @@ #include <errno.h> #include <string.h> #include <stdlib.h> +#include "sample.h" #include "samplerate.h" /* NOTE: This is quick and dirtry. */ @@ -44,19 +45,13 @@ int init_samplerate(samplerate_t *state, double samplerate) } /* convert input sample rate to 8000 Hz */ -int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) +int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num) { int output_num = 0, i, idx; double factor = state->factor, in_index; - double spl[input_num]; - int32_t value; - - /* convert samples to double */ - for (i = 0; i < input_num; i++) - spl[i] = *input++ / 32768.0; /* filter down */ - filter_process(&state->down.lp, spl, input_num); + filter_process(&state->down.lp, samples, input_num); /* resample filtered result */ in_index = state->down.in_index; @@ -68,12 +63,7 @@ int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, in if (idx >= input_num) break; /* copy value from input to output */ - value = spl[idx] * 32768.0; - if (value < -32768) - value = -32768; - else if (value > 32767) - value = 32767; - *output++ = value; + samples[i] = samples[idx]; /* count output number */ output_num++; /* increment input index */ @@ -92,12 +82,17 @@ int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, in } /* convert 8000 Hz sample rate to output sample rate */ -int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output) +int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sample_t *output) { int output_num = 0, i, idx; double factor = 1.0 / state->factor, in_index; - double spl[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ - int32_t value; + sample_t buff[(int)((double)input_num / factor + 0.5) + 10]; /* add some fafety */ + sample_t *samples; + + if (input == output) + samples = buff; + else + samples = output; /* resample input */ in_index = state->up.in_index; @@ -109,7 +104,7 @@ int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int1 if (idx >= input_num) break; /* copy value */ - spl[i] = input[idx] / 32768.0; + samples[i] = input[idx]; /* count output number */ output_num++; /* increment input index */ @@ -125,16 +120,12 @@ int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int1 state->up.in_index = in_index; /* filter up */ - filter_process(&state->up.lp, spl, output_num); - - /* convert double to samples */ - for (i = 0; i < output_num; i++) { - value = spl[i] * 32768.0; - if (value < -32768) - value = -32768; - else if (value > 32767) - value = 32767; - *output++ = value; + filter_process(&state->up.lp, samples, output_num); + + if (input == output) { + /* copy samples */ + for (i = 0; i < input_num; i++) + *output++ = samples[i]; } return output_num; diff --git a/src/common/samplerate.h b/src/common/samplerate.h index d8c9d41..9efe3b1 100644 --- a/src/common/samplerate.h +++ b/src/common/samplerate.h @@ -13,5 +13,5 @@ typedef struct samplerate { } samplerate_t; int init_samplerate(samplerate_t *state, double samplerate); -int samplerate_downsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output); -int samplerate_upsample(samplerate_t *state, int16_t *input, int input_num, int16_t *output); +int samplerate_downsample(samplerate_t *state, sample_t *samples, int input_num); +int samplerate_upsample(samplerate_t *state, sample_t *input, int input_num, sample_t *output); diff --git a/src/common/sdr.c b/src/common/sdr.c index db46906..77b31a6 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -22,6 +22,7 @@ #include <stdint.h> #include <string.h> #include <math.h> +#include "sample.h" #include "filter.h" #include "sender.h" #ifdef HAVE_UHD @@ -241,7 +242,7 @@ void sdr_close(void *inst) } } -int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) +int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) { sdr_t *sdr = (sdr_t *)inst; float buff[num * 2]; @@ -291,19 +292,19 @@ int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attri } if (sdr->wave_tx_rec.fp) { - int16_t spl[2][num], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][num], *spl_list[2] = { spl[0], spl[1] }; for (s = 0, ss = 0; s < num; s++) { if (buff[ss] >= 1.0) - spl[0][s] = 32767; + spl[0][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[0][s] = -32767; + spl[0][s] = -32767.0; else spl[0][s] = 32767.0 * buff[ss]; ss++; if (buff[ss] >= 1.0) - spl[1][s] = 32767; + spl[1][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[1][s] = -32767; + spl[1][s] = -32767.0; else spl[1][s] = 32767.0 * buff[ss]; ss++; @@ -320,14 +321,14 @@ int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal __attri return sent; } -int sdr_read(void *inst, int16_t **samples, int num, int channels) +int sdr_read(void *inst, sample_t **samples, int num, int channels) { sdr_t *sdr = (sdr_t *)inst; float buff[num * 2]; double I[num], Q[num], i, q; int count; int c, s, ss; - double phase, rot, last_phase, spl, dev, rate; + double phase, rot, last_phase, dev, rate; rate = sdr->samplerate; @@ -338,19 +339,19 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) return count; if (sdr->wave_rx_rec.fp) { - int16_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; for (s = 0, ss = 0; s < count; s++) { if (buff[ss] >= 1.0) - spl[0][s] = 32767; + spl[0][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[0][s] = -32767; + spl[0][s] = -32767.0; else spl[0][s] = 32767.0 * buff[ss]; ss++; if (buff[ss] >= 1.0) - spl[1][s] = 32767; + spl[1][s] = 32767.0; else if (buff[ss] <= -1.0) - spl[1][s] = -32767; + spl[1][s] = -32767.0; else spl[1][s] = 32767.0 * buff[ss]; ss++; @@ -358,11 +359,11 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) wave_write(&sdr->wave_rx_rec, spl_list, count); } if (sdr->wave_rx_play.fp) { - int16_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; + sample_t spl[2][count], *spl_list[2] = { spl[0], spl[1] }; wave_read(&sdr->wave_rx_play, spl_list, count); for (s = 0, ss = 0; s < count; s++) { - buff[ss++] = (double)spl[0][s] / 32767.0; - buff[ss++] = (double)spl[1][s] / 32767.0; + buff[ss++] = spl[0][s] / 32767.0; + buff[ss++] = spl[1][s] / 32767.0; } } display_iq(buff, count); @@ -390,12 +391,7 @@ int sdr_read(void *inst, int16_t **samples, int num, int channels) else if (dev > 0.49) dev -= 1.0; dev *= rate; - spl = dev / sdr->spl_deviation; - if (spl > 32766.0) - spl = 32766.0; - else if (spl < -32766.0) - spl = -32766.0; - samples[c][s] = spl; + samples[c][s] = dev / sdr->spl_deviation; } sdr->chan[c].rx_last_phase = last_phase; } diff --git a/src/common/sdr.h b/src/common/sdr.h index 8ccd56a..5495de6 100644 --- a/src/common/sdr.h +++ b/src/common/sdr.h @@ -2,7 +2,7 @@ int sdr_init(const char *device_args, double rx_gain, double tx_gain, const char *write_iq_rx_wave, const char *write_iq_tx_wave, const char *read_iq_rx_wave); void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sdr_close(void *inst); -int sdr_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); -int sdr_read(void *inst, int16_t **samples, int num, int channels); +int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sdr_read(void *inst, sample_t **samples, int num, int channels); int sdr_get_inbuffer(void *inst); diff --git a/src/common/sender.c b/src/common/sender.c index 21aae70..f63e021 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <errno.h> #include <string.h> +#include "sample.h" #include "debug.h" #include "sender.h" @@ -224,19 +225,12 @@ void sender_destroy(sender_t *sender) jitter_destroy(&sender->dejitter); } -static void gain_samples(int16_t *samples, int length, double gain) +static void gain_samples(sample_t *samples, int length, double gain) { int i; - int32_t sample; - - for (i = 0; i < length; i++) { - sample = (int32_t)((double)(*samples) * gain); - if (sample > 32767) - sample = 32767; - else if (sample < -32768) - sample = -32768; - *samples++ = sample; - } + + for (i = 0; i < length; i++) + *samples++ *= gain; } /* Handle audio streaming of one transceiver. */ @@ -248,7 +242,7 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl) /* count instances for audio channel */ for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave); - int16_t buff[num_chan][latspl], *samples[num_chan]; + sample_t buff[num_chan][latspl], *samples[num_chan]; enum paging_signal paging_signal[num_chan]; int on[num_chan]; for (i = 0; i < num_chan; i++) { diff --git a/src/common/sender.h b/src/common/sender.h index 12f30ab..1af6be1 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -39,8 +39,8 @@ typedef struct sender { char audiodev[64]; /* audio device name (alsa or sdr) */ void *(*audio_open)(const char *, double *, double *, int, double, int, double, double); void (*audio_close)(void *); - int (*audio_write)(void *, int16_t **, int, enum paging_signal *, int *, int); - int (*audio_read)(void *, int16_t **, int, int); + int (*audio_write)(void *, sample_t **, int, enum paging_signal *, int *, int); + int (*audio_read)(void *, sample_t **, int, int); int (*audio_get_inbuffer)(void *); int samplerate; samplerate_t srstate; /* sample rate conversion state */ @@ -64,7 +64,7 @@ typedef struct sender { jitter_t dejitter; /* audio buffer for audio to send to caller (20ms = 160 samples @ 8000Hz) */ - int16_t rxbuf[160]; + sample_t rxbuf[160]; int rxbuf_pos; /* current fill of buffer */ /* loss of carrier detection */ @@ -87,7 +87,7 @@ int sender_create(sender_t *sender, int kanal, double sendefrequenz, double empf void sender_destroy(sender_t *sender); int sender_open_audio(void); void process_sender_audio(sender_t *sender, int *quit, int latspl); -void sender_send(sender_t *sender, int16_t *samples, int count); -void sender_receive(sender_t *sender, int16_t *samples, int count); +void sender_send(sender_t *sender, sample_t *samples, int count); +void sender_receive(sender_t *sender, sample_t *samples, int count); void sender_paging(sender_t *sender, int on); diff --git a/src/common/sound.h b/src/common/sound.h index a352f06..607e1f5 100644 --- a/src/common/sound.h +++ b/src/common/sound.h @@ -3,7 +3,7 @@ enum paging_signal; void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sound_close(void *inst); -int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); -int sound_read(void *inst, int16_t **samples, int num, int channels); +int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sound_read(void *inst, sample_t **samples, int num, int channels); int sound_get_inbuffer(void *inst); diff --git a/src/common/sound_alsa.c b/src/common/sound_alsa.c index 4eef893..efc93de 100644 --- a/src/common/sound_alsa.c +++ b/src/common/sound_alsa.c @@ -20,6 +20,7 @@ #include <stdlib.h> #include <stdint.h> #include <alsa/asoundlib.h> +#include "sample.h" #include "debug.h" #include "sender.h" @@ -248,35 +249,66 @@ static void gen_paging_tone(sound_t *sound, int16_t *samples, int length, enum p } } -int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels) +int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels) { sound_t *sound = (sound_t *)inst; + int32_t value; int16_t buff[num << 1]; int rc; int i, ii; if (sound->pchannels == 2) { + /* two channels */ if (paging_signal && on && paging_signal[0] != PAGING_SIGNAL_NONE) { int16_t paging[num << 1]; gen_paging_tone(sound, paging, num, paging_signal[0], on[0]); for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; buff[ii++] = paging[i]; } } else if (channels == 2) { for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; - buff[ii++] = samples[1][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + value = samples[1][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; } } else { for (i = 0, ii = 0; i < num; i++) { - buff[ii++] = samples[0][i]; - buff[ii++] = samples[0][i]; + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + buff[ii++] = value; } } - rc = snd_pcm_writei(sound->phandle, buff, num); - } else - rc = snd_pcm_writei(sound->phandle, samples[0], num); + } else { + /* one channel */ + for (i = 0, ii = 0; i < num; i++) { + value = samples[0][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[ii++] = value; + } + } + rc = snd_pcm_writei(sound->phandle, buff, num); if (rc < 0) { PDEBUG(DSOUND, DEBUG_ERROR, "failed to write audio to interface (%s)\n", snd_strerror(rc)); @@ -293,7 +325,7 @@ int sound_write(void *inst, int16_t **samples, int num, enum paging_signal *pagi #define KEEP_FRAMES 8 /* minimum frames not to read, due to bug in ALSA */ -int sound_read(void *inst, int16_t **samples, int num, int channels) +int sound_read(void *inst, sample_t **samples, int num, int channels) { sound_t *sound = (sound_t *)inst; int16_t buff[num << 1]; @@ -312,10 +344,7 @@ int sound_read(void *inst, int16_t **samples, int num, int channels) if (in > num) in = num; - if (sound->cchannels == 2) - rc = snd_pcm_readi(sound->chandle, buff, in); - else - rc = snd_pcm_readi(sound->chandle, samples[0], in); + rc = snd_pcm_readi(sound->chandle, buff, in); if (rc < 0) { if (errno == EAGAIN) @@ -332,18 +361,18 @@ int sound_read(void *inst, int16_t **samples, int num, int channels) for (i = 0, ii = 0; i < rc; i++) { spl = buff[ii++]; spl += buff[ii++]; - if (spl > 32767) - spl = 32767; - else if (spl < -32768) - spl = -32768; - samples[0][i] = spl; + samples[0][i] = (sample_t)spl; } } else { for (i = 0, ii = 0; i < rc; i++) { - samples[0][i] = buff[ii++]; - samples[1][i] = buff[ii++]; + samples[0][i] = (sample_t)buff[ii++]; + samples[1][i] = (sample_t)buff[ii++]; } } + } else { + for (i = 0, ii = 0; i < rc; i++) { + samples[0][i] = (sample_t)buff[ii++]; + } } return rc; diff --git a/src/common/uhd.c b/src/common/uhd.c index baf3249..8437e3b 100644 --- a/src/common/uhd.c +++ b/src/common/uhd.c @@ -54,9 +54,6 @@ int uhd_open(const char *device_args, double tx_frequency, double rx_frequency, samplerate = rate; check_rate = 1; -#warning HACK -if (tx_frequency < 200000000) tx_frequency = 463000000, rx_frequency = 463000000; - /* create USRP */ PDEBUG(DUHD, DEBUG_INFO, "Creating USRP with args \"%s\"...\n", device_args); error = uhd_usrp_make(&usrp, device_args); diff --git a/src/common/wave.c b/src/common/wave.c index 097ecc0..804fd5a 100644 --- a/src/common/wave.c +++ b/src/common/wave.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include "sample.h" #include "wave.h" struct fmt { @@ -193,7 +194,7 @@ error: return rc; } -int wave_read(wave_play_t *play, int16_t **samples, int length) +int wave_read(wave_play_t *play, sample_t **samples, int length) { uint8_t buff[2 * length * play->channels]; int __attribute__((__unused__)) len; @@ -201,7 +202,7 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) if (length > (int)play->left) { for (c = 0; c < play->channels; c++) - memset(samples[c], 0, 2 * length); + memset(samples[c], 0, sizeof(samples[c][0] * length)); length = play->left; } if (!length) @@ -215,7 +216,7 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) len = fread(buff, 1, 2 * length * play->channels, play->fp); for (i = 0, j = 0; i < length; i++) { for (c = 0; c < play->channels; c++) { - samples[c][i] = buff[j] + (buff[j + 1] << 8); + samples[c][i] = (double)(buff[j] + (buff[j + 1] << 8)); j += 2; } } @@ -223,8 +224,9 @@ int wave_read(wave_play_t *play, int16_t **samples, int length) return length; } -int wave_write(wave_rec_t *rec, int16_t **samples, int length) +int wave_write(wave_rec_t *rec, sample_t **samples, int length) { + int32_t value; uint8_t buff[2 * length * rec->channels]; int __attribute__((__unused__)) len; int i, j, c; @@ -232,8 +234,13 @@ int wave_write(wave_rec_t *rec, int16_t **samples, int length) /* write and correct endiness */ for (i = 0, j = 0; i < length; i++) { for (c = 0; c < rec->channels; c++) { - buff[j++] = samples[c][i]; - buff[j++] = samples[c][i] >> 8; + value = samples[c][i]; + if (value > 32767) + value = 32767; + else if (value < -32767) + value = -32767; + buff[j++] = value; + buff[j++] = value >> 8; } } len = fwrite(buff, 1, 2 * length * rec->channels, rec->fp); diff --git a/src/common/wave.h b/src/common/wave.h index 3c7aa48..59c1db8 100644 --- a/src/common/wave.h +++ b/src/common/wave.h @@ -14,8 +14,8 @@ typedef struct wave_play { int wave_create_record(wave_rec_t *rec, const char *filename, int samplerate, int channels); int wave_create_playback(wave_play_t *play, const char *filename, int samplerate, int channels); -int wave_read(wave_play_t *play, int16_t **samples, int length); -int wave_write(wave_rec_t *rec, int16_t **samples, int length); +int wave_read(wave_play_t *play, sample_t **samples, int length); +int wave_write(wave_rec_t *rec, sample_t **samples, int length); void wave_destroy_record(wave_rec_t *rec); void wave_destroy_playback(wave_play_t *play); |