/* Usually called from the timer callback of @progress->timer. */ void update_progress(struct progress *progress, off_t loaded, off_t size, off_t pos) { off_t bytes_delta; timeval_T now, elapsed, dis_b_max, dis_b_interval; timeval_now(&now); timeval_sub(&elapsed, &progress->last_time, &now); timeval_copy(&progress->last_time, &now); progress->loaded = loaded; bytes_delta = progress->loaded - progress->last_loaded; progress->last_loaded = progress->loaded; timeval_add_interval(&progress->elapsed, &elapsed); timeval_add_interval(&progress->dis_b, &elapsed); timeval_from_milliseconds(&dis_b_max, mult_ms(SPD_DISP_TIME, CURRENT_SPD_SEC)); timeval_from_milliseconds(&dis_b_interval, SPD_DISP_TIME); while (timeval_cmp(&progress->dis_b, &dis_b_max) >= 0) { progress->cur_loaded -= progress->data_in_secs[0]; memmove(progress->data_in_secs, progress->data_in_secs + 1, sizeof(*progress->data_in_secs) * (CURRENT_SPD_SEC - 1)); progress->data_in_secs[CURRENT_SPD_SEC - 1] = 0; timeval_sub_interval(&progress->dis_b, &dis_b_interval); } progress->data_in_secs[CURRENT_SPD_SEC - 1] += bytes_delta; progress->cur_loaded += bytes_delta; progress->current_speed = progress->cur_loaded / (CURRENT_SPD_SEC * ((long) SPD_DISP_TIME) / 1000); progress->pos = pos; progress->size = size; if (progress->size != -1 && progress->size < progress->pos) progress->size = progress->pos; progress->average_speed = timeval_div_off_t(progress->loaded, &progress->elapsed); if (progress->average_speed) /* Division by zero risk */ timeval_from_seconds(&progress->estimated_time, (progress->size - progress->pos) / progress->average_speed); install_timer(&progress->timer, SPD_DISP_TIME, progress_timeout, progress); }
wr_errorcode_t wr_wavfile_filter_start(wr_rtp_filter_t * filter) { SNDFILE * file; SF_INFO file_info; wr_encoder_t * codec; wr_rtp_packet_t rtp_packet; int sequence_number = 0; int rtp_timestamp = 0; struct timeval packet_start_timestamp; struct timeval packet_end_timestamp; gettimeofday(&packet_start_timestamp, NULL); timeval_copy(&packet_end_timestamp, &packet_start_timestamp); int rtp_in_frame = iniparser_getpositiveint(wr_options.output_options, "global:rtp_in_frame", 1); int frames_count = 0; /* open WAV file */ file = sf_open(wr_options.filename, SFM_READ, &file_info); if (!file){ wr_set_error("cannot open or render sound file"); return WR_FATAL; } if (file_info.samplerate != 8000){ wr_set_error("this tool works only with .wav files in 8kHz, rerecord your signal or resample it (with sox for example)\n"); return WR_FATAL; } list_iterator_start(wr_options.codec_list); if (list_iterator_hasnext(wr_options.codec_list)){ codec = (wr_encoder_t*)list_iterator_next(wr_options.codec_list); wr_rtp_packet_init(&rtp_packet, codec->payload_type, sequence_number, 1, rtp_timestamp, packet_start_timestamp); }else{ wr_set_error("no codec is found"); return WR_FATAL; } wr_rtp_filter_notify_observers(filter, TRANSMISSION_START, NULL); /* One cycle iteration encode one data frame */ while(codec){ int input_buffer_size = (*codec->get_input_buffer_size)(codec->state); int output_buffer_size = (*codec->get_output_buffer_size)(codec->state); short input_buffer[input_buffer_size]; char output_buffer[output_buffer_size]; bzero(input_buffer, input_buffer_size); bzero(output_buffer, output_buffer_size); input_buffer_size = sf_read_short(file, input_buffer, input_buffer_size); if (!input_buffer_size){ /*EOF*/ if (frames_count){ wr_rtp_filter_notify_observers(filter, NEW_PACKET, &rtp_packet); wr_rtp_packet_destroy(&rtp_packet); frames_count = 0; sequence_number++; timeval_copy(&packet_start_timestamp, &packet_end_timestamp); wr_rtp_packet_init(&rtp_packet, codec->payload_type, sequence_number, 0, rtp_timestamp, packet_start_timestamp); } sf_seek(file, 0, SEEK_SET); if (list_iterator_hasnext(wr_options.codec_list)){ codec = (wr_encoder_t*)list_iterator_next(wr_options.codec_list); }else{ codec = NULL; list_iterator_stop(wr_options.codec_list); } continue; } output_buffer_size = (*codec->encode)(codec->state, input_buffer, output_buffer); wr_rtp_packet_add_frame(&rtp_packet, output_buffer, output_buffer_size, 1000 * input_buffer_size / file_info.samplerate); timeval_increment(&packet_end_timestamp, 1e6 * input_buffer_size / file_info.samplerate); rtp_timestamp += input_buffer_size; frames_count++; if (frames_count == rtp_in_frame){ wr_rtp_filter_notify_observers(filter, NEW_PACKET, &rtp_packet); wr_rtp_packet_destroy(&rtp_packet); frames_count = 0; sequence_number++; timeval_copy(&packet_start_timestamp, &packet_end_timestamp); wr_rtp_packet_init(&rtp_packet, codec->payload_type, sequence_number, 0, rtp_timestamp, packet_start_timestamp); } } wr_rtp_filter_notify_observers(filter, TRANSMISSION_END, NULL); sf_close(file); }