add looping buffers

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4849 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2007-04-04 18:22:59 +00:00
parent 79e54b1fd1
commit ceb98915bb
4 changed files with 50 additions and 48 deletions

View File

@ -96,6 +96,21 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_inuse(switch_buffer_t *buffer);
*/
SWITCH_DECLARE(switch_size_t) switch_buffer_read(switch_buffer_t *buffer, void *data, switch_size_t datalen);
/*! \brief Read data endlessly from a switch_buffer_t
* \param buffer any buffer of type switch_buffer_t
* \param data pointer to the read data to be returned
* \param datalen amount of data to be returned
* \return int ammount of data actually read
* \note Once you have read all the data from the buffer it will loop around.
*/
SWITCH_DECLARE(switch_size_t) switch_buffer_read_loop(switch_buffer_t *buffer, void *data, switch_size_t datalen);
/*! \brief Assign a number of loops to read
* \param buffer any buffer of type switch_buffer_t
* \param loops the number of loops (-1 for infinite)
*/
SWITCH_DECLARE(void) switch_buffer_set_loops(switch_buffer_t *buffer, int32_t loops);
/*! \brief Write data into a switch_buffer_t up to the length of datalen
* \param buffer any buffer of type switch_buffer_t
* \param data pointer to the data to be written

View File

@ -46,7 +46,6 @@ struct teletone_obj {
switch_core_session_t *session;
switch_codec_t codec;
switch_buffer_t *audio_buffer;
switch_buffer_t *loop_buffer;
switch_memory_pool_t *pool;
switch_timer_t *timer;
switch_timer_t timer_base;
@ -158,7 +157,6 @@ static void teletone_destroy(JSContext * cx, JSObject * obj)
}
teletone_destroy_session(&tto->ts);
switch_buffer_destroy(&tto->audio_buffer);
switch_buffer_destroy(&tto->loop_buffer);
switch_core_codec_destroy(&tto->codec);
pool = tto->pool;
tto->pool = NULL;
@ -221,17 +219,12 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
return JS_FALSE;
}
loops--;
if (!tto->loop_buffer) {
switch_buffer_create_dynamic(&tto->loop_buffer, JS_BLOCK_SIZE, JS_BUFFER_SIZE, 0);
}
}
if (tto->audio_buffer) {
switch_buffer_zero(tto->audio_buffer);
}
if (tto->loop_buffer) {
switch_buffer_zero(tto->loop_buffer);
}
tto->ts.debug = 1;
tto->ts.debug_stream = switch_core_get_console();
@ -250,6 +243,10 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
}
}
if (loops) {
switch_buffer_set_loops(tto->audio_buffer, loops);
}
for (;;) {
if (switch_test_flag(tto, TTF_DTMF)) {
@ -284,24 +281,10 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
break;
}
}
if ((write_frame.datalen = (uint32_t) switch_buffer_read(tto->audio_buffer, fdata, write_frame.codec->implementation->bytes_per_frame)) <= 0) {
if (loops) {
switch_buffer_t *tmp;
/* Switcharoo */
tmp = tto->audio_buffer;
tto->audio_buffer = tto->loop_buffer;
tto->loop_buffer = tmp;
loops--;
/* try again */
if ((write_frame.datalen =
(uint32_t) switch_buffer_read(tto->audio_buffer, fdata, write_frame.codec->implementation->bytes_per_frame)) <= 0) {
if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(tto->audio_buffer,
fdata, write_frame.codec->implementation->bytes_per_frame)) <= 0) {
break;
}
} else {
break;
}
}
write_frame.samples = write_frame.datalen / 2;
for (stream_id = 0; stream_id < switch_core_session_get_stream_count(session); stream_id++) {
@ -310,9 +293,6 @@ static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsva
break;
}
}
if (tto->loop_buffer && loops) {
switch_buffer_write(tto->loop_buffer, write_frame.data, write_frame.datalen);
}
}
if (tto->timer) {

View File

@ -48,6 +48,7 @@ struct switch_buffer {
switch_size_t blocksize;
uint32_t flags;
uint32_t id;
int32_t loops;
};
SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool, switch_buffer_t **buffer, switch_size_t max_len)
@ -147,6 +148,26 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_toss(switch_buffer_t *buffer, switch
return buffer->used;
}
SWITCH_DECLARE(void) switch_buffer_set_loops(switch_buffer_t *buffer, int32_t loops)
{
buffer->loops = loops;
}
SWITCH_DECLARE(switch_size_t) switch_buffer_read_loop(switch_buffer_t *buffer, void *data, switch_size_t datalen)
{
switch_size_t len;
if ((len = switch_buffer_read(buffer, data, datalen)) == 0) {
if (buffer->loops == 0) {
return 0;
}
buffer->head = buffer->data;
buffer->used = buffer->actually_used;
len = switch_buffer_read(buffer, data, datalen);
buffer->loops--;
}
return len;
}
SWITCH_DECLARE(switch_size_t) switch_buffer_read(switch_buffer_t *buffer, void *data, switch_size_t datalen)
{
switch_size_t reading = 0;

View File

@ -210,7 +210,6 @@ static uint8_t check_channel_status(switch_channel_t **peer_channels,
struct ringback {
switch_buffer_t *audio_buffer;
switch_buffer_t *loop_buffer;
teletone_generation_session_t ts;
switch_file_handle_t fhb;
switch_file_handle_t *fh;
@ -623,7 +622,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
char *tmp_data = NULL;
switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
switch_buffer_set_loops(ringback.audio_buffer, -1);
if (*ringback_data == '/') {
char *ext;
@ -665,7 +664,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
teletone_destroy_session(&ringback.ts);
switch_buffer_destroy(&ringback.audio_buffer);
switch_buffer_destroy(&ringback.loop_buffer);
ringback_data = NULL;
}
}
@ -747,27 +745,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
break;
}
} else if (ringback.audio_buffer) {
if ((write_frame.datalen = (uint32_t) switch_buffer_read(ringback.audio_buffer,
write_frame.data,
write_frame.codec->implementation->bytes_per_frame)) <= 0) {
switch_buffer_t *tmp;
tmp = ringback.audio_buffer;
ringback.audio_buffer = ringback.loop_buffer;
ringback.loop_buffer = tmp;
if ((write_frame.datalen = (uint32_t) switch_buffer_read(ringback.audio_buffer,
if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
write_frame.data,
write_frame.codec->implementation->bytes_per_frame)) <= 0) {
break;
}
}
}
if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
break;
}
if (ringback.loop_buffer) {
switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
}
}
} else {
@ -908,7 +895,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
} else if (ringback.audio_buffer) {
teletone_destroy_session(&ringback.ts);
switch_buffer_destroy(&ringback.audio_buffer);
switch_buffer_destroy(&ringback.loop_buffer);
}
for (i = 0; i < and_argc; i++) {