Updated libs

This commit is contained in:
Andreas Eversberg 2022-10-05 20:12:23 +02:00
parent 42f4e4a243
commit e8a91e12f9
18 changed files with 202 additions and 124 deletions

View File

@ -1508,7 +1508,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
else else
g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
osmo_cc_rtp_send(call->codec, data, len, 1, len); osmo_cc_rtp_send(call->codec, data, len, 0, 1, len);
free(data); free(data);
/* mix audio for (hold) remote interface and forward */ /* mix audio for (hold) remote interface and forward */
@ -1525,7 +1525,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); g711_encode_alaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
else else
g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len); g711_encode_ulaw_flipped((uint8_t *)audio_mix, audio_len, &data, &len);
osmo_cc_rtp_send(other->codec, data, len, 1, len); osmo_cc_rtp_send(other->codec, data, len, 0, 1, len);
free(data); free(data);
} }
@ -1537,7 +1537,7 @@ static void send_to_rtp(call_t *call, unsigned char *data, int len)
if (call->bridge_enabled) if (call->bridge_enabled)
return; return;
osmo_cc_rtp_send(call->codec, data, len, 1, len); osmo_cc_rtp_send(call->codec, data, len, 0, 1, len);
} }
/* receive audio and control from B-channel, transmit data from jitter buffer accoring to received length */ /* receive audio and control from B-channel, transmit data from jitter buffer accoring to received length */

View File

