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