static int sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) { SINC_FILTER *filter ; double input_index, src_ratio, count, float_increment, terminate, rem ; increment_t increment, start_filter_index ; int half_filter_chan_len, samples_in_hand ; if (psrc->private_data == NULL) return SRC_ERR_NO_PRIVATE ; filter = (SINC_FILTER*) psrc->private_data ; /* If there is not a problem, this will be optimised out. */ if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) return SRC_ERR_SIZE_INCOMPATIBILITY ; filter->in_count = data->input_frames * filter->channels ; filter->out_count = data->output_frames * filter->channels ; filter->in_used = filter->out_gen = 0 ; src_ratio = psrc->last_ratio ; if (is_bad_src_ratio (src_ratio)) return SRC_ERR_BAD_INTERNAL_STATE ; /* Check the sample rate ratio wrt the buffer len. */ count = (filter->coeff_half_len + 2.0) / filter->index_inc ; if (MIN (psrc->last_ratio, data->src_ratio) < 1.0) count /= MIN (psrc->last_ratio, data->src_ratio) ; /* Maximum coefficientson either side of center point. */ half_filter_chan_len = filter->channels * (lrint (count) + 1) ; input_index = psrc->last_position ; float_increment = filter->index_inc ; rem = fmod_one (input_index) ; filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; input_index = rem ; terminate = 1.0 / src_ratio + 1e-20 ; /* Main processing loop. */ while (filter->out_gen < filter->out_count) { /* Need to reload buffer? */ samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; if (samples_in_hand <= half_filter_chan_len) { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0) return psrc->error ; samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; if (samples_in_hand <= half_filter_chan_len) break ; } ; /* This is the termination condition. */ if (filter->b_real_end >= 0) { if (filter->b_current + input_index + terminate >= filter->b_real_end) break ; } ; if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10) src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ; float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ; increment = double_to_fp (float_increment) ; start_filter_index = double_to_fp (input_index * float_increment) ; calc_output_hex (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; filter->out_gen += 6 ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; rem = fmod_one (input_index) ; filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; input_index = rem ; } ; psrc->last_position = input_index ; /* Save current ratio rather then target ratio. */ psrc->last_ratio = src_ratio ; data->input_frames_used = filter->in_used / filter->channels ; data->output_frames_gen = filter->out_gen / filter->channels ; return SRC_ERR_NO_ERROR ; } /* sinc_hex_vari_process */
static int linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) { LINEAR_DATA *priv ; double src_ratio, input_index, rem ; int ch ; if (data->input_frames <= 0) return SRC_ERR_NO_ERROR ; if (psrc->private_data == NULL) return SRC_ERR_NO_PRIVATE ; priv = (LINEAR_DATA*) psrc->private_data ; if (priv->reset) { /* If we have just been reset, set the last_value data. */ for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [ch] ; priv->reset = 0 ; } ; priv->in_count = data->input_frames * priv->channels ; priv->out_count = data->output_frames * priv->channels ; priv->in_used = priv->out_gen = 0 ; src_ratio = psrc->last_ratio ; input_index = psrc->last_position ; /* Calculate samples before first sample in input array. */ while (input_index < 1.0 && priv->out_gen < priv->out_count) { if (priv->in_used + priv->channels * (1.0 + input_index) >= priv->in_count) break ; if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index * (data->data_in [ch] - priv->last_value [ch])) ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; } ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; /* Main processing loop. */ while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index < priv->in_count) { if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; if (SRC_DEBUG && priv->in_used < priv->channels && input_index < 1.0) { printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", priv->in_used, priv->channels, input_index) ; exit (1) ; } ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - priv->channels + ch] + input_index * (data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - priv->channels + ch])) ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; } ; if (priv->in_used > priv->in_count) { input_index += (priv->in_used - priv->in_count) / priv->channels ; priv->in_used = priv->in_count ; } ; psrc->last_position = input_index ; if (priv->in_used > 0) for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ; /* Save current ratio rather then target ratio. */ psrc->last_ratio = src_ratio ; data->input_frames_used = priv->in_used / priv->channels ; data->output_frames_gen = priv->out_gen / priv->channels ; return SRC_ERR_NO_ERROR ; } /* linear_vari_process */
static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) { ZOH_DATA *priv ; double src_ratio, input_index, rem ; int ch ; if (data->input_frames <= 0) return SRC_ERR_NO_ERROR ; if (psrc->private_data == NULL) return SRC_ERR_NO_PRIVATE ; priv = (ZOH_DATA*) psrc->private_data ; if (priv->reset) { /* If we have just been reset, set the last_value data. */ for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [ch] ; priv->reset = 0 ; } ; priv->in_count = data->input_frames * priv->channels ; priv->out_count = data->output_frames * priv->channels ; priv->in_used = priv->out_gen = 0 ; src_ratio = psrc->last_ratio ; if (is_bad_src_ratio (src_ratio)) return SRC_ERR_BAD_INTERNAL_STATE ; input_index = psrc->last_position ; /* Calculate samples before first sample in input array. */ while (input_index < 1.0 && priv->out_gen < priv->out_count) { if (priv->in_used + priv->channels * input_index >= priv->in_count) break ; if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = priv->last_value [ch] ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; } ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; /* Main processing loop. */ while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index <= priv->in_count) { if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = data->data_in [priv->in_used - priv->channels + ch] ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; } ; if (priv->in_used > priv->in_count) { input_index += (priv->in_used - priv->in_count) / priv->channels ; priv->in_used = priv->in_count ; } ; psrc->last_position = input_index ; if (priv->in_used > 0) for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ; /* Save current ratio rather then target ratio. */ psrc->last_ratio = src_ratio ; data->input_frames_used = priv->in_used / priv->channels ; data->output_frames_gen = priv->out_gen / priv->channels ; return SRC_ERR_NO_ERROR ; } /* zoh_vari_process */