@ -292,11 +292,11 @@ static void ph_socket_rx_msg(ph_socket_t *s, int channel, uint8_t prim, uint8_t
case PH_PRIM_CTRL_IND: case PH_PRIM_CTRL_IND:
if (length >= 1) { if (length >= 1) {
switch (data[0]) { switch (data[0]) {
case PH_CTRL_ENABLE: case PH_CTRL_UNBLOCK:
printk(KERN_DEBUG "PH-SOCKET Interface available\n"); printk(KERN_DEBUG "PH-SOCKET Interface available\n");
drv->enabled = 1; drv->enabled = 1;
break; break;
case PH_CTRL_DISABLE: case PH_CTRL_BLOCK:
printk(KERN_DEBUG "PH-SOCKET Interface unavailable\n"); printk(KERN_DEBUG "PH-SOCKET Interface unavailable\n");
drv->enabled = 0; drv->enabled = 0;
if (drv->activated) { if (drv->activated) {

View File

@ -57,6 +57,7 @@ struct debug_cat {
{ "jollycom", "\033[1;34m" }, { "jollycom", "\033[1;34m" },
{ "eurosignal", "\033[1;34m" }, { "eurosignal", "\033[1;34m" },
{ "pocsag", "\033[1;34m" }, { "pocsag", "\033[1;34m" },
{ "golay", "\033[1;34m" },
{ "5-ton-folge", "\033[1;34m" }, { "5-ton-folge", "\033[1;34m" },
{ "frame", "\033[0;36m" }, { "frame", "\033[0;36m" },
{ "call", "\033[0;37m" }, { "call", "\033[0;37m" },

View File

@ -19,43 +19,44 @@
#define DJOLLY 12 #define DJOLLY 12
#define DEURO 13 #define DEURO 13
#define DPOCSAG 14 #define DPOCSAG 14
#define DFUENF 15 #define DGOLAY 15
#define DFRAME 16 #define DFUENF 16
#define DCALL 17 #define DFRAME 17
#define DCC 18 #define DCALL 18
#define DDB 19 #define DCC 19
#define DTRANS 20 #define DDB 20
#define DDMS 21 #define DTRANS 21
#define DSMS 22 #define DDMS 22
#define DSDR 23 #define DSMS 23
#define DUHD 24 #define DSDR 24
#define DSOAPY 25 #define DUHD 25
#define DWAVE 26 #define DSOAPY 26
#define DRADIO 27 #define DWAVE 27
#define DAM791X 28 #define DRADIO 28
#define DUART 29 #define DAM791X 29
#define DDEVICE 30 #define DUART 30
#define DDATENKLO 31 #define DDEVICE 31
#define DZEIT 32 #define DDATENKLO 32
#define DSIM1 33 #define DZEIT 33
#define DSIM2 34 #define DSIM1 34
#define DSIMI 35 #define DSIM2 35
#define DSIM7 36 #define DSIMI 36
#define DMTP2 37 #define DSIM7 37
#define DMTP3 38 #define DMTP2 38
#define DMUP 39 #define DMTP3 39
#define DROUTER 40 #define DMUP 40
#define DSTDERR 41 #define DROUTER 41
#define DSS5 42 #define DSTDERR 42
#define DISDN 43 #define DSS5 43
#define DMISDN 44 #define DISDN 44
#define DDSS1 45 #define DMISDN 45
#define DSIP 46 #define DDSS1 46
#define DTEL 47 #define DSIP 47
#define DUK0 48 #define DTEL 48
#define DPH 49 #define DUK0 49
#define DDCF77 50 #define DPH 50
#define DJITTER 51 #define DDCF77 51
#define DJITTER 52
//NOTE: increment mask array, if 127 is exceeded //NOTE: increment mask array, if 127 is exceeded
void lock_debug(void); void lock_debug(void);

View File

@ -28,13 +28,13 @@
* *
* Packets with the same sequence are dropped. * Packets with the same sequence are dropped.
* *
* Early packts that exceed maximum jitter window size cause jitter
* window to shift into the future.
*
* Late packets cause jitter window to shift into the past (allowing more * Late packets cause jitter window to shift into the past (allowing more
* delay). Minimum jitter window size is added also, to prevent subsequent * delay). Minimum jitter window size is added also, to prevent subsequent
* packets from beeing late too. * packets from beeing late too.
* *
* Early packts that exceed maximum jitter window size cause jitter
* window to shift into the future.
*
* If no sequence is provided (autosequence), the sequence number is generated * If no sequence is provided (autosequence), the sequence number is generated
* by a counter. Also the timestamp is generated by counting the length of each * by a counter. Also the timestamp is generated by counting the length of each
* frame. * frame.
@ -51,16 +51,17 @@
* *
* Missing packets are interpolated by repeating last 20ms of audio (optional) * Missing packets are interpolated by repeating last 20ms of audio (optional)
* or by inserting zeroes (sample size > 1 byte) or by inserting 0xff (sample * or by inserting zeroes (sample size > 1 byte) or by inserting 0xff (sample
* size = 1). * size = 1). In case of repeating audio, the number of turns are limited until
* buffer is reset to silence, if no frames are received for a certain time.
* *
* Optionally the constant delay will be measured continuously and lowered to * Optionally the constant delay will be measured continuously and lowered if
* minimum window size. (adaptive jitter buffer window) * greater than minimum window size. (adaptive jitter buffer size)
* *
* Note that the delay is measured with time stamp of frame, no matter what * Note that the delay is measured with time stamp of frame, no matter what
* the length is. Length is an extra delay, but not considered here. * the length is. Length is an extra delay, but not considered here.
* *
* *
* Unocking: * Unlocking:
* *
* If the buffer is created or reset, the buffer is locked, so no packets are * If the buffer is created or reset, the buffer is locked, so no packets are
* stored. When the playout routine is called, the buffer is unlocked. This * stored. When the playout routine is called, the buffer is unlocked. This
@ -80,8 +81,9 @@
#include "jitter.h" #include "jitter.h"
#define INITIAL_DELAY_INTERVAL 0.5 #define INITIAL_DELAY_INTERVAL 0.5
#define REPEAT_DELAY_INTERVAL 2.0 #define REPEAT_DELAY_INTERVAL 3.0
#define EXTRA_BUFFER 0.020 // 20 ms #define EXTRA_BUFFER 0.020 // 20 ms
#define EXTRA_TIMEOUT 0.500 // maximum time to repeat extrapolation buffer
/* uncomment to enable heavy debugging */ /* uncomment to enable heavy debugging */
//#define HEAVY_DEBUG //#define HEAVY_DEBUG
@ -98,7 +100,6 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
jb->target_window_size = (int)(samplerate * target_window_duration); jb->target_window_size = (int)(samplerate * target_window_duration);
jb->max_window_size = (int)(samplerate * max_window_duration); jb->max_window_size = (int)(samplerate * max_window_duration);
jb->window_flags = window_flags; jb->window_flags = window_flags;
jb->delay_value = -1;
jb->extra_size = (int)(EXTRA_BUFFER * samplerate); jb->extra_size = (int)(EXTRA_BUFFER * samplerate);
jb->extra_samples = calloc(sample_size, jb->extra_size); jb->extra_samples = calloc(sample_size, jb->extra_size);
@ -107,7 +108,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
rc = -ENOMEM; rc = -ENOMEM;
goto error; goto error;
} }
jb->extra_timeout_max = (int)ceil(EXTRA_TIMEOUT / EXTRA_BUFFER);
/* optionally give a string to be show with the debug */ /* optionally give a string to be show with the debug */
if (name && *name) if (name && *name)
@ -117,7 +118,7 @@ int jitter_create(jitter_t *jb, const char *name, double samplerate, int sample_
jitter_reset(jb); jitter_reset(jb);
PDEBUG(DJITTER, DEBUG_DEBUG, "%sCreated jitter buffer.\n", jb->name); PDEBUG(DJITTER, DEBUG_INFO, "%sCreated jitter buffer. (samplerate=%.0f, target_window=%.0fms, max_window=%.0fms, flag:latency=%s flag:repeat=%s)\n", jb->name, samplerate, target_window_duration * 1000.0, max_window_duration * 1000.0, (window_flags & JITTER_FLAG_LATENCY) ? "true" : "false", (window_flags & JITTER_FLAG_REPEAT) ? "true" : "false");
error: error:
if (rc) if (rc)
@ -125,15 +126,20 @@ error:
return rc; return rc;
} }
static void clear_extra_buffer(jitter_t *jb)
{
if (jb->sample_size == 1)
memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size);
else
memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size);
}
/* reset jitter buffer */ /* reset jitter buffer */
void jitter_reset(jitter_t *jb) void jitter_reset(jitter_t *jb)
{ {
jitter_frame_t *jf, *temp; jitter_frame_t *jf, *temp;
if (!jb->window_valid) PDEBUG(DJITTER, DEBUG_INFO, "%sReset jitter buffer.\n", jb->name);
return;
PDEBUG(DJITTER, DEBUG_DEBUG, "%sReset jitter buffer.\n", jb->name);
/* jitter buffer locked */ /* jitter buffer locked */
jb->unlocked = 0; jb->unlocked = 0;
@ -151,20 +157,22 @@ void jitter_reset(jitter_t *jb)
jb->frame_list = NULL; jb->frame_list = NULL;
/* clear extrapolation buffer */ /* clear extrapolation buffer */
if (jb->extra_samples) { if (jb->extra_samples)
if (jb->sample_size == 1) clear_extra_buffer(jb);
memset(jb->extra_samples, 0xff, jb->sample_size * jb->extra_size);
else
memset(jb->extra_samples, 0, jb->sample_size * jb->extra_size);
}
jb->extra_index = 0; jb->extra_index = 0;
jb->extra_timeout_count = jb->extra_timeout_max; /* no data in buffer yet, so we set timeout condition */
/* delay measurement and reduction */
jb->delay_counter = 0.0;
jb->delay_interval = INITIAL_DELAY_INTERVAL;
jb->min_delay_value = -1;
} }
void jitter_destroy(jitter_t *jb) void jitter_destroy(jitter_t *jb)
{ {
jitter_reset(jb); jitter_reset(jb);
PDEBUG(DJITTER, DEBUG_DEBUG, "%sDestroying jitter buffer.\n", jb->name); PDEBUG(DJITTER, DEBUG_INFO, "%sDestroying jitter buffer.\n", jb->name);
if (jb->extra_samples) { if (jb->extra_samples) {
free(jb->extra_samples); free(jb->extra_samples);
@ -208,6 +216,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
jb->next_timestamp = timestamp + length; jb->next_timestamp = timestamp + length;
} }
/* first packet (with this ssrc) sets window size to target_window_size */
if (!jb->window_valid || jb->window_ssrc != ssrc) {
if (!jb->window_valid)
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name);
else
PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name);
// NOTE: Reset must be called before finding the frame location below, because there will be no frame in list anymore!
jitter_reset(jb);
jb->unlocked = 1;
/* when using dynamic jitter buffer, we use half of the target delay */
if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size / 2;
} else {
jb->window_timestamp = timestamp - (uint32_t)jb->target_window_size;
}
jb->window_valid = 1;
jb->window_ssrc = ssrc;
}
/* find location where to put frame into the list, depending on sequence number */ /* find location where to put frame into the list, depending on sequence number */
jfp = &jb->frame_list; jfp = &jb->frame_list;
while(*jfp) { while(*jfp) {
@ -223,37 +250,25 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
jfp = &((*jfp)->next); jfp = &((*jfp)->next);
} }
/* first packet (with this ssrc) sets window size to target_window_size */
if (!jb->window_valid || jb->window_ssrc != ssrc) {
if (!jb->window_valid)
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Initial frame after init or reset.\n", jb->name);
else
PDEBUG(DJITTER, DEBUG_DEBUG, "%s SSRC changed.\n", jb->name);
jitter_reset(jb);
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
jb->window_valid = 1;
jb->window_ssrc = ssrc;
jb->delay_counter = 0.0;
jb->delay_interval = INITIAL_DELAY_INTERVAL;
jb->delay_value = -1;
}
offset_timestamp = timestamp - jb->window_timestamp; offset_timestamp = timestamp - jb->window_timestamp;
#ifdef HEAVY_DEBUG
PDEBUG(DJITTER, DEBUG_DEBUG, "%sFrame has offset of %.0fms in jitter buffer.\n", jb->name, (double)offset_timestamp * jb->sample_duration * 1000.0);
#endif
/* measure delay */ /* measure delay */
if (offset_timestamp > jb->delay_value) if (jb->min_delay_value < 0 || offset_timestamp < jb->min_delay_value)
jb->delay_value = offset_timestamp; jb->min_delay_value = offset_timestamp;
/* if frame is too early (delay ceases), shift window to the future */ /* if frame is too early (delay ceases), shift window to the future */
if (offset_timestamp > jb->max_window_size) { if (offset_timestamp > jb->max_window_size) {
if ((jb->window_flags & JITTER_FLAG_LATENCY)) { if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, and add target window size. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size); PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the end. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
/* shift window so frame fits to the start of window + target delay */
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
} else {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
/* shift window so it fits to the end of window */ /* shift window so it fits to the end of window */
jb->window_timestamp = timestamp - jb->max_window_size; jb->window_timestamp = timestamp - jb->max_window_size;
} else {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too early: Shift jitter buffer to the future, to make the frame fit to the target delay. (offset_timestamp(%d) > max_window_size(%d))\n", jb->name, offset_timestamp, jb->max_window_size);
/* shift window so frame fits to the start of window + target delay */
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
} }
} }
@ -261,12 +276,12 @@ void jitter_save(jitter_t *jb, void *samples, int length, int has_sequence, uint
if (offset_timestamp < 0) { if (offset_timestamp < 0) {
if ((jb->window_flags & JITTER_FLAG_LATENCY)) { if ((jb->window_flags & JITTER_FLAG_LATENCY)) {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp); PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
/* shift window so frame fits to the start of window + half of target delay */
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size) / 2;
} else {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past, and add half target window size. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
/* shift window so frame fits to the start of window + target delay */ /* shift window so frame fits to the start of window + target delay */
jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size); jb->window_timestamp = timestamp - (uint32_t)(jb->target_window_size);
} else {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Frame too late: Shift jitter buffer to the past. (offset_timestamp(%d) < 0)\n", jb->name, offset_timestamp);
/* shift window so frame fits to the start of window */
jb->window_timestamp = timestamp;
} }
} }
@ -302,18 +317,21 @@ void jitter_load(jitter_t *jb, void *samples, int length)
/* now unlock jitter buffer */ /* now unlock jitter buffer */
jb->unlocked = 1; jb->unlocked = 1;
/* reduce delay */
jb->delay_counter += jb->sample_duration * (double)length; jb->delay_counter += jb->sample_duration * (double)length;
if (jb->delay_counter >= jb->delay_interval) { if (jb->delay_counter >= jb->delay_interval) {
if (jb->delay_value >= 0) if (jb->min_delay_value >= 0)
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_delay=%.0fms max_delay=%.0fms current_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->delay_value * jb->sample_duration * 1000.0); PDEBUG(DJITTER, DEBUG_DEBUG, "%s Statistics: target_window_delay=%.0fms max_window_delay=%.0fms current min_delay=%.0fms\n", jb->name, (double)jb->target_window_size * jb->sample_duration * 1000.0, (double)jb->max_window_size * jb->sample_duration * 1000.0, (double)jb->min_delay_value * jb->sample_duration * 1000.0);
/* delay reduction, if greater than target jitter window size */ /* delay reduction, if maximum delay is greater than target jitter window size */
if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->delay_value > jb->target_window_size) { if ((jb->window_flags & JITTER_FLAG_LATENCY) && jb->min_delay_value > jb->target_window_size) {
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current delay of %.0fms that is greater than target jitter window size of %.0fms.\n", jb->name, (double)jb->delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0); PDEBUG(DJITTER, DEBUG_DEBUG, "%s Reducing current minimum delay of %.0fms, because maximum delay is greater than target window size of %.0fms.\n", jb->name, (double)jb->min_delay_value * jb->sample_duration * 1000.0, (double)jb->target_window_size * jb->sample_duration * 1000.0);
jb->window_timestamp += (uint32_t)(jb->delay_value - jb->target_window_size); /* only reduce delay to half of the target window size */
jb->window_timestamp += jb->min_delay_value - jb->target_window_size / 2;
} }
jb->delay_counter -= jb->delay_interval; jb->delay_counter -= jb->delay_interval;
jb->delay_interval = REPEAT_DELAY_INTERVAL; jb->delay_interval = REPEAT_DELAY_INTERVAL;
jb->delay_value = -1; jb->min_delay_value = -1;
} }
/* process all frames until output buffer is loaded */ /* process all frames until output buffer is loaded */
@ -342,8 +360,18 @@ void jitter_load(jitter_t *jb, void *samples, int length)
count2 = jb->extra_size - jb->extra_index; count2 = jb->extra_size - jb->extra_index;
memcpy(samples, (uint8_t *)jb->extra_samples + jb->extra_index * jb->sample_size, count2 * jb->sample_size); memcpy(samples, (uint8_t *)jb->extra_samples + jb->extra_index * jb->sample_size, count2 * jb->sample_size);
jb->extra_index += count2; jb->extra_index += count2;
if (jb->extra_index == jb->extra_size) if (jb->extra_index == jb->extra_size) {
jb->extra_index = 0; jb->extra_index = 0;
if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_timeout_count < jb->extra_timeout_max) {
jb->extra_timeout_count++;
if (jb->extra_timeout_count == jb->extra_timeout_max) {
#ifdef HEAVY_DEBUG
PDEBUG(DJITTER, DEBUG_DEBUG, "%s Repeated jitter buffer enough, clearing to silence.\n", jb->name);
#endif
clear_extra_buffer(jb);
}
}
}
samples = (uint8_t *)samples + count2 * jb->sample_size; samples = (uint8_t *)samples + count2 * jb->sample_size;
length -= count2; length -= count2;
jb->window_timestamp += count2; jb->window_timestamp += count2;
@ -360,8 +388,8 @@ void jitter_load(jitter_t *jb, void *samples, int length)
count = length; count = length;
if (jf->length - index < count) if (jf->length - index < count)
count = jf->length - index; count = jf->length - index;
/* if extrapolation is used, limit count to what we can store into buffer */ /* if extrapolation is to be written, limit count to what we can store into buffer */
if (jb->extra_samples && jb->extra_size - jb->extra_index < count) if ((jb->window_flags & JITTER_FLAG_REPEAT) && jb->extra_size - jb->extra_index < count)
count = jb->extra_size - jb->extra_index; count = jb->extra_size - jb->extra_index;
/* copy samples from packet to play out, increment sample pointer and decrement length */ /* copy samples from packet to play out, increment sample pointer and decrement length */
#ifdef HEAVY_DEBUG #ifdef HEAVY_DEBUG
@ -376,6 +404,7 @@ void jitter_load(jitter_t *jb, void *samples, int length)
jb->extra_index += count; jb->extra_index += count;
if (jb->extra_index == jb->extra_size) if (jb->extra_index == jb->extra_size)
jb->extra_index = 0; jb->extra_index = 0;
jb->extra_timeout_count = 0; /* now we have new data, we reset timeout condition */
} }
/* increment time stamp */ /* increment time stamp */
jb->window_timestamp += count; jb->window_timestamp += count;

