annotate libaf/af_center.c @ 22697:2fe9bd97a7f6

Fix configure -march detection for athlon-xp The configure script uses SSE support to distinguish between athlon and athlon-xp, but SSE support was tested _after_ deciding the basic CPU type. Thus athlon-xp was always misdetected as athlon. Fix this by moving the CPU extensions check before the CPU type check. Patch from Andrew Savchenko, bircoph list ru.
author uau
date Sun, 18 Mar 2007 13:38:55 +0000
parents ab617c2e24d3
children fd6f824ef894
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
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 };