X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=port.cpp;h=02d8dc318500251a2c23ade67f10538ecacc9937;hp=1c0f63e33915b2b7e619b443cb8dc13bf1323645;hb=83477c7faf66a160530f5a01c1bf3016e2127a4d;hpb=e9daaa4ef7ee895e6a8610ebb2166cc99c891a4e diff --git a/port.cpp b/port.cpp index 1c0f63e..02d8dc3 100644 --- a/port.cpp +++ b/port.cpp @@ -19,12 +19,10 @@ Audio flow has two ways: * from the upper layer to the channel -> sound from remote channel - -> sound from asterisk Audio is required: -> if local or remote channel is not mISDN - -> if endpoint is linked to asterisk -> if call is recorded (vbox) @@ -57,6 +55,9 @@ Functions: #include #include "main.h" +#define SHORT_MIN -32768 +#define SHORT_MAX 32767 + class Port *port_first = NULL; unsigned long port_serial = 1; /* must be 1, because 0== no port */ @@ -88,8 +89,7 @@ void Port::free_epointlist(struct epoint_list *epointlist) /* free */ PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial); - memset(temp, 0, sizeof(struct epoint_list)); - free(temp); + FREE(temp, sizeof(struct epoint_list)); ememuse--; } @@ -110,7 +110,7 @@ void Port::free_epointid(unsigned long epoint_id) } if (temp == 0) { - PERROR("epoint_id not in port's list, exitting.\n"); + PERROR("epoint_id not in port's list.\n"); return; } /* detach */ @@ -118,8 +118,7 @@ void Port::free_epointid(unsigned long epoint_id) /* free */ PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial); - memset(temp, 0, sizeof(struct epoint_list)); - free(temp); + FREE(temp, sizeof(struct epoint_list)); ememuse--; } @@ -131,15 +130,11 @@ struct epoint_list *Port::epointlist_new(unsigned long epoint_id) struct epoint_list *epointlist, **epointlistpointer; /* epointlist structure */ - epointlist = (struct epoint_list *)calloc(1, sizeof(struct epoint_list)); + epointlist = (struct epoint_list *)MALLOC(sizeof(struct epoint_list)); if (!epointlist) - { - PERROR("no mem for allocating epoint_list\n"); - return(0); - } + FATAL("No memory for epointlist\n"); ememuse++; PDEBUG(DEBUG_EPOINT, "PORT(%d) allocating epoint_list.\n", p_serial); - memset(epointlist, 0, sizeof(struct epoint_list)); /* add epoint_list to chain */ epointlist->next = NULL; @@ -175,11 +170,8 @@ 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_last_tv_sec = 0; - p_last_tv_msec = 0; p_type = type; p_serial = port_serial++; - p_debug_nothingtosend = 0; p_tone_fh = -1; p_tone_fetched = NULL; p_tone_name[0] = '\0'; @@ -255,10 +247,7 @@ Port::~Port(void) temp = temp->next; } if (temp == NULL) - { - PERROR("PORT(%s) port not in port's list.\n", p_name); - exit(-1); - } + FATAL("PORT(%s) port not in port's list.\n", p_name); /* detach */ *tempp=this->next; @@ -495,7 +484,7 @@ void Port::set_vbox_speed(int speed) /* * read from the given file as specified in port_set_tone and return sample data - * silence is appended if sample ends, but only the number of samples with tones are returned + * if the tone ends, the result may be less samples than requested */ int Port::read_audio(unsigned char *buffer, int length) { @@ -511,12 +500,8 @@ int Port::read_audio(unsigned char *buffer, int length) len = length; /* if there is no tone set, use silence */ - if (p_tone_name[0] == 0) - { -rest_is_silence: - memset(buffer, (options.law=='a')?0x2a:0xff, len); /* silence */ - goto done; - } + if (!p_tone_name[0]) + return(0); /* if the file pointer is not open, we open it */ if (p_tone_fh<0 && p_tone_fetched==NULL) @@ -586,7 +571,7 @@ read_more: } if (len==0) - goto done; + return(length-len); if (p_tone_fh >= 0) { @@ -605,7 +590,7 @@ read_more: PDEBUG(DEBUG_PORT, "PORT(%s) 0-length loop: %s\n", p_name, filename); p_tone_name[0]=0; p_tone_dir[0]=0; - goto rest_is_silence; + return(length-len); } /* if eof is reached, or if the normal file cannot be opened, continue with the loop file if possible */ @@ -630,7 +615,7 @@ try_loop: PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename); p_tone_dir[0] = '\0'; p_tone_name[0] = '\0'; - goto rest_is_silence; + return(length-len); } fhuse++; } @@ -643,7 +628,7 @@ try_loop: PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename); p_tone_dir[0] = '\0'; p_tone_name[0] = '\0'; - goto rest_is_silence; + return(length-len); } fhuse++; } @@ -652,9 +637,6 @@ try_loop: /* now we have opened the loop */ goto read_more; - -done: - return(length-len); } @@ -825,9 +807,9 @@ void Port::close_record(int beep) PDEBUG(DEBUG_PORT, "data still in record buffer: %d (dir %d)\n", (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK, p_record_buffer_dir); memcpy(&callerinfo, &p_callerinfo, sizeof(struct caller_info)); - apply_callerid_restriction(p_record_anon_ignore, -1, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, NULL/*callerinfo.voip*/, callerinfo.extension, callerinfo.name); +// apply_callerid_restriction(p_record_anon_ignore, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, callerinfo.extension, callerinfo.name); - SCPY(number, p_dialinginfo.number); + SCPY(number, p_dialinginfo.id); SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype)); if (callerid[0] == '\0') { @@ -1047,26 +1029,33 @@ void Port::record(unsigned char *data, int length, int dir_fromup) if (!p_record || !length) return; - /* skip */ - if (dir_fromup) + /* skip data from local caller (dtmf input) */ + if (p_record_skip && !dir_fromup) { - /* more than we have */ + /* more to skip than we have */ if (p_record_skip > length) { p_record_skip -= length; return; } + /* less to skip */ data += p_record_skip; length -= p_record_skip; + p_record_skip = 0; } +//printf("dir=%d len=%d\n", dir_fromup, length); + free = ((p_record_buffer_readp - p_record_buffer_writep - 1) & RECORD_BUFFER_MASK); +//PDEBUG(DEBUG_PORT, "record(data,%d,%d): free=%d, p_record_buffer_dir=%d, p_record_buffer_readp=%d, p_record_buffer_writep=%d.\n", length, dir_fromup, free, p_record_buffer_dir, p_record_buffer_readp, p_record_buffer_writep); + /* the buffer stores the same data stream */ if (dir_fromup == p_record_buffer_dir) { - same_again: +same_again: +//printf("same free=%d length=%d\n", free, length); /* first write what we can to the buffer */ while(free && length) { @@ -1078,7 +1067,7 @@ void Port::record(unsigned char *data, int length, int dir_fromup) /* all written, so we return */ if (!length) return; - /* still data left, buffer is full, so we need to write to file */ + /* still data left, buffer is full, so we need to write a chunk to file */ switch(p_record_type) { case CODEC_MONO: @@ -1091,6 +1080,7 @@ void Port::record(unsigned char *data, int length, int dir_fromup) i++; } fwrite(write_buffer, 512, 1, p_record); + p_record_length += 512; break; case CODEC_STEREO: @@ -1117,6 +1107,7 @@ void Port::record(unsigned char *data, int length, int dir_fromup) } } fwrite(write_buffer, 1024, 1, p_record); + p_record_length += 1024; break; case CODEC_8BIT: @@ -1124,11 +1115,12 @@ void Port::record(unsigned char *data, int length, int dir_fromup) i = 0; while(i < 256) { - *d++ = (p_record_buffer[p_record_buffer_readp]+0x8000) >> 8; + *d++ = ((unsigned short)(p_record_buffer[p_record_buffer_readp]+0x8000)) >> 8; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; i++; } fwrite(write_buffer, 512, 1, p_record); + p_record_length += 512; break; case CODEC_LAW: @@ -1141,14 +1133,16 @@ void Port::record(unsigned char *data, int length, int dir_fromup) i++; } fwrite(write_buffer, 256, 1, p_record); + p_record_length += 256; break; } /* because we still have data, we write again */ - free += sizeof(write_buffer); + free += 256; goto same_again; } /* the buffer stores the other stream */ +different_again: /* if buffer empty, change it */ if (p_record_buffer_readp == p_record_buffer_writep) { @@ -1159,6 +1153,12 @@ void Port::record(unsigned char *data, int length, int dir_fromup) ii = (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK; if (length < ii) ii = length; + + if (ii > 256) + ii = 256; +//printf("same ii=%d length=%d\n", ii, length); +//PDEBUG(DEBUG_PORT, "record(data,%d,%d): free=%d, p_record_buffer_dir=%d, p_record_buffer_readp=%d, p_record_buffer_writep=%d: mixing %d bytes.\n", length, dir_fromup, free, p_record_buffer_dir, p_record_buffer_readp, p_record_buffer_writep, ii); + /* write data mixed with the buffer */ switch(p_record_type) { @@ -1170,14 +1170,13 @@ void Port::record(unsigned char *data, int length, int dir_fromup) sample = p_record_buffer[p_record_buffer_readp] + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; - if (sample < 32767) - sample = -32767; - if (sample > 32768) - sample = 32768; + if (sample < SHORT_MIN) sample = SHORT_MIN; + if (sample > SHORT_MAX) sample = SHORT_MAX; *s++ = sample; i++; } fwrite(write_buffer, ii<<1, 1, p_record); + p_record_length += (ii<<1); break; case CODEC_STEREO: @@ -1199,10 +1198,12 @@ void Port::record(unsigned char *data, int length, int dir_fromup) { *s++ = p_record_buffer[p_record_buffer_readp]; *s++ = audio_law_to_s32[*data++]; + p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; i++; } } fwrite(write_buffer, ii<<2, 1, p_record); + p_record_length += (ii<<2); break; case CODEC_8BIT: @@ -1213,14 +1214,13 @@ void Port::record(unsigned char *data, int length, int dir_fromup) sample = p_record_buffer[p_record_buffer_readp] + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; - if (sample < 32767) - sample = -32767; - if (sample > 32768) - sample = 32768; + if (sample < SHORT_MIN) sample = SHORT_MIN; + if (sample > SHORT_MAX) sample = SHORT_MAX; *d++ = (sample+0x8000) >> 8; i++; } fwrite(write_buffer, ii, 1, p_record); + p_record_length += ii; break; case CODEC_LAW: @@ -1231,23 +1231,19 @@ void Port::record(unsigned char *data, int length, int dir_fromup) sample = p_record_buffer[p_record_buffer_readp] + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; - if (sample < 32767) - sample = -32767; - if (sample > 32768) - sample = 32768; + if (sample < SHORT_MIN) sample = SHORT_MIN; + if (sample > SHORT_MAX) sample = SHORT_MAX; *d++ = audio_s16_to_law[sample & 0xffff]; i++; } fwrite(write_buffer, ii, 1, p_record); + p_record_length += ii; break; } length -= ii; - /* data, but buffer empty */ + /* still data */ if (length) - { - p_record_buffer_dir = dir_fromup; - goto same_again; - } + goto different_again; /* no data (maybe buffer) */ return;