View File

@ -39,12 +39,14 @@ typedef struct jitter {
/* reduction of delay */ /* reduction of delay */
double delay_interval; double delay_interval;
double delay_counter; double delay_counter;
int32_t delay_value; int32_t min_delay_value;
/* extrapolation */ /* extrapolation */
int extra_size; int extra_size;
int extra_index; int extra_index;
void *extra_samples; void *extra_samples;
int extra_timeout_max;
int extra_timeout_count;
/* list of frames */ /* list of frames */
jitter_frame_t *frame_list; jitter_frame_t *frame_list;

View File

@ -568,6 +568,18 @@ static void notify_ind(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
forward_to_ul(call, msg); forward_to_ul(call, msg);
} }
static void update_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
{
/* to lower layer */
forward_to_ll(call, msg);
}
static void update_cnf(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
{
/* to upper layer */
forward_to_ul(call, msg);
}
static void disc_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg) static void disc_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
{ {
/* change state */ /* change state */
@ -853,6 +865,10 @@ static struct statemachine {
OSMO_CC_MSG_INFO_IND, info_ind}, OSMO_CC_MSG_INFO_IND, info_ind},
{SBIT(OSMO_CC_STATE_ACTIVE), {SBIT(OSMO_CC_STATE_ACTIVE),
OSMO_CC_MSG_INFO_REQ, info_req}, OSMO_CC_MSG_INFO_REQ, info_req},
{SBIT(OSMO_CC_STATE_ACTIVE),
OSMO_CC_MSG_UPDATE_REQ, update_req},
{SBIT(OSMO_CC_STATE_ACTIVE),
OSMO_CC_MSG_UPDATE_CNF, update_cnf},
/* call release */ /* call release */
{SBIT(OSMO_CC_STATE_INIT_OUT) | SBIT(OSMO_CC_STATE_INIT_IN) | {SBIT(OSMO_CC_STATE_INIT_OUT) | SBIT(OSMO_CC_STATE_INIT_IN) |

View File

@ -29,7 +29,7 @@
#include "endpoint.h" #include "endpoint.h"
#include "helper.h" #include "helper.h"
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug) osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug)
{ {
osmo_cc_session_t *session; osmo_cc_session_t *session;
osmo_cc_session_media_t *media; osmo_cc_session_media_t *media;
@ -52,7 +52,7 @@ osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, vo
return session; return session;
} }
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec) const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec)
{ {
char offer_sdp[65536]; char offer_sdp[65536];
const char *accept_sdp; const char *accept_sdp;

View File

@ -7,7 +7,7 @@ struct osmo_cc_helper_audio_codecs {
void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len); void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len);
}; };
osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug); osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug);
const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec); const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec);
int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p); int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p);

