ftmod_isdn: Rework teletone buffer offset handling in isdn_tones_run().

Store the offset in the teletone buffer in the b-channel private data.

An NT-mode setup with ftmod_misdn showed severe (dial-)tone distortions
in a sound editor (330Hz sine wave phase errors), caused by
using a global teletone buffer offset.

Switching to a per-channel offset, that is advanced by the amount
of data actually written to the channel, removes (almost) all
distortions.

There is still a minimal phase error every ~500ms (audible) that
needs more investigating.

Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
Stefan Knoblich 2012-07-26 01:05:36 +02:00
parent c9e172789c
commit 5367b96153
2 changed files with 19 additions and 9 deletions

View File

@ -1797,7 +1797,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
teletone_generation_session_t ts = {{{{0}}}};;
unsigned char frame[1024];
int x, interval;
int offset = 0;
ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n");
ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
@ -1842,6 +1841,7 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
ftdm_size_t len = sizeof(frame), rlen;
ftdm_isdn_bchan_data_t *data = chan->call_data;
if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) {
continue;
@ -1855,7 +1855,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
switch (ftdm_channel_get_state(chan)) {
case FTDM_CHANNEL_STATE_DIALTONE:
{
ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)chan->call_data;
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
/* check overlap dial timeout first before generating tone */
@ -1933,7 +1932,7 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
}
/* seek to current offset */
ftdm_buffer_seek(dt_buffer, offset);
ftdm_buffer_seek(dt_buffer, data->offset);
rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
@ -1953,7 +1952,22 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
goto done;
}
}
ftdm_channel_write(chan, frame, sizeof(frame), &rlen);
if (ftdm_channel_write(chan, frame, sizeof(frame), &rlen) == FTDM_SUCCESS) {
/*
* Advance offset in teletone buffer by amount
* of data actually written to channel.
*/
if (chan->effective_codec != FTDM_CODEC_SLIN) {
data->offset += rlen << 1; /* teletone buffer is slin (= len * 2) */
} else {
data->offset += rlen;
}
if (data->offset >= ts.rate) {
data->offset = 0;
}
}
}
/*
@ -1962,11 +1976,6 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
if (!gated) {
ftdm_sleep(interval);
}
offset += (ts.rate / (1000 / interval)) << 1;
if (offset >= ts.rate) {
offset = 0;
}
}
done:

View File

@ -79,6 +79,7 @@ typedef struct ftdm_isdn_data ftdm_isdn_data_t;
struct ftdm_isdn_bchan_data
{
int32_t digit_timeout;
int offset; /* offset in teletone buffer */
};
typedef struct ftdm_isdn_bchan_data ftdm_isdn_bchan_data_t;