Mercurial > mplayer.hg
annotate libaf/af_center.c @ 16529:d320720fe74e
feel free to fix this as you see fit...
i want to be sure people will not take interest in this option and
look it up and try using it. just enough for those already know it
and still stubborn enough to use it.
author | ods15 |
---|---|
date | Mon, 19 Sep 2005 19:36:10 +0000 (2005-09-19) |
parents | ab617c2e24d3 |
children | fd6f824ef894 |
rev | line source |
---|---|
14749
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
1 /* |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
2 (C) Alex Beregszaszi |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
3 License: GPL |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
4 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
5 This filter adds a center channel to the audio stream by |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
6 averaging the left and right channel. |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
7 There are two runtime controls one for setting which channel to |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
8 insert the center-audio into called AF_CONTROL_SUB_CH. |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
9 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
10 FIXME: implement a high-pass filter for better results. |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
11 */ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
12 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
13 #include <stdio.h> |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
14 #include <stdlib.h> |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
15 #include <string.h> |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
16 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
17 #include "af.h" |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
18 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
19 // Data for specific instances of this filter |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
20 typedef struct af_center_s |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
21 { |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
22 int ch; // Channel number which to insert the filtered data |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
23 }af_center_t; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
24 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
25 // Initialization and runtime control |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
26 static int control(struct af_instance_s* af, int cmd, void* arg) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
27 { |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
28 af_center_t* s = af->setup; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
29 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
30 switch(cmd){ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
31 case AF_CONTROL_REINIT:{ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
32 // Sanity check |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
33 if(!arg) return AF_ERROR; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
34 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
35 af->data->rate = ((af_data_t*)arg)->rate; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
36 af->data->nch = max(s->ch+1,((af_data_t*)arg)->nch); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
37 af->data->format = AF_FORMAT_FLOAT_NE; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
38 af->data->bps = 4; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
39 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
40 return af_test_output(af,(af_data_t*)arg); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
41 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
42 case AF_CONTROL_COMMAND_LINE:{ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
43 int ch=1; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
44 sscanf(arg,"%i", &ch); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
45 return control(af,AF_CONTROL_CENTER_CH | AF_CONTROL_SET, &ch); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
46 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
47 case AF_CONTROL_CENTER_CH | AF_CONTROL_SET: // Requires reinit |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
48 // Sanity check |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
49 if((*(int*)arg >= AF_NCH) || (*(int*)arg < 0)){ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
50 af_msg(AF_MSG_ERROR,"[sub] Center channel number must be between " |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
51 " 0 and %i current value is %i\n", AF_NCH-1, *(int*)arg); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
52 return AF_ERROR; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
53 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
54 s->ch = *(int*)arg; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
55 return AF_OK; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
56 case AF_CONTROL_CENTER_CH | AF_CONTROL_GET: |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
57 *(int*)arg = s->ch; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
58 return AF_OK; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
59 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
60 return AF_UNKNOWN; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
61 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
62 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
63 // Deallocate memory |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
64 static void uninit(struct af_instance_s* af) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
65 { |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
66 if(af->data) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
67 free(af->data); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
68 if(af->setup) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
69 free(af->setup); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
70 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
71 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
72 // Filter data through filter |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
73 static af_data_t* play(struct af_instance_s* af, af_data_t* data) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
74 { |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
75 af_data_t* c = data; // Current working data |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
76 af_center_t* s = af->setup; // Setup for this instance |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
77 float* a = c->audio; // Audio data |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
78 int len = c->len/4; // Number of samples in current audio block |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
79 int nch = c->nch; // Number of channels |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
80 int ch = s->ch; // Channel in which to insert the center audio |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
81 register int i; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
82 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
83 // Run filter |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
84 for(i=0;i<len;i+=nch){ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
85 // Average left and right |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
86 a[i+ch] = (a[i]/2) + (a[i+1]/2); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
87 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
88 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
89 return c; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
90 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
91 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
92 // Allocate memory and set function pointers |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
93 static int open(af_instance_t* af){ |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
94 af_center_t* s; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
95 af->control=control; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
96 af->uninit=uninit; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
97 af->play=play; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
98 af->mul.n=1; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
99 af->mul.d=1; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
100 af->data=calloc(1,sizeof(af_data_t)); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
101 af->setup=s=calloc(1,sizeof(af_center_t)); |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
102 if(af->data == NULL || af->setup == NULL) |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
103 return AF_ERROR; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
104 // Set default values |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
105 s->ch = 1; // Channel nr 2 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
106 return AF_OK; |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
107 } |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
108 |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
109 // Description of this filter |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
110 af_info_t af_info_center = { |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
111 "Audio filter for adding a center channel", |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
112 "center", |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
113 "Alex Beregszaszi", |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
114 "", |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
115 AF_FLAGS_NOT_REENTRANT, |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
116 open |
ab617c2e24d3
filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff
changeset
|
117 }; |