View File

@ -30,6 +30,8 @@ enum osmo_cc_msg_type {
OSMO_CC_MSG_NOTIFY_IND = 0x85, OSMO_CC_MSG_NOTIFY_IND = 0x85,
OSMO_CC_MSG_INFO_REQ = 0x88, OSMO_CC_MSG_INFO_REQ = 0x88,
OSMO_CC_MSG_INFO_IND = 0x89, OSMO_CC_MSG_INFO_IND = 0x89,
OSMO_CC_MSG_UPDATE_REQ = 0x91,
OSMO_CC_MSG_UPDATE_CNF = 0x93,
OSMO_CC_MSG_ATTACH_REQ = 0xf8, OSMO_CC_MSG_ATTACH_REQ = 0xf8,
OSMO_CC_MSG_ATTACH_IND = 0xf9, OSMO_CC_MSG_ATTACH_IND = 0xf9,
OSMO_CC_MSG_ATTACH_RSP = 0xfa, OSMO_CC_MSG_ATTACH_RSP = 0xfa,

View File

@ -132,7 +132,7 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
return 0; return 0;
} }
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc) static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
{ {
struct rtp_hdr *rtph; struct rtp_hdr *rtph;
char data[sizeof(*rtph) + payload_len]; char data[sizeof(*rtph) + payload_len];
@ -141,7 +141,7 @@ static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t pt, ui
rtph = (struct rtp_hdr *)data; rtph = (struct rtp_hdr *)data;
len = sizeof(*rtph); len = sizeof(*rtph);
rtph->byte0 = RTP_VERSION << 6; rtph->byte0 = RTP_VERSION << 6;
rtph->byte1 = pt; rtph->byte1 = pt | (marker << 7);
rtph->sequence = htons(sequence); rtph->sequence = htons(sequence);
rtph->timestamp = htonl(timestamp); rtph->timestamp = htonl(timestamp);
rtph->ssrc = htonl(ssrc); rtph->ssrc = htonl(ssrc);
@ -321,7 +321,7 @@ connect_error:
} }
/* send rtp data with given codec */ /* send rtp data with given codec */
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, int inc_sequence, int inc_timestamp) void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp)
{ {
uint8_t *payload = NULL; uint8_t *payload = NULL;
int payload_len = 0; int payload_len = 0;
@ -336,7 +336,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, in
payload_len = len; payload_len = len;
} }
rtp_send(codec->media->rtp_socket, payload, payload_len, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc); rtp_send(codec->media->rtp_socket, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
codec->media->tx_sequence += inc_sequence; codec->media->tx_sequence += inc_sequence;
codec->media->tx_timestamp += inc_timestamp; codec->media->tx_timestamp += inc_timestamp;
@ -382,7 +382,7 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media)
} }
if (codec->media->receive) if (codec->media->receive)
codec->media->receiver(codec, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len); codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
if (codec->decoder) if (codec->decoder)
free(data); free(data);

