[MPlayer-dev-eng] [PATCH 5/7] af_scale*: af_scalerate
Robert Juliano
juliano.1 at osu.edu
Mon Jun 11 06:53:14 CEST 2007
af_scalerate
This is the old behavior implemented as a filter. Enable
with -af scalerate.
This patch adds stream to af_instance_t and adds af_create
to af.h to allow one filter to swallow another. This is
needed by the next patch as well.
I found that the build system didn't catch making af_create
non-static. If you have problems, run:
# make -C libaf clean
# make
That's it for tonight. Robert.
Files:
libaf/Makefile
libaf/af.c
libaf/af.h
libaf/af_scalerate.c
libaf/control.h
Index: mplayer-HEAD/libaf/Makefile
===================================================================
--- mplayer-HEAD.orig/libaf/Makefile 2007-06-10 16:35:02.000000000 -0400
+++ mplayer-HEAD/libaf/Makefile 2007-06-10 17:05:32.000000000 -0400
@@ -16,6 +16,7 @@
af_karaoke.c \
af_pan.c \
af_resample.c \
+ af_scalerate.c \
af_scaletempo.c \
af_sinesuppress.c \
af_sub.c \
Index: mplayer-HEAD/libaf/af.c
===================================================================
--- mplayer-HEAD.orig/libaf/af.c 2007-06-10 16:52:58.000000000 -0400
+++ mplayer-HEAD/libaf/af.c 2007-06-10 17:04:45.000000000 -0400
@@ -33,6 +33,7 @@
extern af_info_t af_info_sinesuppress;
extern af_info_t af_info_karaoke;
extern af_info_t af_info_scaletempo;
+extern af_info_t af_info_scalerate;
static af_info_t* filter_list[]={
&af_info_dummy,
@@ -64,6 +65,7 @@
&af_info_sinesuppress,
&af_info_karaoke,
&af_info_scaletempo,
+ &af_info_scalerate,
NULL
};
@@ -103,7 +105,7 @@
/*/ Function for creating a new filter of type name. The name may
contain the commandline parameters for the filter */
-static af_instance_t* af_create(af_stream_t* s, char* name)
+af_instance_t* af_create(af_stream_t* s, char* name)
{
char* cmdline = name;
@@ -134,6 +136,8 @@
af_msg(AF_MSG_VERBOSE,"[libaf] Adding filter %s \n",name);
+ new->stream = s;
+
// Initialize the new filter
if(AF_OK == new->info->open(new) &&
AF_ERROR < new->control(new,AF_CONTROL_POST_CREATE,&s->cfg)){
Index: mplayer-HEAD/libaf/af.h
===================================================================
--- mplayer-HEAD.orig/libaf/af.h 2007-06-10 16:30:35.000000000 -0400
+++ mplayer-HEAD/libaf/af.h 2007-06-10 16:55:06.000000000 -0400
@@ -64,6 +64,7 @@
af_data_t* data; // configuration for outgoing data stream
struct af_instance_s* next;
struct af_instance_s* prev;
+ struct af_stream_s* stream; // allow filters to create, add, etc. other filters
double delay; // Delay caused by the filter [ms]
frac_t mul; /* length multiplier: how much does this instance change
the length of the buffer. */
@@ -173,6 +174,16 @@
void af_remove(af_stream_t* s, af_instance_t* af);
/**
+ * \brief create instance of filter
+ * \param name name of filter to create with command line paramters
+ * \return pointer to the new filter, NULL if failed
+ *
+ * Does not add filter to filter chain. Useful for swallowing other
+ * filters. Use af_add to add filter to filter chain.
+ */
+af_instance_t* af_create(af_stream_t* s, char* name);
+
+/**
* \brief find filter in chain by name
* \param name name of the filter to find
* \return first filter with right name or NULL if not found
Index: mplayer-HEAD/libaf/af_scalerate.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ mplayer-HEAD/libaf/af_scalerate.c 2007-06-10 16:55:06.000000000 -0400
@@ -0,0 +1,135 @@
+/*
+ * (cc) GPL 2007 MPlayer / Robert Juliano
+ *
+ * License: GPL http://creativecommons.org/licenses/GPL/2.0/
+ *
+ * scale rate (both time and tempo) (i.e. chipmunk effect)
+ *
+ * basic technique:
+ * pretend input rate is scaled rate and resample to input rate
+ *
+ * Changelog
+ * 2007-06-10 Initial release
+ *
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "af.h"
+
+#ifdef USE_LIBAVCODEC
+ #define RESAMPLER "lavcresample"
+#else
+ #define RESAMPLER "resample"
+#endif
+
+// Data for specific instances of this filter
+typedef struct af_scalerate_s
+{
+ af_instance_t* resampler;
+ float speed;
+ int base_rate;
+} af_scalerate_t;
+
+// Initialization and runtime control
+static int control(struct af_instance_s* af, int cmd, void* arg)
+{
+ af_scalerate_t* s = (af_scalerate_t*)af->setup;
+ af_instance_t* resampler = s->resampler;
+ switch(cmd){
+ case AF_CONTROL_REINIT:{
+ af_data_t* c = (af_data_t*)arg;
+ int rv;
+
+ s->base_rate = c->rate;
+ c->rate = s->base_rate * s->speed;
+ af_msg(AF_MSG_DEBUG0,"[scalerate] Was reinitialized: %.3f speed %i Hz (%i base)\n", s->speed, c->rate, s->base_rate);
+
+ resampler->control(resampler, AF_CONTROL_RESAMPLE_RATE, &(s->base_rate));
+ rv = resampler->control(resampler, AF_CONTROL_REINIT, c);
+ if (rv == AF_DETACH) {
+ memcpy(af->data, c, sizeof(af_data_t));
+ af->mul.n = af->mul.d = 1;
+ af->delay = 0;
+ return AF_OK;
+ }
+ if (rv == AF_ERROR) return rv;
+
+ memcpy(af->data, resampler->data, sizeof(af_data_t));
+ af->data->rate = c->rate = s->base_rate;
+ af->mul.n = resampler->mul.n;
+ af->mul.d = resampler->mul.d;
+ af->delay = resampler->delay;
+
+ return af_test_output(af,(af_data_t*)arg);
+ }
+ case AF_CONTROL_SCALERATE_AMOUNT | AF_CONTROL_SET:
+ case AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET:{
+ s->speed = *(float*)arg;
+ return AF_OK;
+ }
+ case AF_CONTROL_SCALERATE_AMOUNT | AF_CONTROL_GET:{
+ *(float*)arg = s->speed;
+ return AF_OK;
+ }
+ }
+ return AF_UNKNOWN;
+}
+
+// Deallocate memory
+static void uninit(struct af_instance_s* af)
+{
+ af_scalerate_t* s = (af_scalerate_t*)af->setup;
+ if(af->data)
+ free(af->data);
+ if(s->resampler) {
+ s->resampler->uninit(s->resampler);
+ free(s->resampler);
+ }
+ if(af->setup)
+ free(af->setup);
+}
+
+// Filter data through filter
+static af_data_t* play(struct af_instance_s* af, af_data_t* data)
+{
+ af_scalerate_t* s = (af_scalerate_t*)af->setup;
+ if (s->speed == 1.0) return data;
+ return s->resampler->play(s->resampler, data);
+}
+
+// Allocate memory and set function pointers
+static int af_open(af_instance_t* af){
+ af_scalerate_t* s;
+
+ af->control=control;
+ af->uninit=uninit;
+ af->play=play;
+ af->mul.d=1;
+ af->mul.n=1;
+ af->data=malloc(sizeof(af_data_t));
+ af->setup=malloc(sizeof(af_scalerate_t));
+ if(af->data == NULL || af->setup == NULL)
+ return AF_ERROR;
+
+ s = (af_scalerate_t*)af->setup;
+ s->speed = 1.0;
+ s->base_rate = 0;
+ s->resampler = af_create(af->stream, RESAMPLER);
+ if (!s->resampler)
+ return AF_ERROR;
+
+ return AF_OK;
+}
+
+// Description of this filter
+af_info_t af_info_scalerate = {
+ "Scales audio rate (both pitch and tempo) (i.e. chipmunk effect)",
+ "scalerate",
+ "Robert Juliano",
+ "",
+ AF_FLAGS_NOT_REENTRANT,
+ af_open
+};
Index: mplayer-HEAD/libaf/control.h
===================================================================
--- mplayer-HEAD.orig/libaf/control.h 2007-06-10 16:35:02.000000000 -0400
+++ mplayer-HEAD/libaf/control.h 2007-06-10 17:04:45.000000000 -0400
@@ -232,7 +232,8 @@
// Generic: respond to change in playback_speed
#define AF_CONTROL_PLAYBACK_SPEED 0x00002500 | AF_CONTROL_FILTER_SPECIFIC
-// ScaleTempo
+// Scale Tempo, Rate
#define AF_CONTROL_SCALETEMPO_AMOUNT 0x00002600 | AF_CONTROL_FILTER_SPECIFIC
+#define AF_CONTROL_SCALERATE_AMOUNT 0x00002700 | AF_CONTROL_FILTER_SPECIFIC
#endif /*__af_control_h */
More information about the MPlayer-dev-eng
mailing list