+ if (p_record_vbox_email[0]) {
+ send_mail(p_record_vbox_email_file?filename:(char *)"", callerid, callerinfo.extension, callerinfo.name, p_record_vbox_email, p_record_vbox_year, p_record_vbox_mon, p_record_vbox_mday, p_record_vbox_hour, p_record_vbox_min, p_record_extension);
+ }
+ }
+}
+
+
+/*
+ * recording function
+ * Records all data from down and from up into one single stream.
+ * Both streams may have gaps or jitter.
+ * A Jitter buffer for both streams is used to compensate jitter.
+ *
+ * If one stream (dir) received packets, they are stored to a
+ * buffer to wait for the other stream (dir), so both streams can
+ * be combined. If the buffer is full, it's content is written
+ * without mixing stream. (assuming only one stram (dir) exists.)
+ * A flag is used to indicate what stream is currently in buffer.
+ *
+ * NOTE: First stereo sample (odd) is from down, second is from up.
+ */
+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 int sample;
+ int ret;
+
+ /* no recording */
+ if (!p_record || !length)
+ return;
+
+ /* skip data from local caller (dtmf input) */
+ if (p_record_skip && !dir_fromup) {
+ /* 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:
+
+//printf("same free=%d length=%d\n", free, length);
+ /* first write what we can to the buffer */
+ while(free && length) {
+ p_record_buffer[p_record_buffer_writep] = audio_law_to_s32[*data++];
+ p_record_buffer_writep = (p_record_buffer_writep + 1) & RECORD_BUFFER_MASK;
+ free--;
+ length--;
+ }
+ /* all written, so we return */
+ if (!length)
+ return;
+ /* still data left, buffer is full, so we need to write a chunk to file */
+ switch(p_record_type) {
+ case CODEC_MONO:
+ s = (signed short *)write_buffer;
+ i = 0;
+ while(i < 256) {
+ *s++ = p_record_buffer[p_record_buffer_readp];
+ p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
+ i++;
+ }
+ ret = fwrite(write_buffer, 512, 1, p_record);
+ p_record_length += 512;
+ break;
+
+ case CODEC_STEREO:
+ s = (signed short *)write_buffer;
+ if (p_record_buffer_dir) {
+ i = 0;
+ while(i < 256) {
+ *s++ = 0; /* nothing from down */
+ *s++ = p_record_buffer[p_record_buffer_readp];
+ p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
+ i++;
+ }
+ } else {
+ i = 0;
+ while(i < 256) {
+ *s++ = p_record_buffer[p_record_buffer_readp];
+ *s++ = 0; /* nothing from up */
+ p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
+ i++;
+ }
+ }
+ ret = fwrite(write_buffer, 1024, 1, p_record);
+ p_record_length += 1024;
+ break;
+
+ case CODEC_8BIT:
+ d = write_buffer;
+ i = 0;
+ while(i < 256) {
+ *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++;
+ }
+ ret = fwrite(write_buffer, 512, 1, p_record);
+ p_record_length += 512;
+ break;
+
+ case CODEC_LAW:
+ d = write_buffer;
+ i = 0;
+ while(i < 256) {
+ *d++ = audio_s16_to_law[p_record_buffer[p_record_buffer_readp] & 0xffff];
+ p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
+ i++;
+ }
+ ret = fwrite(write_buffer, 256, 1, p_record);
+ p_record_length += 256;
+ break;