X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=port.cpp;h=0bc74a23b795b5740cd280a970e88275e345569a;hp=0fdfd39b00e871bd48bcc2cf1a0205cfa1da9c56;hb=ab4a1270e9c99ab7a21a957759de2a885100afb1;hpb=ef3fc1931a2fa82f482d21fb1296735206463d3a diff --git a/port.cpp b/port.cpp index 0fdfd39..0bc74a2 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) @@ -47,19 +45,14 @@ Functions: */ -#include -#include -#include -#include -#include -#include -#include -#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 */ +unsigned int port_serial = 1; /* must be 1, because 0== no port */ /* free epointlist relation @@ -93,7 +86,7 @@ void Port::free_epointlist(struct epoint_list *epointlist) } -void Port::free_epointid(unsigned long epoint_id) +void Port::free_epointid(unsigned int epoint_id) { struct epoint_list *temp, **tempp; @@ -124,7 +117,7 @@ void Port::free_epointid(unsigned long epoint_id) /* create new epointlist relation */ -struct epoint_list *Port::epointlist_new(unsigned long epoint_id) +struct epoint_list *Port::epointlist_new(unsigned int epoint_id) { struct epoint_list *epointlist, **epointlistpointer; @@ -214,10 +207,10 @@ Port::Port(int type, char *portname, struct port_settings *settings) Port::~Port(void) { class Port *temp, **tempp; - struct message *message; + struct lcr_msg *message; if (p_record) - close_record(0); + close_record(0, 0); classuse--; @@ -274,7 +267,7 @@ void Port::new_state(int state) /* * find the port with port_id */ -class Port *find_port_id(unsigned long port_id) +class Port *find_port_id(unsigned int port_id) { class Port *port = port_first; @@ -310,6 +303,17 @@ void Port::set_tone(char *dir, char *name) if (name == NULL) name = ""; +#if 0 + /* if tones is jingle, store next tone */ + if ((p_tone_fh >= 0 || p_tone_fetched) + && (!strcmp(p_tone_name, "left") || !strcmp(p_tone_name, "joined"))) + { + SCPY(p_tone_dir, dir); + SCPY(p_tone_name, name); + return; + } +#endif + /* no counter, no eof, normal speed */ p_tone_counter = 0; p_tone_eof = 0; @@ -446,8 +450,8 @@ void Port::set_vbox_tone(char *dir, char *name) */ void Port::set_vbox_play(char *name, int offset) { - signed long size; - struct message *message; + signed int size; + struct lcr_msg *message; /* use ser_box_tone() */ set_vbox_tone("", name); @@ -561,7 +565,7 @@ read_more: if (((p_tone_size-p_tone_left)/8000) != (p_tone_size-tone_left_before)/8000) { //printf("\nsize=%d left=%d\n\n",p_tone_size,p_tone_left); - struct message *message; + struct lcr_msg *message; message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER); message->param.counter.current = (p_tone_size-p_tone_left)/8000; message->param.counter.max = -1; @@ -596,7 +600,7 @@ read_more: try_loop: if (p_tone_eof && ACTIVE_EPOINT(p_epointlist)) { - struct message *message; + struct lcr_msg *message; message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_EOF); message_put(message); } @@ -650,8 +654,8 @@ int Port::handler(void) * this is called by the message_epoint inherited by child classes * therefor a return=1 means: stop, no more processing */ -//extern struct message *dddebug; -int Port::message_epoint(unsigned long epoint_id, int message_id, union parameter *param) +//extern struct lcr_msg *dddebug; +int Port::message_epoint(unsigned int epoint_id, int message_id, union parameter *param) { /* check if we got audio data from one remote port */ switch(message_id) @@ -686,8 +690,8 @@ int Port::message_epoint(unsigned long epoint_id, int message_id, union paramete struct fmt { unsigned short stereo; /* 1 = mono, 2 = stereo */ unsigned short channels; /* number of channels */ - unsigned long sample_rate; /* sample rate */ - unsigned long data_rate; /* data rate */ + unsigned int sample_rate; /* sample rate */ + unsigned int data_rate; /* data rate */ unsigned short bytes_sample; /* bytes per sample (all channels) */ unsigned short bits_sample; /* bits per sample (one channel) */ }; @@ -787,11 +791,10 @@ int Port::open_record(int type, int vbox, int skip, char *extension, int anon_ig /* * close the recoding file, put header in front and rename */ -void Port::close_record(int beep) +void Port::close_record(int beep, int mute) { - static signed long beep_mono[] = {-10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000}; - static unsigned char beep_8bit[] = {48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208}; - unsigned long size, wsize; + static signed short beep_mono[256]; + unsigned int size, wsize; struct fmt fmt; char filename[512], indexname[512]; FILE *fp; @@ -806,10 +809,10 @@ 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, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, 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.id); - SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype)); + SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype, options.national, options.international)); if (callerid[0] == '\0') { if (callerinfo.present == INFO_PRESENT_RESTRICTED) @@ -848,41 +851,31 @@ void Port::close_record(int beep) i++; } + /* mute */ + if (mute && p_record_type==CODEC_MONO) + { + i = p_record_length; + if (i > mute) + i = mute; + fseek(p_record, -(i<<1), SEEK_END); + p_record_length -= (i<<1); + } /* add beep to the end of recording */ - if (beep) - switch(p_record_type) + if (beep && p_record_type==CODEC_MONO) { - case CODEC_MONO: i = 0; - while(i < beep) + while(i < 256) { - fwrite(beep_mono, sizeof(beep_mono), 1, p_record); - i += sizeof(beep_mono); - p_record_length += sizeof(beep_mono); - } - break; - case CODEC_8BIT: - i = 0; - while(i < beep) - { - fwrite(beep_8bit, sizeof(beep_8bit), 1, p_record); - i += sizeof(beep_8bit); - p_record_length += sizeof(beep_8bit); + beep_mono[i] = (signed short)(sin((double)i / 5.688888888889 * 2.0 * 3.1415927) * 2000.0); + i++; } - break; -#if 0 - case CODEC_LAW: i = 0; while(i < beep) { - fwrite(beep_law, sizeof(beep_law), 1, p_record); - i += sizeof(beep_law); - p_record_length += sizeof(beep_law); + fwrite(beep_mono, sizeof(beep_mono), 1, p_record); + i += sizeof(beep_mono); + p_record_length += sizeof(beep_mono); } - break; -#endif - default: - PERROR("codec %d not supported for beep adding\n", p_record_type); } /* complete header */ @@ -1022,32 +1015,39 @@ void Port::record(unsigned char *data, int length, int dir_fromup) unsigned char write_buffer[1024], *d; signed short *s; int free, i, ii; - signed long sample; + signed int sample; /* no recording */ 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) { @@ -1059,7 +1059,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: @@ -1072,6 +1072,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: @@ -1098,6 +1099,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: @@ -1105,11 +1107,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: @@ -1122,14 +1125,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) { @@ -1140,6 +1145,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) { @@ -1151,14 +1162,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: @@ -1180,10 +1190,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: @@ -1194,14 +1206,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: @@ -1212,23 +1223,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;