summaryrefslogtreecommitdiffstats
path: root/port.cpp
diff options
context:
space:
mode:
authorSuper User2007-05-15 22:59:29 +0200
committerSuper User2007-05-15 22:59:29 +0200
commitfd2045584f7084d209607f4d717a66bea9afe88e (patch)
tree8118fb0cb231a4546d43a13cb85d8b80992c9d64 /port.cpp
parentbackup work (diff)
downloadlcr-fd2045584f7084d209607f4d717a66bea9afe88e.tar.gz
lcr-fd2045584f7084d209607f4d717a66bea9afe88e.tar.xz
lcr-fd2045584f7084d209607f4d717a66bea9afe88e.zip
backup
Diffstat (limited to 'port.cpp')
-rw-r--r--port.cpp1113
1 files changed, 22 insertions, 1091 deletions
diff --git a/port.cpp b/port.cpp
index a68ca59..a3a33c8 100644
--- a/port.cpp
+++ b/port.cpp
@@ -141,6 +141,7 @@ Port::Port(int type, char *portname, struct port_settings *settings)
}
SCPY(p_name, portname);
SCPY(p_tone_dir, p_settings.tones_dir); // just to be sure
+ p_clock = 0;
p_type = type;
p_serial = port_serial++;
p_debug_nothingtosend = 0;
@@ -262,25 +263,6 @@ void Port::new_state(int state)
/*
- * find the port using h323 token
- */
-class Port *find_port_with_token(char *name)
-{
- class Port *port = port_first;
-
- while(port)
- {
-//printf("comparing: '%s' with '%s'\n", name, p_name);
- if ((port->p_type==PORT_TYPE_H323_IN || port->p_type==PORT_TYPE_H323_OUT) && !strcmp(port->p_name, name))
- return(port);
- port = port->next;
- }
-
- return(NULL);
-}
-
-
-/*
* find the port with port_id
*/
class Port *find_port_id(unsigned long port_id)
@@ -298,47 +280,6 @@ class Port *find_port_id(unsigned long port_id)
return(NULL);
}
-#if 0
-/*
- * open the knock sound
- */
-void Port::set_knock(char *tones_dir_epoint)
-{
- char filename[128], *tones_dir;
-
- /* check if we have the epoint override the tones_dir of options.conf */
- tones_dir = options.tones_dir;
- if (tones_dir_epoint[0])
- {
- tones_dir = tones_dir_epoint;
- }
-
- if (p_knock_fh >= 0)
- {
- close(p_knock_fh);
- p_knock_fh = -1;
- fhuse--;
- }
- p_knock_fetched = NULL;
-
- if ((p_knock_fetched=open_tone_fetched(tones_dir, "knock", &p_knock_codec, &p_knock_size, &p_knock_left)))
- {
- PDEBUG(DEBUG_PORT, "PORT(%s) opening fetched tone: %s\n", p_name, "knock");
- return;
- }
-
- SPRINT(filename, "%s/%s/knock", INSTALL_DATA, tones_dir);
- if ((p_knock_fh=open_tone(filename, &p_knock_codec, &p_knock_size, &p_knock_left)) >= 0)
- {
- PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
- fhuse++;
- } else
- {
- p_knock_fh = -1;
- }
-}
-#endif
-
/*
* set echotest
@@ -348,6 +289,7 @@ void Port::set_echotest(int echotest)
p_echotest = echotest;
}
+
/*
* set the file in the tone directory with the given name
*/
@@ -359,15 +301,6 @@ void Port::set_tone(char *dir, char *name)
if (name == NULL)
name = "";
-#if 0
- /* knocking ? */
- if (!strcmp(name, "knock"))
- {
- set_knock(tones_dir_epoint);
- return;
- }
-#endif
-
/* no counter, no eof, normal speed */
p_tone_counter = 0;
p_tone_eof = 0;
@@ -518,45 +451,6 @@ void Port::set_vbox_play(char *name, int offset)
/* seek */
if (p_tone_name[0])
{
-//printf("\n\n\n tone_codec = %d\n\n\n\n",p_tone_codec);
-#if 0
- switch(p_tone_codec)
- {
- case CODEC_LAW:
- case CODEC_8BIT:
- lseek(p_tone_fh, offset*8000L, SEEK_SET);
- size = p_tone_size / 8000L;
- if (offset*8000L <= p_tone_left)
- p_tone_left -= offset*8000L;
- break;
-
- case CODEC_MONO:
- lseek(p_tone_fh, offset*16000L, SEEK_SET);
- size = p_tone_size / 16000L;
- if (offset*16000L <= p_tone_left)
- p_tone_left -= offset*16000L;
-//printf("\n\n\n size = %d\n\n\n\n",size);
- break;
-
- case CODEC_STEREO:
- lseek(p_tone_fh, offset*32000L, SEEK_SET);
- size = p_tone_size / 32000L;
- if (offset*32000L <= p_tone_left)
- p_tone_left -= offset*32000L;
- break;
-
- default:
- PERROR("no codec specified! exitting...\n");
- exit(-1);
- }
-#else
- lseek(p_tone_fh, offset*8000L, SEEK_SET);
- size = p_tone_size / 8000L;
- if (offset*8000L <= p_tone_left)
- p_tone_left -= offset*8000L;
-#endif
-
-
/* send message with counter value */
if (p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
{
@@ -578,274 +472,30 @@ void Port::set_vbox_speed(int speed)
p_tone_speed = speed;
}
-/* write data to port's mixer buffer
- * it will be read by the port using read_audio
- * synchronisation is also done when writing is too fast and buffer is full
- * the mixer buffer will only mix what cannot be mixed by kernel mixer
- *
- * also write data to the record buffer. the record buffer will mix everything.
- */
-void Port::mixer(union parameter *param)
-{
- struct mixer_relation *relation, **relationpointer;
- int len;
- unsigned char *data;
- signed short *data_16;
- int writep;
- signed long *buffer, *record;
- int must_mix = 1; /* set, if we need to mix (not done by kernel) */
-
- /* we do not mix if we have audio from ourself but we need to record
- * unless we have a local echo enabled
- */
- if (param->data.port_id==p_serial && !p_echotest)
- must_mix = 0;
-
- if ((param->data.port_type&PORT_CLASS_MASK)==PORT_CLASS_mISDN
- && (p_type&PORT_CLASS_MASK)==PORT_CLASS_mISDN)
- {
- must_mix = 0;
- }
- if (!p_record && !must_mix) /* if we do not record AND no need to mix */
- {
- return;
- }
-
- /* get the relation to the write pointer. if no relation exists
- * for the given source port, we create one.
- */
- relation = p_mixer_rel;
- relationpointer = &(p_mixer_rel);
- if (!relation) /* there is no relation at all */
- {
- /* clear buffer to 0-volume and reset writep */
- memset(p_mixer_buffer, 0, sizeof(p_mixer_buffer));
- memset(p_record_buffer, 0, sizeof(p_record_buffer));
- memset(p_stereo_buffer, 0, sizeof(p_stereo_buffer));
- } else /* else because we do not need to run a 0-loop */
- while(relation)
- {
- if (relation->port_id == param->data.port_id)
- break;
- relationpointer = &(relation->next);
- relation = relation->next;
- }
- if (!relation)
- {
- relation = *relationpointer = (struct mixer_relation *)calloc(1, sizeof(struct mixer_relation));
- if (!relation)
- {
- PERROR("fatal error: cannot alloc memory for port mixer relation\n");
- return; /* no mem */
- }
- pmemuse++;
- memset(relation, 0, sizeof(struct mixer_relation));
- relation->port_id = param->data.port_id;
- /* put write buffer in front of read buffer */
-#ifndef BETTERDELAY
- relation->mixer_writep = (p_mixer_readp+(PORT_BUFFER/2))%PORT_BUFFER;
-#else
- relation->mixer_writep = p_mixer_readp;
-#endif
-#ifdef MIXER_DEBUG
- PDEBUG(DEBUG_PORT, "PORT(%s) Adding new mixer relation from port #%d (readp=%d, writep=%d, PORT_BUFFER=%d).\n", p_name, param->data.port_id, p_mixer_readp, relation->mixer_writep, PORT_BUFFER);
-#endif
- }
-
- /* adding remote's audio data to our mixer_buffer / record_buffer */
- len = param->data.len;
- if (param->data.compressed == 0) /* in case of 16 bit data */
- len >>= 1;
- if (len>PORT_BUFFER)
- PERROR("fatal error: audio data from remote port #%d is larger than mixer buffer %d>%d\n", param->data.port_id, len, PORT_BUFFER);
- writep = relation->mixer_writep;
- buffer = p_mixer_buffer;
- record = p_record_buffer;
- /* if stereo should be recorded */
- if (param->data.port_id == p_serial)
- if (p_record_type == CODEC_STEREO)
- record = p_stereo_buffer;
- /* NOTE: if read and write pointer are equal, the buffer is full */
- if ((p_mixer_readp-writep+PORT_BUFFER)%PORT_BUFFER < len) /* we would overrun the read pointer */
- {
-#ifdef MIXER_DEBUG
- PERROR("PORT(%s) buffer overrun, source port #%d is sending too fast. (dropping %d samples)\n", p_name, param->data.port_id, len);
-#endif
- // we do not resync since dropping causes slowing writepointer down anyway...
- //relation->mixer_writep = (p_mixer_readp+(PORT_BUFFER/2))%PORT_BUFFER;
- return;
- }
-
- if (!p_record && must_mix)
- {
- /* WE MUST MIX BUT DO NOT RECORD */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- buffer[writep++] += audio_law_to_s32[*(data++)];
- writep = 0;
- }
- while(len--) /* write rest */
- buffer[writep++] += audio_law_to_s32[*(data++)];
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- buffer[writep++] += *(data_16++);
- writep = 0;
- }
- while(len--) /* write rest */
- buffer[writep++] += *(data_16++);
- }
- } else /* else */
- if (p_record && !must_mix)
- {
- /* WE MUST RECORD BUT DO NOT MIX */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- record[writep++] += audio_law_to_s32[*(data++)];
- writep = 0;
- }
- while(len--) /* write rest */
- record[writep++] += audio_law_to_s32[*(data++)];
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- record[writep++] += *(data_16++);
- writep = 0;
- }
- while(len--) /* write rest */
- record[writep++] += *(data_16++);
- }
- } else
- {
- /* WE MUST MIX AND MUST RECORD */
- if (param->data.compressed)
- {
- /* compressed data */
- data = param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- {
- buffer[writep] += audio_law_to_s32[*data];
- record[writep++] += audio_law_to_s32[*(data++)];
- }
- writep = 0;
- }
- while(len--) /* write rest */
- {
- buffer[writep] += audio_law_to_s32[*data];
- record[writep++] += audio_law_to_s32[*(data++)];
- }
- } else
- {
- /* uncompressed data */
- data_16 = (signed short *)param->data.data;
- if (len+writep >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+writep-PORT_BUFFER; /* rest to write in front of buffer */
- while(writep < PORT_BUFFER) /* write till buffer end */
- {
- buffer[writep] += *data_16;
- record[writep++] += *(data_16++);
- }
- writep = 0;
- }
- while(len--) /* write rest */
- {
- buffer[writep] += *data_16;
- record[writep++] += *(data_16++);
- }
- }
- }
- relation->mixer_writep = writep; /* new write pointer */
-// PDEBUG(DEBUG_PORT "written data len=%d port=%d (readp=%d, writep=%d, PORT_BUFFER=%d).\n", param->data.len, param->data.port_id, p_mixer_readp, relation->mixer_writep, PORT_BUFFER);
-}
-
-
/*
* read from the given file as specified in port_set_tone and return sample data
- * this data is mixed with the user space mixer (if anything mixed) and
- * filled into the buffer as many as given by length.
- * if compressed is true, the result in buffer is alaw/ulaw-compressed
- * otherwhise it is 16 bit audio. in this case the buffer size must be twice the lenght.
- * the length is the number of samples, not bytes in buffer!
*/
-int Port::read_audio(unsigned char *buffer, int length, int compressed)
+int Port::read_audio(unsigned char *buffer, int length)
{
int l,len;
- unsigned short temp_buffer[PORT_BUFFER]; /* buffer for up to 32 bit of data */
- int codec_in; /* current codec to use */
- unsigned char *buf_in8; /* buffer pointer for alaw/ulaw/8bit data */
- signed short *buf_in16; /* buffer pointer for alaw/ulaw/8bit data */
- signed short *buf_out16; /* buffer pointer for outgoing audio data */
- signed long *mix_buffer, *mix_buffer2, sample; /* pointer to mixer buffer */
- struct mixer_relation *relation, **relationpointer;
int readp;
- int nodata=0; /* to detect 0-length files */
+ int nodata=0; /* to detect 0-length files and avoid endless reopen */
char filename[128];
- signed short record_buffer[PORT_BUFFER<<1], *rec_buffer; /* buffer of recorded part which will be written (*2 for stereo) */
- unsigned char *rec8_buffer; /* used to send 8-bit audio (wave-8bit, law) */
int tone_left_before; /* temp variable to determine the change in p_tone_left */
/* nothing */
if (length == 0)
return(0);
- /* just in case, we get too much to do */
- if (length > PORT_BUFFER-1)
- length = PORT_BUFFER-1;
-
len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
-
codec_in = p_tone_codec;
/* if there is no tone set, use silence */
if (p_tone_name[0] == 0)
{
- codec_in = CODEC_LAW;
rest_is_silence:
- switch(codec_in)
- {
- case CODEC_LAW:
- memset(buf_in8, (options.law=='a')?0x2a:0xff, len); /* silence */
- break;
-
- case CODEC_MONO:
- case CODEC_8BIT:
- case CODEC_STEREO:
- memset(buf_in16, 0, len<<1); /* silence */
- break;
-
- default:
- PERROR("Software error: no codec during silence\n");
- exit(-1);
- }
- goto mix_to_buffer;
+ memset(buffer, (options.law=='a')?0x2a:0xff, len); /* silence */
+ goto done;
}
/* if the file pointer is not open, we open it */
@@ -877,8 +527,6 @@ rest_is_silence:
}
fhuse++;
}
- codec_in = p_tone_codec;
-//printf("\n\ncodec=%d\n\n\n", p_tone_codec);
PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
}
@@ -887,69 +535,19 @@ read_more:
tone_left_before = p_tone_left;
if (p_tone_fh >= 0)
{
- switch(codec_in)
- {
- case CODEC_LAW:
- l = read_tone(p_tone_fh, buf_in8, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in8 += l;
- len -= l;
- break;
-
- case CODEC_8BIT:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- case CODEC_MONO:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- case CODEC_STEREO:
- l = read_tone(p_tone_fh, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- default:
- PERROR("Software error: current tone reading has no codec\n");
- exit(-1);
- }
+ l = read_tone(p_tone_fh, buffer, p_tone_codec, len, p_tone_size, &p_tone_left, p_tone_speed);
+ if (l<0 || l>len) /* paranoia */
+ l=0;
+ buffer += l;
+ len -= l;
}
if (p_tone_fetched)
{
- switch(codec_in)
- {
- case CODEC_LAW:
- l = read_tone_fetched(&p_tone_fetched, buf_in8, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in8 += l;
- len -= l;
- break;
-
- case CODEC_MONO:
- l = read_tone_fetched(&p_tone_fetched, buf_in16, codec_in, len, p_tone_size, &p_tone_left, p_tone_speed);
- if (l<0 || l>len) /* paranoia */
- l=0;
- buf_in16 += l;
- len -= l;
- break;
-
- default:
- PERROR("Software error: current tone reading has no codec\n");
- exit(-1);
- }
+ l = read_tone_fetched(&p_tone_fetched, buffer, len, p_tone_size, &p_tone_left, p_tone_speed);
+ if (l<0 || l>len) /* paranoia */
+ l=0;
+ buffer += l;
+ len -= l;
}
/* if counter is enabled, we check if we have a change */
@@ -968,7 +566,7 @@ read_more:
}
if (len==0)
- goto mix_to_buffer;
+ goto done;
if (p_tone_fh >= 0)
{
@@ -1031,690 +629,23 @@ try_loop:
}
fhuse++;
}
- codec_in = p_tone_codec;
nodata++;
PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
/* now we have opened the loop */
goto read_more;
- /* **********
- * now we mix
- * we take the buffer content and mix the mixer_buffer to what we got
- */
-mix_to_buffer:
- /* release all writepointer which will underrun, since writing of
- * remote port data is too slow
- */
- relation = p_mixer_rel;
- readp = p_mixer_readp;
- relationpointer = &(p_mixer_rel);
- while(relation) /* if no relation, this is skipped */
- {
- /* NOTE: if writep and readp are equal, the distance ist max
- * == PORT_BUFFER
- */
- if (((relation->mixer_writep-readp-1+PORT_BUFFER)%PORT_BUFFER)+1 <= length) /* underrun */
- {
- /* remove port relation in order to resync.
- * this is also caused by ports which do not transmit
- * anymore.
- */
-#ifdef MIXER_DEBUG
- PERROR("PORT(%s) Buffer underrun, source port is sending too slow or stopped sending, removing relation. (readp=%d, writep=%d, PORT_BUFFER=%d)\n", p_name, readp, relation->mixer_writep, PORT_BUFFER);
-#endif
-
- *relationpointer = relation->next;
- memset(relation, 0, sizeof(struct mixer_relation));
- free(relation);
- pmemuse--;
- relation = *relationpointer;
- continue;
- }
- relationpointer = &(relation->next);
- relation = relation->next;
- }
-
- /* if we do recording, we write the record data and the buffer data to the record fp and increment record_count */
- if (p_record)
- switch (p_record_type)
- {
- case CODEC_MONO:
- /* convert from mixer to uncompressed 16 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<1), 1, p_record);
- p_record_length = (length<<1) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_STEREO:
- /* convert from mixer to uncompressed 16 bit stereo audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- mix_buffer2 = p_stereo_buffer;
- rec_buffer = record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
-
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec_buffer++) = sample;
- *(rec_buffer++) = mix_buffer2[readp];
- mix_buffer2[readp++] = 0;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length<<2), 1, p_record);
- p_record_length = (length<<2) + p_record_length;
- }
- break;
- }
- break;
-
- case CODEC_8BIT:
- /* convert from mixer to uncompressed 8 bit mono audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = (sample>>8)+0x80;
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- }
- break;
-
- case CODEC_LAW:
- case CODEC_OFF: /* if no codec is specified, the recorded data will be stored as LAW */
- /* convert from mixer to law */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
-
- case CODEC_LAW:
- len = length;
- mix_buffer = p_record_buffer;
- rec8_buffer = (unsigned char *)record_buffer;
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(rec8_buffer++) = audio_s16_to_law[sample & 0xffff];
- }
-
- /* restore (changed) read pointer for further use */
- readp = p_mixer_readp;
-
- /* now write the rec_buffer to the file */
- if (p_record_skip)
- {
- p_record_skip -= length;
- if (p_record_skip < 0)
- p_record_skip = 0;
- } else
- {
- fwrite(record_buffer, (length), 1, p_record);
- p_record_length = (length) + p_record_length;
- }
- break;
- }
- break;
- }
-
- /* if we have no transmitting relation, we do not need read mixer */
- if (!p_mixer_rel)
- { /* nothing mixed to(no rel), so we are just done */
- if (compressed)
- {
- /* compress to law */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- *(buffer++) = audio_s16_to_law[*(buf_in16++) & 0xffff];
- break;
-
- case CODEC_LAW:
- memcpy(buffer, temp_buffer, length);
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- } else
- {
- /* uncompress law files */
- len = length;
- buf_in8 = (unsigned char *)temp_buffer;
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- while(len--)
- (*(buf_out16++)) = *(buf_in16++);
- break;
-
- case CODEC_LAW:
- while(len--)
- (*(buf_out16++)) = audio_law_to_s32[*(buf_in8++)];
- break;
-
- default:
- PERROR("Software error: current tone for unmixed & uncompressed, has no codec\n");
- exit(-1);
- }
- }
- return(length);
- }
-
-// PDEBUG(DEBUG_PORT, "PORT(%s) mixing %d bytes. (readp=%d, PORT_BUFFER=%d)\n", p_name, length, readp, PORT_BUFFER);
- /* now we got our stuff and we'll mix it baby */
-
- len = length;
- mix_buffer = p_mixer_buffer;
- if (compressed)
- {
- /* convert from mixer to compressed law data */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buffer++) = audio_s16_to_law[sample & 0xffff];
- }
- break;
-
- default:
- PERROR("Software error: current tone for compressed data has no codec\n");
- exit(-1);
- }
- } else
- {
- /* convert from mixer to uncompressed 16 bit audio */
- switch(codec_in)
- {
- case CODEC_MONO:
- case CODEC_STEREO:
- case CODEC_8BIT:
- buf_in16 = (signed short *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+*(buf_in16++);
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- case CODEC_LAW:
- buf_in8 = (unsigned char *)temp_buffer;
- buf_out16 = (signed short *)buffer;
- if (len+readp >= PORT_BUFFER) /* data hits the buffer end */
- {
- len = len+readp-PORT_BUFFER; /* rest to read from buffer start */
- while(readp < PORT_BUFFER)
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- readp = 0;
- }
- while(len--) /* write rest */
- { /* mix till buffer end */
- sample = mix_buffer[readp]+audio_law_to_s32[*(buf_in8++)];
- mix_buffer[readp++] = 0;
- if (sample < -32767)
- sample = -32767;
- if (sample > 32767)
- sample = 32767;
- *(buf_out16++) = sample;
- }
- break;
-
- default:
- PERROR("Software error: current tone for uncompressed data has no codec\n");
- exit(-1);
- }
- }
-
- p_mixer_readp = readp; /* new read pointer */
-
+done:
return(length);
}
-/* dummy handler */
+/* port handler:
+ * process transmission clock */
int Port::handler(void)
{
+ port
+
return(0);
}