aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-12 18:26:37 +0000
committerfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2008-03-12 18:26:37 +0000
commit7c07a7987bf7a6c2b8abc6028431efbf4346a66d (patch)
tree30072642033dae96e60d35bbd88fdd74b62b75a9 /main
parentde7685531815fc619a99c3c80547a8abf4193157 (diff)
Add a trigger mode that triggers on both read and write. The actual function that returns the combined audio frame though will wait until both sides have fed in audio, or until one side stops (such as the case when you call Wait).
(closes issue #11945) Reported by: xheliox git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@108083 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/audiohook.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/main/audiohook.c b/main/audiohook.c
index 806ae0bea..8fd1501c9 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -128,22 +128,21 @@ int ast_audiohook_destroy(struct ast_audiohook *audiohook)
int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
{
struct ast_slinfactory *factory = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_factory : &audiohook->write_factory);
+ struct timeval *time = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook->read_time : &audiohook->write_time);
/* Write frame out to respective factory */
ast_slinfactory_feed(factory, frame);
+ /* Update last fed time for the above factory */
+ *time = ast_tvnow();
+
/* If we need to notify the respective handler of this audiohook, do so */
- switch (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE)) {
- case AST_AUDIOHOOK_TRIGGER_READ:
- if (direction == AST_AUDIOHOOK_DIRECTION_READ)
- ast_cond_signal(&audiohook->trigger);
- break;
- case AST_AUDIOHOOK_TRIGGER_WRITE:
- if (direction == AST_AUDIOHOOK_DIRECTION_WRITE)
- ast_cond_signal(&audiohook->trigger);
- break;
- default:
- break;
+ if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_READ) && (direction == AST_AUDIOHOOK_DIRECTION_READ)) {
+ ast_cond_signal(&audiohook->trigger);
+ } else if ((ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_MODE) == AST_AUDIOHOOK_TRIGGER_WRITE) && (direction == AST_AUDIOHOOK_DIRECTION_WRITE)) {
+ ast_cond_signal(&audiohook->trigger);
+ } else if (ast_test_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC)) {
+ ast_cond_signal(&audiohook->trigger);
}
return 0;
@@ -179,7 +178,7 @@ static struct ast_frame *audiohook_read_frame_single(struct ast_audiohook *audio
static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audiohook, size_t samples)
{
- int i = 0;
+ int i = 0, usable_read, usable_write;
short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
struct ast_frame frame = {
.frametype = AST_FRAME_VOICE,
@@ -189,8 +188,33 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
.samples = samples,
};
+ /* Make sure both factories have the required samples */
+ usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
+ usable_write = (ast_slinfactory_available(&audiohook->write_factory) >= samples ? 1 : 0);
+
+ if (!usable_read && !usable_write) {
+ /* If both factories are unusable bail out */
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Read factory %p and write factory %p both fail to provide %zd samples\n", &audiohook->read_factory, &audiohook->write_factory, samples);
+ return NULL;
+ }
+
+ /* If we want to provide only a read factory make sure we aren't waiting for other audio */
+ if (usable_read && !usable_write && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Write factory %p was pretty quick last time, waiting for them.\n", &audiohook->write_factory);
+ return NULL;
+ }
+
+ /* If we want to provide only a write factory make sure we aren't waiting for other audio */
+ if (usable_write && !usable_read && (ast_tvdiff_ms(ast_tvnow(), audiohook->write_time) < (samples/8)*2)) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Read factory %p was pretty quick last time, waiting for them.\n", &audiohook->read_factory);
+ return NULL;
+ }
+
/* Start with the read factory... if there are enough samples, read them in */
- if (ast_slinfactory_available(&audiohook->read_factory) >= samples) {
+ if (usable_read && ast_slinfactory_available(&audiohook->read_factory) >= samples) {
if (ast_slinfactory_read(&audiohook->read_factory, buf1, samples)) {
read_buf = buf1;
/* Adjust read volume if need be */
@@ -209,7 +233,7 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
ast_log(LOG_DEBUG, "Failed to get %zd samples from read factory %p\n", samples, &audiohook->read_factory);
/* Move on to the write factory... if there are enough samples, read them in */
- if (ast_slinfactory_available(&audiohook->write_factory) >= samples) {
+ if (usable_write && ast_slinfactory_available(&audiohook->write_factory) >= samples) {
if (ast_slinfactory_read(&audiohook->write_factory, buf2, samples)) {
write_buf = buf2;
/* Adjust write volume if need be */