static JSBool teletone_generate(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { struct teletone_obj *tto = JS_GetPrivate(cx, obj); int32 loops = 0; if (argc > 0) { char *script; switch_core_session_t *session; switch_frame_t write_frame = { 0 }; unsigned char *fdata[1024]; switch_frame_t *read_frame; switch_channel_t *channel; if (argc > 1) { if (!JS_ValueToInt32(cx, argv[1], &loops)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Convert to INT\n"); return JS_FALSE; } loops--; } if (tto->audio_buffer) { switch_buffer_zero(tto->audio_buffer); } tto->ts.debug = 1; tto->ts.debug_stream = switch_core_get_console(); script = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); teletone_run(&tto->ts, script); session = tto->session; write_frame.codec = &tto->codec; write_frame.data = fdata; write_frame.buflen = sizeof(fdata); channel = switch_core_session_get_channel(session); if (tto->timer) { switch_core_service_session(session); } if (loops) { switch_buffer_set_loops(tto->audio_buffer, loops); } for (;;) { if (switch_test_flag(tto, TTF_DTMF)) { char dtmf[128]; char *ret; if (switch_channel_has_dtmf(channel)) { uintN aargc = 0; jsval aargv[4]; switch_channel_dequeue_dtmf_string(channel, dtmf, sizeof(dtmf)); aargv[aargc++] = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, dtmf)); JS_CallFunction(cx, obj, tto->function, aargc, aargv, &tto->ret); ret = JS_GetStringBytes(JS_ValueToString(cx, tto->ret)); if (strcmp(ret, "true") && strcmp(ret, "undefined")) { *rval = tto->ret; return JS_TRUE; } } } if (tto->timer) { if (switch_core_timer_next(tto->timer) != SWITCH_STATUS_SUCCESS) { break; } } else { switch_status_t status; status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { break; } } if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(tto->audio_buffer, fdata, write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) { break; } write_frame.samples = write_frame.datalen / 2; if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad Write\n"); break; } } if (tto->timer) { switch_core_thread_session_end(session); } return JS_TRUE; } return JS_FALSE; }
static switch_status_t tone_stream_file_open(switch_file_handle_t *handle, const char *path) { switch_buffer_t *audio_buffer = NULL; teletone_generation_session_t ts; char *tonespec; int loops = 0; char *tmp; int fd = -1; char buf[1024] = ""; size_t len; memset(&ts, 0, sizeof(ts)); tonespec = switch_core_strdup(handle->memory_pool, path); switch_buffer_create_dynamic(&audio_buffer, 1024, 1024, 0); switch_assert(audio_buffer); if ((tmp = (char *)switch_stristr(";loops=", tonespec))) { *tmp = '\0'; tmp += 7; if (tmp) { loops = atoi(tmp); switch_buffer_set_loops(audio_buffer, loops); } } if (handle->params) { if ((tmp = switch_event_get_header(handle->params, "loops"))) { loops = atoi(tmp); switch_buffer_set_loops(audio_buffer, loops); } } if (!handle->samplerate) { handle->samplerate = 8000; } handle->channels = 1; teletone_init_session(&ts, 0, teletone_handler, audio_buffer); ts.rate = handle->samplerate; ts.channels = 1; if (!strncasecmp(tonespec, "path=", 5)) { tmp = tonespec + 5; if ((fd = open(tmp, O_RDONLY)) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to open [%s]\n", tmp); return SWITCH_STATUS_FALSE; } while ((len = switch_fd_read_line(fd, buf, sizeof(buf)))) { teletone_run(&ts, buf); } close(fd); fd = -1; } else { teletone_run(&ts, tonespec); } teletone_destroy_session(&ts); handle->private_info = audio_buffer; return SWITCH_STATUS_SUCCESS; }