/* -*- C -*- */ _TYPE_ *data_in, *data_out, *filter_data; filter_data = (_TYPE_ *) filter->buffer; num_filter = filter->buffer_bytes / sizeof(_TYPE_); do { if (in == NULL && ! filter->eos) in = gst_pad_pull(filter->sinkpad); /****************************************************************************/ /* see if we've got any events coming through ... */ while (! filter->eos && GST_IS_EVENT(in)) { if (GST_EVENT_TYPE(in) == GST_EVENT_EOS) { gst_event_unref(in); gst_buffer_free(in); filter->eos = TRUE; } else if ((GST_EVENT_TYPE(in) == GST_EVENT_SEEK) || (GST_EVENT_TYPE(in) == GST_EVENT_FLUSH)) { gst_event_unref(in); gst_buffer_free(in); filter->eos = FALSE; filter->write = 0; } else { gst_pad_push(filter->srcpad, in); } in = gst_pad_pull(filter->sinkpad); } /****************************************************************************/ /* handle data from the input buffer. */ if (! filter->eos) { register guint j, w = filter->write; data_in = (_TYPE_ *) GST_BUFFER_DATA(in); num_in = GST_BUFFER_SIZE(in) / sizeof(_TYPE_); for (j = 0; (j < num_in) && (w+j < num_filter); j++) filter_data[w+j] = data_in[j]; filter->write += j; if (filter->write >= num_filter) filter->eos = TRUE; out = in; } else { out = gst_buffer_new_from_pool(filter->bufpool, 0, 0); } in = NULL; /****************************************************************************/ /* check to see if we have to add new play pointers. */ if (filter->clock) { register gint t, tick_offset; guint total_ticks = filter->total_ticks; guint current_tick = \ ((guint) (gst_clock_get_time(filter->clock) * filter->tick_rate / GST_SECOND)) % total_ticks; /* for some reason modulo arithmetic isn't working for me here, i suspect some unsigned/signed voodoo. but it's probably safe to do this with an if statement since it doesn't happen all that often ... */ tick_offset = current_tick - last_tick; if (tick_offset < 0) tick_offset += total_ticks; for (tick_offset -= 1, t = current_tick - tick_offset; tick_offset >= 0; tick_offset--, t--) { if (t < 0) t += total_ticks; if (filter->ticks[t / 32] & (1 << t % 32)) play_on_demand_add_play_pointer( filter, filter->rate * tick_offset / filter->tick_rate); } last_tick = current_tick; } /****************************************************************************/ /* handle output data. */ { register guint k, p; data_out = (_TYPE_ *) GST_BUFFER_DATA(out); num_out = GST_BUFFER_SIZE(out) / sizeof(_TYPE_); for (k = 0; k < num_out; k++) data_out[k] = zero; for (p = 0; p < filter->max_plays; p++) { guint offset = filter->plays[p]; if (offset != G_MAXUINT) { /* only copy audio data if the element's not muted. */ if (! filter->mute) for (k = 0; (k < num_out) && (offset+k < num_filter); k++) data_out[k] = CLAMP(data_out[k] + filter_data[offset+k], min, max); /* update the play pointer. k > 0 even if the filter is muted. */ filter->plays[p] = (offset+k >= num_filter) ? G_MAXUINT : offset + k; } } } /****************************************************************************/ /* push out the buffer. */ gst_pad_push(filter->srcpad, out); if (gst_element_interrupt (GST_ELEMENT (filter))) break; } while (TRUE);