aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/call.c51
-rw-r--r--src/common/call.h4
-rw-r--r--src/common/compandor.c27
-rw-r--r--src/common/compandor.h4
-rw-r--r--src/common/debug.c1
-rw-r--r--src/common/display.h4
-rw-r--r--src/common/display_iq.c1
-rw-r--r--src/common/display_wave.c14
-rw-r--r--src/common/dtmf.c5
-rw-r--r--src/common/dtmf.h2
-rw-r--r--src/common/emphasis.c24
-rw-r--r--src/common/emphasis.h4
-rw-r--r--src/common/goertzel.c33
-rw-r--r--src/common/goertzel.h9
-rw-r--r--src/common/jitter.c13
-rw-r--r--src/common/jitter.h6
-rw-r--r--src/common/main_common.c1
-rw-r--r--src/common/mncc_sock.c3
-rw-r--r--src/common/sample.c27
-rw-r--r--src/common/sample.h6
-rw-r--r--src/common/samplerate.c47
-rw-r--r--src/common/samplerate.h4
-rw-r--r--src/common/sdr.c40
-rw-r--r--src/common/sdr.h4
-rw-r--r--src/common/sender.c18
-rw-r--r--src/common/sender.h10
-rw-r--r--src/common/sound.h4
-rw-r--r--src/common/sound_alsa.c71
-rw-r--r--src/common/uhd.c3
-rw-r--r--src/common/wave.c19
-rw-r--r--src/common/wave.h4
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);