#include <linux/zaptel.h>
#endif
+/* uncomment if you have problems with 'monitoring' synchronized files */
+#if 0
+#define MONITOR_CONSTANT_DELAY
+#define MONITOR_DELAY 150 * 8 /* 150 ms of MONITORING DELAY */
+#endif
static int shutting_down = 0;
static int uniqueint = 0;
f = &null_frame;
} else {
if (chan->monitor && chan->monitor->read_stream ) {
- if( ast_writestream( chan->monitor->read_stream, f ) < 0 ) {
+#ifndef MONITOR_CONSTANT_DELAY
+ int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
+ if (jump >= 0) {
+ if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+ chan->insmpl += jump + 2 * f->samples;
+ } else
+ chan->insmpl+= f->samples;
+#else
+ int jump = chan->outsmpl - chan->insmpl;
+ if (jump - MONITOR_DELAY >= 0) {
+ if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+ chan->insmpl += jump;
+ } else
+ chan->insmpl += f->samples;
+#endif
+ if (ast_writestream(chan->monitor->read_stream, f) < 0)
ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
- }
}
if (chan->pvt->readtrans) {
f = ast_translate(chan->pvt->readtrans, f, 1);
f = ast_translate(chan->pvt->writetrans, fr, 0);
} else
f = fr;
- if (f)
- {
+ if (f) {
res = chan->pvt->write(chan, f);
if( chan->monitor &&
chan->monitor->write_stream &&
f && ( f->frametype == AST_FRAME_VOICE ) ) {
- if( ast_writestream( chan->monitor->write_stream, f ) < 0 ) {
+#ifndef MONITOR_CONSTANT_DELAY
+ int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
+ if (jump >= 0) {
+ if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+ chan->outsmpl += jump + 2 * f->samples;
+ } else
+ chan->outsmpl += f->samples;
+#else
+ int jump = chan->insmpl - chan->outsmpl;
+ if (jump - MONITOR_DELAY >= 0) {
+ if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+ chan->outsmpl += jump;
+ } else
+ chan->outsmpl += f->samples;
+#endif
+ if (ast_writestream(chan->monitor->write_stream, f) < 0)
ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
- }
}
- }
- else
+ } else
res = 0;
}
}
max = lseek(fs->fd, 0, SEEK_END);
bytes = 20 * (sample_offset / 160);
- if(whence == SEEK_SET)
+ if (whence == SEEK_SET)
offset = bytes;
- if(whence == SEEK_CUR)
+ else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = cur + bytes;
- if(whence == SEEK_END)
+ else if (whence == SEEK_END)
offset = max - bytes;
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset > max)?max:offset;
+ offset = (offset < min)?min:offset;
+ }
if (lseek(fs->fd, offset, SEEK_SET) < 0)
return -1;
return 0;
distance = (sample_offset/160) * 33;
if(whence == SEEK_SET)
offset = distance;
- if(whence == SEEK_CUR)
+ else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = distance + cur;
- if(whence == SEEK_END)
+ else if(whence == SEEK_END)
offset = max - distance;
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset > max)?max:offset;
+ offset = (offset < min)?min:offset;
+ }
return lseek(fs->fd, offset, SEEK_SET);
}
struct timeval last;
};
-
+#if 0
static struct ast_filestream *glist = NULL;
+#endif
static ast_mutex_t mp3_lock = AST_MUTEX_INITIALIZER;
static int glistcnt = 0;
min = 0;
cur = lseek(fs->fd, 0, SEEK_CUR);
max = lseek(fs->fd, 0, SEEK_END);
- if(whence == SEEK_SET)
+ if (whence == SEEK_SET)
offset = sample_offset;
- if(whence == SEEK_CUR)
+ else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = sample_offset + cur;
- if(whence == SEEK_END)
+ else if (whence == SEEK_END)
offset = max - sample_offset;
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset > max)?max:offset;
+ offset = (offset < min)?min:offset;
+ }
return lseek(fs->fd, offset, SEEK_SET);
}
min = 0;
cur = lseek(fs->fd, 0, SEEK_CUR);
max = lseek(fs->fd, 0, SEEK_END);
- if(whence == SEEK_SET)
+ if (whence == SEEK_SET)
offset = sample_offset;
- if(whence == SEEK_CUR)
+ else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = sample_offset + cur;
- if(whence == SEEK_END)
+ else if (whence == SEEK_END)
offset = max - sample_offset;
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset > max)?max:offset;
+ offset = (offset < min)?min:offset;
+ }
return lseek(fs->fd, offset, SEEK_SET);
}
min = 44; /* wav header is 44 bytes */
cur = lseek(fs->fd, 0, SEEK_CUR);
max = lseek(fs->fd, 0, SEEK_END);
- if(whence == SEEK_SET)
+ if (whence == SEEK_SET)
offset = samples + min;
- if(whence == SEEK_CUR)
+ else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = samples + cur;
- if(whence == SEEK_END)
- offset = max - samples;
- offset = (offset > max)?max:offset;
- offset = (offset < min)?min:offset;
+ else if (whence == SEEK_END)
+ offset = max - samples;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset > max)?max:offset;
+ offset = (offset < min)?min:offset;
+ }
return lseek(fs->fd,offset,SEEK_SET);
}
distance = (sample_offset/320) * 65;
if(whence == SEEK_SET)
offset = distance + min;
- if(whence == SEEK_CUR)
+ else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
offset = distance + cur;
- if(whence == SEEK_END)
+ else if(whence == SEEK_END)
offset = max - distance;
- offset = (offset < min)?min:offset;
- offset = (offset > max)?max:offset;
+ if (whence != SEEK_FORCECUR) {
+ offset = (offset < min)?min:offset;
+ offset = (offset > max)?max:offset;
+ }
fs->secondhalf = 0;
return lseek(fs->fd, offset, SEEK_SET);
}
/* Channel monitoring */
struct ast_channel_monitor *monitor;
+ /*! Track the read/written samples for monitor use */
+ unsigned long insmpl;
+ unsigned long outsmpl;
+
/* Frames in/out counters */
unsigned int fin;
unsigned int fout;
//! Convenient for waiting
#define AST_DIGIT_ANY "0123456789#*"
+#define SEEK_FORCECUR 10
+
/* Defined by individual formats. First item MUST be a
pointer for use by the stream manager */
struct ast_filestream;