Mercurial > mplayer.hg
annotate libaf/af_pan.c @ 13394:455a5056801f
New generic 'portable anymap' video output driver. It supports portable
pixmaps and graymaps in both raw and ASCII mode. Besides PPM and PGM, it
can also output PGMYUV files which are PGM files with the U and V plane
appended to the bottom of the Y image (bottom left and bottom right). All
files can be written to the current directory, to a specified output directory
or to multiple subdirectories if the filesystem can't handle the amount of
files in one directory anymore.
Note: This driver is not yet activated and will not be compiled and linked
to libvo. A separate patch will take care of that. This is just for adding
the file to the repository.
author | ivo |
---|---|
date | Mon, 20 Sep 2004 00:54:57 +0000 |
parents | 8631b43c9d82 |
children | 14090f7300a8 |
rev | line source |
---|---|
8607 | 1 /*============================================================================= |
2 // | |
3 // This software has been released under the terms of the GNU Public | |
4 // license. See http://www.gnu.org/copyleft/gpl.html for details. | |
5 // | |
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au | |
7 // | |
8 //============================================================================= | |
9 */ | |
10 | |
11 /* */ | |
12 | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 | |
16 #include <unistd.h> | |
17 #include <inttypes.h> | |
18 #include <math.h> | |
19 #include <limits.h> | |
20 | |
21 #include "af.h" | |
22 | |
23 // Data for specific instances of this filter | |
24 typedef struct af_pan_s | |
25 { | |
26 float level[AF_NCH][AF_NCH]; // Gain level for each channel | |
27 }af_pan_t; | |
28 | |
29 // Initialization and runtime control | |
30 static int control(struct af_instance_s* af, int cmd, void* arg) | |
31 { | |
32 af_pan_t* s = af->setup; | |
33 | |
34 switch(cmd){ | |
35 case AF_CONTROL_REINIT: | |
36 // Sanity check | |
37 if(!arg) return AF_ERROR; | |
38 | |
39 af->data->rate = ((af_data_t*)arg)->rate; | |
40 af->data->format = AF_FORMAT_F | AF_FORMAT_NE; | |
41 af->data->bps = 4; | |
42 af->mul.n = af->data->nch; | |
43 af->mul.d = ((af_data_t*)arg)->nch; | |
44 | |
45 if((af->data->format != ((af_data_t*)arg)->format) || | |
46 (af->data->bps != ((af_data_t*)arg)->bps)){ | |
47 ((af_data_t*)arg)->format = af->data->format; | |
48 ((af_data_t*)arg)->bps = af->data->bps; | |
49 return AF_FALSE; | |
50 } | |
51 return control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &af->data->nch); | |
52 case AF_CONTROL_COMMAND_LINE:{ | |
53 int nch = 0; | |
54 int n = 0; | |
55 char* cp = NULL; | |
56 int j,k; | |
57 // Read number of outputs | |
58 sscanf((char*)arg,"%i%n", &nch,&n); | |
59 if(AF_OK != control(af,AF_CONTROL_PAN_NOUT | AF_CONTROL_SET, &nch)) | |
60 return AF_ERROR; | |
61 | |
62 // Read pan values | |
63 cp = &((char*)arg)[n]; | |
64 j = 0; k = 0; | |
65 while((*cp == ':') && (k < AF_NCH)){ | |
66 sscanf(cp, ":%f%n" , &s->level[k][j], &n); | |
67 s->level[k][j] = clamp(s->level[k][j],0.0,1.0); | |
68 af_msg(AF_MSG_VERBOSE,"[pan] Pan level from channel %i to" | |
69 " channel %i = %f\n",j,k,s->level[k][j]); | |
70 cp =&cp[n]; | |
71 j++; | |
72 if(j>=nch){ | |
73 j = 0; | |
74 k++; | |
75 } | |
76 } | |
77 return AF_OK; | |
78 } | |
79 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET:{ | |
80 int i; | |
81 int ch = ((af_control_ext_t*)arg)->ch; | |
82 float* level = ((af_control_ext_t*)arg)->arg; | |
83 for(i=0;i<AF_NCH;i++) | |
84 s->level[ch][i] = clamp(level[i],0.0,1.0); | |
85 return AF_OK; | |
86 } | |
87 case AF_CONTROL_PAN_LEVEL | AF_CONTROL_GET:{ | |
88 int i; | |
89 int ch = ((af_control_ext_t*)arg)->ch; | |
90 float* level = ((af_control_ext_t*)arg)->arg; | |
91 for(i=0;i<AF_NCH;i++) | |
92 level[i] = s->level[ch][i]; | |
93 return AF_OK; | |
94 } | |
95 case AF_CONTROL_PAN_NOUT | AF_CONTROL_SET: | |
96 // Reinit must be called after this function has been called | |
97 | |
98 // Sanity check | |
12008 | 99 if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){ |
8607 | 100 af_msg(AF_MSG_ERROR,"[pan] The number of output channels must be" |
101 " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]); | |
102 return AF_ERROR; | |
103 } | |
104 af->data->nch=((int*)arg)[0]; | |
105 return AF_OK; | |
106 case AF_CONTROL_PAN_NOUT | AF_CONTROL_GET: | |
107 *(int*)arg = af->data->nch; | |
108 return AF_OK; | |
109 } | |
110 return AF_UNKNOWN; | |
111 } | |
112 | |
113 // Deallocate memory | |
114 static void uninit(struct af_instance_s* af) | |
115 { | |
8674
93212da0032e
10l memory leak + bug fixes in ms to sample time conversion
anders
parents:
8607
diff
changeset
|
116 if(af->data->audio) |
93212da0032e
10l memory leak + bug fixes in ms to sample time conversion
anders
parents:
8607
diff
changeset
|
117 free(af->data->audio); |
8607 | 118 if(af->data) |
119 free(af->data); | |
120 if(af->setup) | |
121 free(af->setup); | |
122 } | |
123 | |
124 // Filter data through filter | |
125 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
126 { | |
127 af_data_t* c = data; // Current working data | |
128 af_data_t* l = af->data; // Local data | |
129 af_pan_t* s = af->setup; // Setup for this instance | |
130 float* in = c->audio; // Input audio data | |
131 float* out = NULL; // Output audio data | |
132 float* end = in+c->len/4; // End of loop | |
133 int nchi = c->nch; // Number of input channels | |
134 int ncho = l->nch; // Number of output channels | |
135 register int j,k; | |
136 | |
137 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
138 return NULL; | |
139 | |
140 out = l->audio; | |
141 // Execute panning | |
142 // FIXME: Too slow | |
143 while(in < end){ | |
144 for(j=0;j<ncho;j++){ | |
145 register float x = 0.0; | |
146 register float* tin = in; | |
147 for(k=0;k<nchi;k++) | |
148 x += tin[k] * s->level[j][k]; | |
149 out[j] = x; | |
150 } | |
151 out+= ncho; | |
152 in+= nchi; | |
153 } | |
154 | |
155 // Set output data | |
156 c->audio = l->audio; | |
157 c->len = (c->len*af->mul.n)/af->mul.d; | |
158 c->nch = l->nch; | |
159 | |
160 return c; | |
161 } | |
162 | |
163 // Allocate memory and set function pointers | |
164 static int open(af_instance_t* af){ | |
165 af->control=control; | |
166 af->uninit=uninit; | |
167 af->play=play; | |
168 af->mul.n=1; | |
169 af->mul.d=1; | |
170 af->data=calloc(1,sizeof(af_data_t)); | |
171 af->setup=calloc(1,sizeof(af_pan_t)); | |
172 if(af->data == NULL || af->setup == NULL) | |
173 return AF_ERROR; | |
174 // Set initial pan to pass-through. | |
175 return AF_OK; | |
176 } | |
177 | |
178 // Description of this filter | |
179 af_info_t af_info_pan = { | |
180 "Panning audio filter", | |
181 "pan", | |
182 "Anders", | |
183 "", | |
184 AF_FLAGS_NOT_REENTRANT, | |
185 open | |
186 }; |