Try to establish a more generic low level soundcard/ISDN/winmodem hardware
abstraction layer at the most fundamental level.
This commit is contained in:
parent
cc0fcaee0a
commit
b47cebd49f
|
@ -197,7 +197,7 @@ void main(int ac, char **av)
|
||||||
mh = modem_initialize();
|
mh = modem_initialize();
|
||||||
|
|
||||||
linedriver = ifax_create_module(IFAX_LINEDRIVER);
|
linedriver = ifax_create_module(IFAX_LINEDRIVER);
|
||||||
ifax_command(linedriver,CMD_LINEDRIVER_ISDN,hh);
|
ifax_command(linedriver,CMD_LINEDRIVER_HARDWARE,hh);
|
||||||
|
|
||||||
/* ifax_command(linedriver,CMD_LINEDRIVER_AUDIO); */
|
/* ifax_command(linedriver,CMD_LINEDRIVER_AUDIO); */
|
||||||
/* ifax_command(linedriver,CMD_LINEDRIVER_RECORD,"modem.dat"); */
|
/* ifax_command(linedriver,CMD_LINEDRIVER_RECORD,"modem.dat"); */
|
||||||
|
|
|
@ -98,11 +98,11 @@ struct HardwareHandle {
|
||||||
|
|
||||||
/* Read a number of samples from the hardware driver.
|
/* Read a number of samples from the hardware driver.
|
||||||
*/
|
*/
|
||||||
void (*read)(struct HardwareHandle *hh, ifax_uint8 *samples);
|
void (*read)(struct HardwareHandle *hh, ifax_uint8 *smpls, int cnt);
|
||||||
|
|
||||||
/* Write a number of (16-bit signed) samples to the hardware driver.
|
/* Write a number of (16-bit signed) samples to the hardware driver.
|
||||||
*/
|
*/
|
||||||
void (*write)(struct HardwareHandle *hh, ifax_sint16 *samples);
|
void (*write)(struct HardwareHandle *hh, ifax_sint16 *smpls, int cnt);
|
||||||
|
|
||||||
/* Supply the hardware driver with configuration parameters.
|
/* Supply the hardware driver with configuration parameters.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
* and work with the hardware abstraction layer in 'hardware-driver.c'
|
* and work with the hardware abstraction layer in 'hardware-driver.c'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#define FSM_DEBUG_STATES
|
#define FSM_DEBUG_STATES
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -178,27 +180,33 @@ static void isdn_service_select(struct HardwareHandle *hh, fd_set *rfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write a set of voice samples to the ISDN device. The samples are in the
|
/*
|
||||||
|
* Write a set of voice samples to the ISDN device. The samples are in the
|
||||||
* form of an array, containing 16-bit signed, linear values.
|
* form of an array, containing 16-bit signed, linear values.
|
||||||
* The array is *modified* by this function to the linear values actually
|
* The array is *modified* by this function to the linear values actually
|
||||||
* transmitted. This is to help an echo cancel function to work on the true
|
* transmitted. This is to help an echo cancel function to work on the true
|
||||||
* values as sent over the ISDN line to the remote end.
|
* values as sent over the ISDN line to the remote end.
|
||||||
*
|
|
||||||
* The number of samples that needs to be sent is dictated by the value
|
|
||||||
* in the hardware driver handle: hh->write_size. This function will assume
|
|
||||||
* there are exactly this many samples in the 'src' array.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void isdn_write_samples(struct HardwareHandle *hh, ifax_sint16 *src)
|
#define ISDN_MAX_WRITE 4096
|
||||||
|
|
||||||
|
static void isdn_write_samples(struct HardwareHandle *hh,
|
||||||
|
ifax_sint16 *src, int cnt)
|
||||||
{
|
{
|
||||||
struct IsdnHandle *ih = hh->private;
|
struct IsdnHandle *ih = hh->private;
|
||||||
ifax_uint8 *dst, wala;
|
ifax_uint8 *dst, wala;
|
||||||
ifax_uint16 linear;
|
ifax_uint16 linear;
|
||||||
int t;
|
ifax_uint8 tmp[2 * ISDN_MAX_WRITE];
|
||||||
|
|
||||||
dst = &ih->tmp_write[0];
|
if ( cnt > ISDN_MAX_WRITE ) {
|
||||||
|
ifax_dprintf(DEBUG_ERROR,"Dropping %d samples in isdn_write_samples",
|
||||||
|
cnt - ISDN_MAX_WRITE);
|
||||||
|
cnt = ISDN_MAX_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
for ( t=0; t < hh->write_size; t++ ) {
|
dst = &tmp[0];
|
||||||
|
|
||||||
|
while ( cnt-- > 0 ) {
|
||||||
|
|
||||||
linear = (ifax_uint16) *src;
|
linear = (ifax_uint16) *src;
|
||||||
wala = sint2wala[linear>>4];
|
wala = sint2wala[linear>>4];
|
||||||
|
@ -209,8 +217,7 @@ static void isdn_write_samples(struct HardwareHandle *hh, ifax_sint16 *src)
|
||||||
*dst++ = wala;
|
*dst++ = wala;
|
||||||
}
|
}
|
||||||
|
|
||||||
iobuffer_fill(ih->outgoing_buffer,&ih->tmp_write[0],
|
iobuffer_fill(ih->outgoing_buffer, &tmp[0], dst - &tmp[0]);
|
||||||
dst - &ih->tmp_write[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <strings.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ifax/types.h>
|
#include <ifax/types.h>
|
||||||
#include <ifax/debug.h>
|
#include <ifax/debug.h>
|
||||||
|
|
|
@ -26,19 +26,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: This code deals with timing-critical device-driver
|
/*
|
||||||
* buffering with synchronized read/write on same
|
* Maintain buffers and send/receive samples to the underlying
|
||||||
* device and between devices (ISDN/Audio).
|
|
||||||
* The relationships between buffer-sizes, read/write
|
|
||||||
* strategy and possible timing glitches should be
|
|
||||||
* investigated more closely. UPDATE: Should work well
|
|
||||||
* as long as (low-level) transmit-buffer is
|
|
||||||
* pre-charged to avoid draining.
|
|
||||||
*
|
|
||||||
* BUGS: Error situations are not handeled well (no warnings etc.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Maintain buffers and send/receive samples to the underlying
|
|
||||||
* physical transmission medium, like ISDN or a soundcard, named
|
* physical transmission medium, like ISDN or a soundcard, named
|
||||||
* pipes for faxing self (debugging) etc.
|
* pipes for faxing self (debugging) etc.
|
||||||
*
|
*
|
||||||
|
@ -83,7 +72,8 @@
|
||||||
#include <ifax/misc/isdnline.h>
|
#include <ifax/misc/isdnline.h>
|
||||||
#include <ifax/modules/linedriver.h>
|
#include <ifax/modules/linedriver.h>
|
||||||
|
|
||||||
/* These defines should probably be run-time configurable.
|
/*
|
||||||
|
* These defines should probably be run-time configurable.
|
||||||
* BUFFERSIZE is the size of the main output buffer which is
|
* BUFFERSIZE is the size of the main output buffer which is
|
||||||
* filled by the handle function (incomming signal-chain).
|
* filled by the handle function (incomming signal-chain).
|
||||||
* We need a buffer here since the signaling-chain may not generate
|
* We need a buffer here since the signaling-chain may not generate
|
||||||
|
@ -97,7 +87,8 @@
|
||||||
#define MAXIOSIZE 256
|
#define MAXIOSIZE 256
|
||||||
|
|
||||||
|
|
||||||
/* An instance of this linedriver module holds the following
|
/*
|
||||||
|
* An instance of this linedriver module holds the following
|
||||||
* state-information and buffer storage.
|
* state-information and buffer storage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -122,7 +113,8 @@ typedef struct {
|
||||||
} linedriver_private;
|
} linedriver_private;
|
||||||
|
|
||||||
|
|
||||||
/* Method of operation:
|
/*
|
||||||
|
* Method of operation:
|
||||||
*
|
*
|
||||||
* The 'handle' function is called, possibly as a result of a 'demand'
|
* The 'handle' function is called, possibly as a result of a 'demand'
|
||||||
* request, with data to fill the output queue (TX). However, no data
|
* request, with data to fill the output queue (TX). However, no data
|
||||||
|
@ -158,6 +150,7 @@ static int work(ifax_modp self)
|
||||||
ifax_sint32 sp;
|
ifax_sint32 sp;
|
||||||
ifax_uint32 up;
|
ifax_uint32 up;
|
||||||
linedriver_private *priv = self->private;
|
linedriver_private *priv = self->private;
|
||||||
|
struct HardwareHandle *hh;
|
||||||
|
|
||||||
/* When driving the ISDN-line, this is how it works:
|
/* When driving the ISDN-line, this is how it works:
|
||||||
* Read as much as we can from the line, and then
|
* Read as much as we can from the line, and then
|
||||||
|
@ -171,17 +164,20 @@ static int work(ifax_modp self)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
chunk = MAXIOSIZE; /* Default buffer-size of IO-operations */
|
chunk = MAXIOSIZE; /* Default size of IO-operations */
|
||||||
|
|
||||||
if ( priv->ih != 0 ) {
|
if ( priv->hh != 0 && priv->hh->state == ONLINE ) {
|
||||||
/* ISDN is online, read first, then transmit */
|
/* Hardware is online, read first, then transmit */
|
||||||
chunk = IsdnReadSamples(priv->ih,&priv->rx_buffer[0],MAXIOSIZE);
|
hh = priv->hh;
|
||||||
|
chunk = hh->read(hh,&priv->rx_buffer[0],MAXIOSIZE);
|
||||||
if ( chunk < 0 )
|
if ( chunk < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
more = chunk == MAXIOSIZE;
|
more = chunk == MAXIOSIZE;
|
||||||
} else
|
} else {
|
||||||
for ( t=0; t < chunk; t++)
|
for ( t=0; t < chunk; t++)
|
||||||
priv->rx_buffer[t] = 0;
|
priv->rx_buffer[t] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fill output queue by demanding data (if needed) */
|
/* Fill output queue by demanding data (if needed) */
|
||||||
while ( priv->output.size < chunk ) {
|
while ( priv->output.size < chunk ) {
|
||||||
|
|
Loading…
Reference in New Issue