summaryrefslogtreecommitdiff
path: root/filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/filter.c b/filter.c
new file mode 100644
index 0000000..00da459
--- /dev/null
+++ b/filter.c
@@ -0,0 +1,137 @@
+#include "esd-server.h"
+
+esd_player_t *esd_filter_list = NULL;
+
+translate_func_t esd_first_filter_func;
+
+/*******************************************************************/
+/* send the filter's buffer to it's associated socket, erase if EOF */
+int filter_write( void *buffer, int size, esd_format_t format, int rate )
+{
+ int actual=0, total_data=0, data_size=0;
+ esd_player_t *filter=esd_filter_list, *erase=NULL;
+
+ /* if no filters, skip it */
+ if( !esd_filter_list ) {
+ return size;
+ }
+
+ /* translate into the first filter buffer */
+ data_size = esd_first_filter_func( filter->data_buffer,
+ filter->buffer_length,
+ filter->rate,
+ filter->format,
+ buffer,
+ size,
+ rate,
+ format );
+
+ /* hop through the list of filters */
+ while( filter ) {
+ /* fprintf( stderr, "filter_write: writing to new filter...\n" ); */
+
+ /* write the data data_buffer to the socket */
+ total_data = 0;
+ actual = 0;
+ erase = NULL;
+
+ /* All of the data from the previous read has to be written.
+ * There's no way I can think of to get around this w/o losing data.
+ * Maybe by using fread and fwrite, to buffer the stuff, but in the
+ * end, all the data still has to be written from here to the buffer.
+ */
+ while( total_data < data_size )
+ {
+ ESD_WRITE_BIN( filter->source_id, filter->data_buffer + total_data,
+ data_size - total_data, actual, "flt wr" );
+
+ if ( actual <= 0 ) {
+ erase = filter;
+ total_data = data_size;
+ } else {
+ total_data += actual;
+ }
+ /* fprintf( stderr, "filter_write: just wrote %d bytes\n", actual ); */
+ }
+
+ /* make sure the filter is still alive before we read from it */
+ if ( !erase ) {
+ actual = read_player( filter );
+ if (actual >= 0)
+ filter->actual_length -= actual;
+ else
+ erase = filter;
+ }
+
+ /* translate data to next filter whether current one is alive or not */
+ if ( filter->next ) {
+ /* translate to next filter */
+ data_size = filter->translate_func( filter->next->data_buffer,
+ filter->next->buffer_length,
+ filter->next->rate,
+ filter->next->format,
+ filter->data_buffer,
+ filter->buffer_length,
+ filter->rate,
+ filter->format );
+ } else {
+ /* translate to audio buffer */
+ data_size = filter->translate_func( buffer,
+ size,
+ rate,
+ format,
+ filter->data_buffer,
+ filter->buffer_length,
+ filter->rate,
+ filter->format );
+ }
+
+ /* next filter... */
+ filter = filter->next;
+
+ /* clean up any finished filters */
+ if ( erase != NULL ) {
+ erase_filter( erase );
+ erase = NULL;
+ }
+ }
+
+ return data_size;
+}
+
+/*******************************************************************/
+/* erase a filter from the filter list */
+void erase_filter( esd_player_t *filter )
+{
+ esd_player_t *previous = NULL;
+ esd_player_t *current = esd_filter_list;
+
+ /* iterate until we hit a NULL */
+ while ( current != NULL )
+ {
+ /* see if we hit the target filter */
+ if ( current == filter ) {
+ if( previous != NULL ){
+ /* we are deleting in the middle of the list */
+ previous->next = current->next;
+ } else {
+ /* we are deleting the head of the list */
+ esd_filter_list = current->next;
+ }
+
+ /* TODO: delete if needed */
+ free_player( filter );
+
+ return;
+ }
+
+ /* iterate through the list */
+ previous = current;
+ current = current->next;
+ }
+
+ /* hmm, we didn't find the desired filter, just get on with life */
+ ESDBG_TRACE( printf( "-%02d- filter not found\n", filter->source_id ); );
+ return;
+}
+