Move samples of int16_t format to sample_t, that is of type double
This prepares the correction of all levels
This commit is contained in:
@@ -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 \
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sample.h"
|
||||
#include "sender.h"
|
||||
|
||||
#define DISPLAY_INTERVAL 0.04
|
||||
|
@@ -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') = ')';
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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) */
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
||||
|
27
src/common/sample.c
Normal file
27
src/common/sample.c
Normal file
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
6
src/common/sample.h
Normal file
6
src/common/sample.h
Normal file
@@ -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);
|
||||
|
@@ -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);
|
||||
filter_process(&state->up.lp, samples, 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;
|
||||
if (input == output) {
|
||||
/* copy samples */
|
||||
for (i = 0; i < input_num; i++)
|
||||
*output++ = samples[i];
|
||||
}
|
||||
|
||||
return output_num;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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++) {
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user