diff src/audacious/src_flow.c @ 4267:a41fb6bc632a

- src stuff traveled to src_flow.c - vis works again.
author Eugene Zagidullin <e.asphyx@gmail.com>
date Sun, 10 Feb 2008 07:19:45 +0300
parents 92642f860860
children 2a4954d14bfb
line wrap: on
line diff
--- a/src/audacious/src_flow.c	Sat Feb 09 01:05:36 2008 +0300
+++ b/src/audacious/src_flow.c	Sun Feb 10 07:19:45 2008 +0300
@@ -17,15 +17,117 @@
  *  Audacious or using our public API to be a derived work.
  */
 
+#define AUD_DEBUG
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
 #ifdef USE_SRC
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
 #include <samplerate.h>
 
-/* The devil is in the details */
+#include "main.h"
+#include "plugin.h"
+#include "input.h"
+#include "playback.h"
+#include "util.h"
+
+#include "src_flow.h"
+
+static SRC_STATE *src_state = NULL;
+static SRC_DATA src_data;
+
+static int overSamplingFs = 48000; /* hmmm... does everybody have 96kHz-enabled hardware? i'm in doubt --asphyx */
+static int inputFs = 0;
+static int input_nch = 0;
+static int converter_type = SRC_SINC_BEST_QUALITY;
+static int srcError = 0;
+
+static float *srcOut = NULL;
+static unsigned int lengthOfSrcOut = 0;
+
+void
+src_flow_free()
+{
+    AUDDBG("\n");
+    if(src_state != NULL) src_state = src_delete(src_state);
+    src_state = NULL;
+    if(srcOut != NULL) free(srcOut);
+    srcOut = NULL;
+    lengthOfSrcOut = 0;
+    inputFs = 0;
+    overSamplingFs = 0;
+    input_nch = 0;
+}
+
+gint
+src_flow_init(gint infreq, gint nch)
+{
+    AUDDBG("input_rate=%d, nch=%d\n", infreq, nch);
+    src_flow_free();
+
+    /* don't resample if sampling rates are the same --nenolod */
+    if (infreq == cfg.src_rate || !cfg.enable_src) return infreq;
+    
+    overSamplingFs = cfg.src_rate;
+    inputFs = infreq;
+    input_nch = nch;
+    converter_type = cfg.src_type;
+    
+    src_state = src_new(converter_type, nch, &srcError);
+    if (src_state != NULL) {
+        src_data.src_ratio = (float)overSamplingFs / (float)infreq;
+        return overSamplingFs;
+    } else {
+        AUDDBG("src_new(): %s\n\n", src_strerror(srcError));
+        return infreq;
+    }
+}
+
+void
+src_flow(FlowContext *context) {
+   
+    if(!cfg.enable_src) return;
+    
+    if(context->fmt != FMT_FLOAT) {
+        context->error = TRUE;
+        return;
+    }
+
+    if(src_state == NULL || context->srate != inputFs || context->channels != input_nch) {
+        AUDDBG("reinitializing src\n");
+        src_flow_init(context->srate, context->channels);
+    }
+
+    int lrLength = context->len;
+    int overLrLength = (int)floor(lrLength * (src_data.src_ratio + 1));
+    
+    if(lengthOfSrcOut < overLrLength || srcOut == NULL) {
+        AUDDBG("reallocating srcOut\n");
+        lengthOfSrcOut = overLrLength;
+        srcOut = smart_realloc(srcOut, &lengthOfSrcOut);
+    }
+    
+    src_data.data_in = (float*)context->data;
+    src_data.data_out = srcOut;
+    src_data.end_of_input = 0;
+    src_data.input_frames = lrLength / context->channels / sizeof(float);
+    src_data.output_frames = overLrLength / context->channels / sizeof(float);
+    if ((srcError = src_process(src_state, &src_data)) > 0) {
+        AUDDBG("src_process(): %s\n", src_strerror(srcError));
+        context->error = TRUE;
+        return;
+    } else {
+        context->data = (gpointer) srcOut;
+        context->len = src_data.output_frames_gen * context->channels * sizeof(float);
+        return;
+    }
+}
 
 #endif /* USE_SRC */