annotate libaf/af_center.c @ 25661:293aeec83153

Replace the persistent CODECS_FLAG_SELECTED by a local "stringset" with an almost-trivial implementation. This allows making the builtin codec structs const, and it also makes clearer that this "selected" status is not used outside the init functions.
author reimar
date Sat, 12 Jan 2008 14:05:46 +0000
parents b2402b4f0afa
children 72d0b1444141
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 14749
diff changeset
93 static int af_open(af_instance_t* af){
14749
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;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22746
diff changeset
98 af->mul=1;
14749
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
99 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
100 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
101 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
102 return AF_ERROR;
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
103 // Set default values
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
104 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
105 return AF_OK;
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
106 }
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 // Description of this filter
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
109 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
110 "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
111 "center",
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
112 "Alex Beregszaszi",
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
113 "",
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
114 AF_FLAGS_NOT_REENTRANT,
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 14749
diff changeset
115 af_open
14749
ab617c2e24d3 filter for adding a center channel, adding a high pass filter would be nice
alex
parents:
diff changeset
116 };