View File

@ -2,7 +2,7 @@
void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16_t to); void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16_t to);
int osmo_cc_rtp_open(osmo_cc_session_media_t *media); int osmo_cc_rtp_open(osmo_cc_session_media_t *media);
int osmo_cc_rtp_connect(osmo_cc_session_media_t *media); int osmo_cc_rtp_connect(osmo_cc_session_media_t *media);
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, int inc_sequence, int inc_timestamp); void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp);
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media); int osmo_cc_rtp_receive(osmo_cc_session_media_t *media);
void osmo_cc_rtp_close(osmo_cc_session_media_t *media); void osmo_cc_rtp_close(osmo_cc_session_media_t *media);

View File

@ -127,7 +127,7 @@ void osmo_cc_free_session(osmo_cc_session_t *session)
free(session); free(session);
} }
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug) osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug)
{ {
osmo_cc_session_config_t *conf = session->config; osmo_cc_session_config_t *conf = session->config;
osmo_cc_session_media_t *media, **mediap; osmo_cc_session_media_t *media, **mediap;
@ -374,7 +374,7 @@ osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf,
return session; return session;
} }
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)) void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len))
{ {
osmo_cc_session_config_t *conf = media->session->config; osmo_cc_session_config_t *conf = media->session->config;

View File

@ -79,7 +79,7 @@ typedef struct osmo_cc_session_media {
osmo_cc_session_connection_data_t connection_data_local, connection_data_remote; osmo_cc_session_connection_data_t connection_data_local, connection_data_remote;
struct osmo_cc_session_codec *codec_list; struct osmo_cc_session_codec *codec_list;
int send, receive; int send, receive;
void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len); void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
int rtp_socket; int rtp_socket;
int rtcp_socket; int rtcp_socket;
uint32_t tx_ssrc, rx_ssrc; uint32_t tx_ssrc, rx_ssrc;
@ -110,14 +110,14 @@ typedef struct osmo_cc_session_codec {
void osmo_cc_set_local_peer(osmo_cc_session_config_t *conf, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address); void osmo_cc_set_local_peer(osmo_cc_session_config_t *conf, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address);
osmo_cc_session_t *osmo_cc_new_session(osmo_cc_session_config_t *conf, void *priv, const char *username, const char *sess_id, const char *sess_version, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *unicast_address, const char *session_name, int debug); osmo_cc_session_t *osmo_cc_new_session(osmo_cc_session_config_t *conf, void *priv, const char *username, const char *sess_id, const char *sess_version, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *unicast_address, const char *session_name, int debug);
void osmo_cc_free_session(osmo_cc_session_t *session); void osmo_cc_free_session(osmo_cc_session_t *session);
osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug); osmo_cc_session_media_t *osmo_cc_add_media(osmo_cc_session_t *session, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, enum osmo_cc_session_media_type type, uint16_t port, enum osmo_cc_session_media_proto proto, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), int debug);
void osmo_cc_free_media(osmo_cc_session_media_t *media); void osmo_cc_free_media(osmo_cc_session_media_t *media);
osmo_cc_session_codec_t *osmo_cc_add_codec(osmo_cc_session_media_t *media, const char *playload_name, uint32_t playload_rate, int playload_channels, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), int debug); osmo_cc_session_codec_t *osmo_cc_add_codec(osmo_cc_session_media_t *media, const char *playload_name, uint32_t playload_rate, int playload_channels, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), int debug);
void osmo_cc_free_codec(osmo_cc_session_codec_t *codec); void osmo_cc_free_codec(osmo_cc_session_codec_t *codec);
int osmo_cc_session_check(struct osmo_cc_session *session, int remote); int osmo_cc_session_check(struct osmo_cc_session *session, int remote);
const char *osmo_cc_session_send_offer(osmo_cc_session_t *session); const char *osmo_cc_session_send_offer(osmo_cc_session_t *session);
osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf, void *priv, const char *sdp); osmo_cc_session_t *osmo_cc_session_receive_offer(osmo_cc_session_config_t *conf, void *priv, const char *sdp);
void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)); void osmo_cc_session_accept_media(osmo_cc_session_media_t *media, enum osmo_cc_session_nettype nettype, enum osmo_cc_session_addrtype addrtype, const char *address, int send, int receive, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len));
void osmo_cc_session_accept_codec(osmo_cc_session_codec_t *codec, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len)); void osmo_cc_session_accept_codec(osmo_cc_session_codec_t *codec, void (*encoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len), void (*decoder)(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len));
const char *osmo_cc_session_send_answer(osmo_cc_session_t *session); const char *osmo_cc_session_send_answer(osmo_cc_session_t *session);
int osmo_cc_session_receive_answer(osmo_cc_session_t *session, const char *sdp); int osmo_cc_session_receive_answer(osmo_cc_session_t *session, const char *sdp);

