Try to establish a more generic low level soundcard/ISDN/winmodem hardware

abstraction layer at the most fundamental level.
This commit is contained in:
Morten Rolland 2001-10-28 19:02:03 +00:00
parent cc0fcaee0a
commit b47cebd49f
5 changed files with 109 additions and 106 deletions

View File

@ -197,7 +197,7 @@ void main(int ac, char **av)
mh = modem_initialize();
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_RECORD,"modem.dat"); */

View File

@ -98,11 +98,11 @@ struct HardwareHandle {
/* 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.
*/
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.
*/

View File

@ -34,6 +34,8 @@
* and work with the hardware abstraction layer in 'hardware-driver.c'
*/
#define _GNU_SOURCE
#define FSM_DEBUG_STATES
#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.
* 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
* 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;
ifax_uint8 *dst, wala;
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;
wala = sint2wala[linear>>4];
@ -209,8 +217,7 @@ static void isdn_write_samples(struct HardwareHandle *hh, ifax_sint16 *src)
*dst++ = wala;
}
iobuffer_fill(ih->outgoing_buffer,&ih->tmp_write[0],
dst - &ih->tmp_write[0]);
iobuffer_fill(ih->outgoing_buffer, &tmp[0], dst - &tmp[0]);
}

View File

@ -47,7 +47,7 @@
*
*/
#include <strings.h>
#include <string.h>
#include <ifax/types.h>
#include <ifax/debug.h>

View File

@ -26,19 +26,8 @@
******************************************************************************
*/
/* NOTE: This code deals with timing-critical device-driver
* buffering with synchronized read/write on same
* 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
/*
* Maintain buffers and send/receive samples to the underlying
* physical transmission medium, like ISDN or a soundcard, named
* pipes for faxing self (debugging) etc.
*
@ -83,7 +72,8 @@
#include <ifax/misc/isdnline.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
* filled by the handle function (incomming signal-chain).
* We need a buffer here since the signaling-chain may not generate
@ -97,7 +87,8 @@
#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.
*/
@ -122,7 +113,8 @@ typedef struct {
} linedriver_private;
/* Method of operation:
/*
* Method of operation:
*
* The 'handle' function is called, possibly as a result of a 'demand'
* 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_uint32 up;
linedriver_private *priv = self->private;
struct HardwareHandle *hh;
/* When driving the ISDN-line, this is how it works:
* Read as much as we can from the line, and then
@ -171,17 +164,20 @@ static int work(ifax_modp self)
do {
chunk = MAXIOSIZE; /* Default buffer-size of IO-operations */
chunk = MAXIOSIZE; /* Default size of IO-operations */
if ( priv->ih != 0 ) {
/* ISDN is online, read first, then transmit */
chunk = IsdnReadSamples(priv->ih,&priv->rx_buffer[0],MAXIOSIZE);
if ( priv->hh != 0 && priv->hh->state == ONLINE ) {
/* Hardware is online, read first, then transmit */
hh = priv->hh;
chunk = hh->read(hh,&priv->rx_buffer[0],MAXIOSIZE);
if ( chunk < 0 )
return -1;
more = chunk == MAXIOSIZE;
} else
} else {
for ( t=0; t < chunk; t++)
priv->rx_buffer[t] = 0;
}
/* Fill output queue by demanding data (if needed) */
while ( priv->output.size < chunk ) {