00361 {
00362 switch_channel_t *channel = switch_core_session_get_channel(session);
00363 switch_dtmf_t dtmf = {0};
00364 switch_file_handle_t lfh = { 0 };
00365 switch_frame_t *read_frame;
00366 switch_codec_t codec, *read_codec = switch_core_session_get_read_codec(session);
00367 char *codec_name;
00368 switch_status_t status = SWITCH_STATUS_SUCCESS;
00369 const char *p;
00370 const char *vval;
00371 time_t start = 0;
00372 uint32_t org_silence_hits = 0;
00373
00374 switch_assert(read_codec != NULL);
00375
00376 if (!fh) {
00377 fh = &lfh;
00378 }
00379
00380 switch_channel_pre_answer(channel);
00381
00382 fh->channels = read_codec->implementation->number_of_channels;
00383 fh->native_rate = read_codec->implementation->actual_samples_per_second;
00384
00385 if (switch_core_file_open(fh,
00386 file,
00387 fh->channels,
00388 read_codec->implementation->actual_samples_per_second,
00389 SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
00390 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
00391 switch_core_session_reset(session, SWITCH_TRUE);
00392 return SWITCH_STATUS_GENERR;
00393 }
00394
00395 switch_channel_pre_answer(channel);
00396
00397 if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) {
00398 vval = switch_core_session_strdup(session, p);
00399 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval);
00400 switch_channel_set_variable(channel, "RECORD_TITLE", NULL);
00401 }
00402
00403 if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) {
00404 vval = switch_core_session_strdup(session, p);
00405 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval);
00406 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL);
00407 }
00408
00409 if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) {
00410 vval = switch_core_session_strdup(session, p);
00411 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval);
00412 switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL);
00413 }
00414
00415 if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) {
00416 vval = switch_core_session_strdup(session, p);
00417 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval);
00418 switch_channel_set_variable(channel, "RECORD_ARTIST", NULL);
00419 }
00420
00421 if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) {
00422 vval = switch_core_session_strdup(session, p);
00423 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval);
00424 switch_channel_set_variable(channel, "RECORD_COMMENT", NULL);
00425 }
00426
00427 if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) {
00428 vval = switch_core_session_strdup(session, p);
00429 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval);
00430 switch_channel_set_variable(channel, "RECORD_DATE", NULL);
00431 }
00432
00433 codec_name = "L16";
00434 if (switch_core_codec_init(&codec,
00435 codec_name,
00436 NULL,
00437 read_codec->implementation->actual_samples_per_second,
00438 read_codec->implementation->microseconds_per_frame / 1000,
00439 read_codec->implementation->number_of_channels,
00440 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00441 switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
00442 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
00443 switch_core_session_set_read_codec(session, &codec);
00444 } else {
00445 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
00446 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate,
00447 fh->channels, read_codec->implementation->microseconds_per_frame / 1000);
00448 switch_core_file_close(fh);
00449 switch_core_session_reset(session, SWITCH_TRUE);
00450 return SWITCH_STATUS_GENERR;
00451 }
00452
00453 if (limit) {
00454 start = switch_timestamp(NULL);
00455 }
00456
00457 if (fh->thresh) {
00458 if (fh->silence_hits) {
00459 fh->silence_hits = fh->samplerate * fh->silence_hits / read_codec->implementation->samples_per_frame;
00460 } else {
00461 fh->silence_hits = fh->samplerate * 3 / read_codec->implementation->samples_per_frame;
00462 }
00463 org_silence_hits = fh->silence_hits;
00464 }
00465
00466 for(;;) {
00467 switch_size_t len;
00468
00469 if (!switch_channel_ready(channel)) {
00470 status = SWITCH_STATUS_FALSE;
00471 break;
00472 }
00473
00474 if (switch_channel_test_flag(channel, CF_BREAK)) {
00475 switch_channel_clear_flag(channel, CF_BREAK);
00476 status = SWITCH_STATUS_BREAK;
00477 break;
00478 }
00479
00480 if (switch_core_session_private_event_count(session)) {
00481 switch_ivr_parse_all_events(session);
00482 }
00483
00484 if (start && (switch_timestamp(NULL) - start) > limit) {
00485 break;
00486 }
00487
00488 if (args && (args->input_callback || args->buf || args->buflen)) {
00489
00490
00491
00492
00493 if (switch_channel_has_dtmf(channel)) {
00494 if (!args->input_callback && !args->buf) {
00495 status = SWITCH_STATUS_BREAK;
00496 break;
00497 }
00498 switch_channel_dequeue_dtmf(channel, &dtmf);
00499 if (args->input_callback) {
00500 status = args->input_callback(session, (void *)&dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
00501 } else {
00502 switch_copy_string((char *) args->buf, (void *)&dtmf, args->buflen);
00503 status = SWITCH_STATUS_BREAK;
00504 }
00505 }
00506
00507 if (args->input_callback) {
00508 switch_event_t *event = NULL;
00509
00510 if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
00511 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
00512 switch_event_destroy(&event);
00513 }
00514 }
00515
00516 if (status != SWITCH_STATUS_SUCCESS) {
00517 break;
00518 }
00519 }
00520
00521 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00522 if (!SWITCH_READ_ACCEPTABLE(status)) {
00523 break;
00524 }
00525
00526 if (args && (args->read_frame_callback)) {
00527 if (args->read_frame_callback(session, read_frame, args->user_data) != SWITCH_STATUS_SUCCESS) {
00528 break;
00529 }
00530 }
00531
00532 if (fh->thresh) {
00533 int16_t *fdata = (int16_t *) read_frame->data;
00534 uint32_t samples = read_frame->datalen / sizeof(*fdata);
00535 uint32_t score, count = 0, j = 0;
00536 double energy = 0;
00537 int divisor = 0;
00538
00539 for (count = 0; count < samples; count++) {
00540 energy += abs(fdata[j]);
00541 j += read_codec->implementation->number_of_channels;
00542 }
00543
00544 if (!(divisor = read_codec->implementation->actual_samples_per_second / 8000)) {
00545 divisor = 1;
00546 }
00547
00548 score = (uint32_t) (energy / (samples / divisor));
00549 if (score < fh->thresh) {
00550 if (!--fh->silence_hits) {
00551 break;
00552 }
00553 } else {
00554 fh->silence_hits = org_silence_hits;
00555 }
00556 }
00557
00558 if (!switch_test_flag(fh, SWITCH_FILE_PAUSE) && !switch_test_flag(read_frame, SFF_CNG)) {
00559 int16_t *data = read_frame->data;
00560 len = (switch_size_t) read_frame->datalen / 2;
00561
00562 if (switch_core_file_write(fh, data, &len) != SWITCH_STATUS_SUCCESS) {
00563 break;
00564 }
00565 }
00566 }
00567
00568 switch_core_session_set_read_codec(session, read_codec);
00569 switch_core_file_close(fh);
00570 switch_core_session_reset(session, SWITCH_TRUE);
00571 return status;
00572 }