View File

@ -80,7 +80,7 @@ int ph_socket_init(ph_socket_t *s, void (*ph_socket_rx_msg)(ph_socket_t *s, int
static void close_connection(ph_socket_t *s) static void close_connection(ph_socket_t *s)
{ {
struct socket_msg_list *ml; struct socket_msg_list *ml;
uint8_t disable = PH_CTRL_DISABLE; uint8_t disable = PH_CTRL_BLOCK;
if (s->connect <= 0) if (s->connect <= 0)
return; return;
@ -123,7 +123,7 @@ void ph_socket_exit(ph_socket_t *s)
int ph_socket_work(ph_socket_t *s) int ph_socket_work(ph_socket_t *s)
{ {
uint8_t enable = PH_CTRL_ENABLE; uint8_t enable = PH_CTRL_UNBLOCK;
int rc, flags; int rc, flags;
int work = 0; int work = 0;

View File

@ -62,8 +62,8 @@
#define PH_MODE_HDLC 0x01 /* HDLC transcoding is performed via B-channel */ #define PH_MODE_HDLC 0x01 /* HDLC transcoding is performed via B-channel */
/* one byte sent with control messages */ /* one byte sent with control messages */
#define PH_CTRL_DISABLE 0x00 /* disable (block) interface, when socket is disconnected */ #define PH_CTRL_BLOCK 0x00 /* disable (block) interface, when socket is disconnected */
#define PH_CTRL_ENABLE 0x01 /* enable (unblock) interface, when socket is connected */ #define PH_CTRL_UNBLOCK 0x01 /* enable (unblock) interface, when socket is connected */
#define PH_CTRL_LOOP_DISABLE 0x04 /* disable loopback */ #define PH_CTRL_LOOP_DISABLE 0x04 /* disable loopback */
#define PH_CTRL_LOOP1_ENABLE 0x05 /* enable LT transceier loopback */ #define PH_CTRL_LOOP1_ENABLE 0x05 /* enable LT transceier loopback */
#define PH_CTRL_LOOP2_ENABLE 0x06 /* enable NT transceier loopback */ #define PH_CTRL_LOOP2_ENABLE 0x06 /* enable NT transceier loopback */

View File

@ -25,6 +25,7 @@
* of 16 bits signed value: * of 16 bits signed value:
*/ */
static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0, which is about 3dBm below full 16 bit range */ static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0, which is about 3dBm below full 16 bit range */
static double int_16_1mw_level = 0.7079; /* dBm0, 3dBm below full 16 bit range */
/* A sample_t is a value that has virtually infinite precision but will also /* A sample_t is a value that has virtually infinite precision but will also
* support high numbers. 'double' or 'float' types are sufficient. * support high numbers. 'double' or 'float' types are sufficient.
@ -40,7 +41,8 @@ static double int_16_speech_level = SPEECH_LEVEL * 0.7079; /* 16 dBm below dBm0,
* envelope is network dependent. * envelope is network dependent.
*/ */
void samples_to_int16(int16_t *spl, sample_t *samples, int length) /* sample conversion relative to SPEECH level */
void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length)
{ {
int32_t value; int32_t value;
@ -55,10 +57,33 @@ void samples_to_int16(int16_t *spl, sample_t *samples, int length)
} }
} }
void int16_to_samples(sample_t *samples, int16_t *spl, int length) void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length)
{ {
while (length--) { while (length--) {
*samples++ = (double)(*spl++) / 32767.0 / int_16_speech_level; *samples++ = (double)(*spl++) / 32767.0 / int_16_speech_level;
} }
} }
/* sample conversion relative to 1mW level */
void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length)
{
int32_t value;
while (length--) {
value = *samples++ * int_16_1mw_level * 32768.0;
if (value > 32767.0)
*spl++ = 32767;
else if (value < -32767.0)
*spl++ = -32767;
else
*spl++ = (uint16_t)value;
}
}
void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length)
{
while (length--) {
*samples++ = (double)(*spl++) / 32767.0 / int_16_1mw_level;
}
}

View File

@ -3,6 +3,8 @@ typedef double sample_t;
#define SPEECH_LEVEL 0.1585 #define SPEECH_LEVEL 0.1585
void samples_to_int16(int16_t *spl, sample_t *samples, int length); void samples_to_int16_speech(int16_t *spl, sample_t *samples, int length);
void int16_to_samples(sample_t *samples, int16_t *spl, int length); void int16_to_samples_speech(sample_t *samples, int16_t *spl, int length);
void samples_to_int16_1mw(int16_t *spl, sample_t *samples, int length);
void int16_to_samples_1mw(sample_t *samples, int16_t *spl, int length);