annotate libaf/af.c @ 19992:be7b8a83649c

removed ivtv driver dependancy in favor of native V4L2 MPEG API (requires Linux 2.6.18 and above)
author ben
date Wed, 27 Sep 2006 20:26:38 +0000
parents 4e43ba6844d8
children 1e78e35b6c7b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
1 #include <stdio.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
2 #include <stdlib.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
3 #include <string.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
4
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
5 #ifdef HAVE_MALLOC_H
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
6 #include <malloc.h>
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
7 #endif
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
8
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
9 #include "af.h"
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
10
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
11 // Static list of filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
12 extern af_info_t af_info_dummy;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
13 extern af_info_t af_info_delay;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
14 extern af_info_t af_info_channels;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
15 extern af_info_t af_info_format;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
16 extern af_info_t af_info_resample;
7974
db1f16543379 enable volume filter and fix nonsense default volume (still not usable
rfelker
parents: 7745
diff changeset
17 extern af_info_t af_info_volume;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents: 7998
diff changeset
18 extern af_info_t af_info_equalizer;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
19 extern af_info_t af_info_gate;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
20 extern af_info_t af_info_comp;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
21 extern af_info_t af_info_pan;
8678
db0810dcab33 Port of pl_surround.c to af-layer.
ranma
parents: 8607
diff changeset
22 extern af_info_t af_info_surround;
8832
a1578b329cc0 Adding sub-woofer filter, use this filter to add a sub channel to the audio stream
anders
parents: 8711
diff changeset
23 extern af_info_t af_info_sub;
10892
2167ac4c1d72 Adding filter for exporting audio data to visual effect applications
anders
parents: 8969
diff changeset
24 extern af_info_t af_info_export;
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents: 13269
diff changeset
25 extern af_info_t af_info_volnorm;
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents: 13269
diff changeset
26 extern af_info_t af_info_extrastereo;
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents: 13566
diff changeset
27 extern af_info_t af_info_lavcresample;
13721
0c2e5c9476df sine sweep generator
michael
parents: 13713
diff changeset
28 extern af_info_t af_info_sweep;
13996
be8f4abbe960 head related transfer function
henry
parents: 13721
diff changeset
29 extern af_info_t af_info_hrtf;
14217
5b5ebf93ec16 Adds support for LADSPA (Linux Audio Developer's Simple Plugin API) plugins.
ivo
parents: 13996
diff changeset
30 extern af_info_t af_info_ladspa;
14750
108423cf7b3f filter for adding a center channel, adding a high pass filter would be nice
alex
parents: 14569
diff changeset
31 extern af_info_t af_info_center;
18611
1c2f694d5232 Rename sinesupress to sinesuppress, including af_sinesupress.c file rename.
corey
parents: 18470
diff changeset
32 extern af_info_t af_info_sinesuppress;
18470
0ea3c732d72d New karaoke af
reynaldo
parents: 18237
diff changeset
33 extern af_info_t af_info_karaoke;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
34
10908
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
35 static af_info_t* filter_list[]={
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
36 &af_info_dummy,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
37 &af_info_delay,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
38 &af_info_channels,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
39 &af_info_format,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
40 &af_info_resample,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
41 &af_info_volume,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
42 &af_info_equalizer,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
43 &af_info_gate,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
44 &af_info_comp,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
45 &af_info_pan,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
46 &af_info_surround,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
47 &af_info_sub,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
48 #ifdef HAVE_SYS_MMAN_H
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
49 &af_info_export,
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
50 #endif
13550
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents: 13269
diff changeset
51 &af_info_volnorm,
81e62cbe57d9 reimplementation of the pl_extrastereo and pl_volnorm plugins
alex
parents: 13269
diff changeset
52 &af_info_extrastereo,
13713
28bb0f15ac91 libavcodec resampling ...
michael
parents: 13566
diff changeset
53 #ifdef USE_LIBAVCODEC
28bb0f15ac91 libavcodec resampling ...
michael
parents: 13566
diff changeset
54 &af_info_lavcresample,
28bb0f15ac91 libavcodec resampling ...
michael
parents: 13566
diff changeset
55 #endif
13721
0c2e5c9476df sine sweep generator
michael
parents: 13713
diff changeset
56 &af_info_sweep,
13996
be8f4abbe960 head related transfer function
henry
parents: 13721
diff changeset
57 &af_info_hrtf,
14217
5b5ebf93ec16 Adds support for LADSPA (Linux Audio Developer's Simple Plugin API) plugins.
ivo
parents: 13996
diff changeset
58 #ifdef HAVE_LADSPA
5b5ebf93ec16 Adds support for LADSPA (Linux Audio Developer's Simple Plugin API) plugins.
ivo
parents: 13996
diff changeset
59 &af_info_ladspa,
5b5ebf93ec16 Adds support for LADSPA (Linux Audio Developer's Simple Plugin API) plugins.
ivo
parents: 13996
diff changeset
60 #endif
14750
108423cf7b3f filter for adding a center channel, adding a high pass filter would be nice
alex
parents: 14569
diff changeset
61 &af_info_center,
18611
1c2f694d5232 Rename sinesupress to sinesuppress, including af_sinesupress.c file rename.
corey
parents: 18470
diff changeset
62 &af_info_sinesuppress,
18470
0ea3c732d72d New karaoke af
reynaldo
parents: 18237
diff changeset
63 &af_info_karaoke,
10908
dcca52fe32bd disable af export for systems without mmap
faust3
parents: 10892
diff changeset
64 NULL
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
65 };
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
66
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
67 // Message printing
e8832e66babd New features:
anders
parents: 8073
diff changeset
68 af_msg_cfg_t af_msg_cfg={0,NULL,NULL};
e8832e66babd New features:
anders
parents: 8073
diff changeset
69
e8832e66babd New features:
anders
parents: 8073
diff changeset
70 // CPU speed
e8832e66babd New features:
anders
parents: 8073
diff changeset
71 int* af_cpu_speed = NULL;
e8832e66babd New features:
anders
parents: 8073
diff changeset
72
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
73 /* Find a filter in the static list of filters using it's name. This
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
74 function is used internally */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 18611
diff changeset
75 static af_info_t* af_find(char*name)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
76 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
77 int i=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
78 while(filter_list[i]){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
79 if(!strcmp(filter_list[i]->name,name))
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
80 return filter_list[i];
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
81 i++;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
82 }
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
83 af_msg(AF_MSG_ERROR,"Couldn't find audio filter '%s'\n",name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
84 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
85 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
86
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
87 /* Find filter in the dynamic filter list using it's name This
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
88 function is used for finding already initialized filters */
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
89 af_instance_t* af_get(af_stream_t* s, char* name)
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
90 {
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
91 af_instance_t* af=s->first;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
92 // Find the filter
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
93 while(af != NULL){
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
94 if(!strcmp(af->info->name,name))
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
95 return af;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
96 af=af->next;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
97 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
98 return NULL;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
99 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
100
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
101 /*/ Function for creating a new filter of type name. The name may
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
102 contain the commandline parameters for the filter */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 18611
diff changeset
103 static af_instance_t* af_create(af_stream_t* s, char* name)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
104 {
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
105 char* cmdline = name;
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7993
diff changeset
106
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
107 // Allocate space for the new filter and reset all pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
108 af_instance_t* new=malloc(sizeof(af_instance_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
109 if(!new){
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
110 af_msg(AF_MSG_ERROR,"[libaf] Could not allocate memory\n");
17780
16c347e53841 fix memory leak when filter with given name does not exist.
reimar
parents: 16815
diff changeset
111 goto err_out;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
112 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
113 memset(new,0,sizeof(af_instance_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
114
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
115 // Check for commandline parameters
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
116 strsep(&cmdline, "=");
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
117
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
118 // Find filter from name
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
119 if(NULL == (new->info=af_find(name)))
17780
16c347e53841 fix memory leak when filter with given name does not exist.
reimar
parents: 16815
diff changeset
120 goto err_out;
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
121
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
122 /* Make sure that the filter is not already in the list if it is
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
123 non-reentrant */
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
124 if(new->info->flags & AF_FLAGS_NOT_REENTRANT){
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
125 if(af_get(s,name)){
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
126 af_msg(AF_MSG_ERROR,"[libaf] There can only be one instance of"
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
127 " the filter '%s' in each stream\n",name);
17780
16c347e53841 fix memory leak when filter with given name does not exist.
reimar
parents: 16815
diff changeset
128 goto err_out;
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
129 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
130 }
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
131
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
132 af_msg(AF_MSG_VERBOSE,"[libaf] Adding filter %s \n",name);
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
133
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
134 // Initialize the new filter
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
135 if(AF_OK == new->info->open(new) &&
7993
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
136 AF_ERROR < new->control(new,AF_CONTROL_POST_CREATE,&s->cfg)){
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
137 if(cmdline){
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
138 if(AF_ERROR<new->control(new,AF_CONTROL_COMMAND_LINE,cmdline))
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
139 return new;
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
140 }
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
141 else
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
142 return new;
ea0680d87f3f Changing the behavour of the commandline parameter -af to conform with -vop. Adding new commanline parameter -af-adv for advanced af options. Adding changes to volume control to support commandline parameters.
anders
parents: 7974
diff changeset
143 }
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
144
17780
16c347e53841 fix memory leak when filter with given name does not exist.
reimar
parents: 16815
diff changeset
145 err_out:
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
146 free(new);
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
147 af_msg(AF_MSG_ERROR,"[libaf] Couldn't create or open audio filter '%s'\n",
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
148 name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
149 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
150 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
151
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
152 /* Create and insert a new filter of type name before the filter in the
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
153 argument. This function can be called during runtime, the return
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
154 value is the new filter */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 18611
diff changeset
155 static af_instance_t* af_prepend(af_stream_t* s, af_instance_t* af, char* name)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
156 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
157 // Create the new filter and make sure it is OK
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
158 af_instance_t* new=af_create(s,name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
159 if(!new)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
160 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
161 // Update pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
162 new->next=af;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
163 if(af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
164 new->prev=af->prev;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
165 af->prev=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
166 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
167 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
168 s->last=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
169 if(new->prev)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
170 new->prev->next=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
171 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
172 s->first=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
173 return new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
174 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
175
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
176 /* Create and insert a new filter of type name after the filter in the
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
177 argument. This function can be called during runtime, the return
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
178 value is the new filter */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 18611
diff changeset
179 static af_instance_t* af_append(af_stream_t* s, af_instance_t* af, char* name)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
180 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
181 // Create the new filter and make sure it is OK
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
182 af_instance_t* new=af_create(s,name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
183 if(!new)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
184 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
185 // Update pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
186 new->prev=af;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
187 if(af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
188 new->next=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
189 af->next=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
190 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
191 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
192 s->first=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
193 if(new->next)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
194 new->next->prev=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
195 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
196 s->last=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
197 return new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
198 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
199
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
200 // Uninit and remove the filter "af"
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
201 void af_remove(af_stream_t* s, af_instance_t* af)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
202 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
203 if(!af) return;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
204
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
205 // Print friendly message
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
206 af_msg(AF_MSG_VERBOSE,"[libaf] Removing filter %s \n",af->info->name);
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
207
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
208 // Notify filter before changing anything
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
209 af->control(af,AF_CONTROL_PRE_DESTROY,0);
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
210
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
211 // Detach pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
212 if(af->prev)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
213 af->prev->next=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
214 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
215 s->first=af->next;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
216 if(af->next)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
217 af->next->prev=af->prev;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
218 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
219 s->last=af->prev;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
220
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
221 // Uninitialize af and free memory
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
222 af->uninit(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
223 free(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
224 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
225
7649
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
226 /* Reinitializes all filters downstream from the filter given in the
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
227 argument the return value is AF_OK if success and AF_ERROR if
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
228 failure */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 18611
diff changeset
229 static int af_reinit(af_stream_t* s, af_instance_t* af)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
230 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
231 do{
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
232 af_data_t in; // Format of the input to current filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
233 int rv=0; // Return value
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
234
15191
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
235 // Check if there are any filters left in the list
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
236 if(NULL == af){
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
237 if(!(af=af_append(s,s->first,"dummy")))
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
238 return AF_UNKNOWN;
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
239 else
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
240 return AF_ERROR;
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
241 }
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
242
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
243 // Check if this is the first filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
244 if(!af->prev)
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
245 memcpy(&in,&(s->input),sizeof(af_data_t));
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
246 else
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
247 memcpy(&in,af->prev->data,sizeof(af_data_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
248 // Reset just in case...
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
249 in.audio=NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
250 in.len=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
251
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
252 rv = af->control(af,AF_CONTROL_REINIT,&in);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
253 switch(rv){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
254 case AF_OK:
15191
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
255 af = af->next;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
256 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
257 case AF_FALSE:{ // Configuration filter is needed
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
258 // Do auto insertion only if force is not specified
e8832e66babd New features:
anders
parents: 8073
diff changeset
259 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
e8832e66babd New features:
anders
parents: 8073
diff changeset
260 af_instance_t* new = NULL;
e8832e66babd New features:
anders
parents: 8073
diff changeset
261 // Insert channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
262 if((af->prev?af->prev->data->nch:s->input.nch) != in.nch){
e8832e66babd New features:
anders
parents: 8073
diff changeset
263 // Create channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
264 if(NULL == (new = af_prepend(s,af,"channels")))
e8832e66babd New features:
anders
parents: 8073
diff changeset
265 return AF_ERROR;
e8832e66babd New features:
anders
parents: 8073
diff changeset
266 // Set number of output channels
e8832e66babd New features:
anders
parents: 8073
diff changeset
267 if(AF_OK != (rv = new->control(new,AF_CONTROL_CHANNELS,&in.nch)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
268 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
269 // Initialize channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
270 if(!new->prev)
e8832e66babd New features:
anders
parents: 8073
diff changeset
271 memcpy(&in,&(s->input),sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
272 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
273 memcpy(&in,new->prev->data,sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
274 if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
275 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
276 }
e8832e66babd New features:
anders
parents: 8073
diff changeset
277 // Insert format filter
14818
663c1ea5f595 finally remove the refences to bps outside libaf. also simplification of some messages and removed redundants
alex
parents: 14750
diff changeset
278 if((af->prev?af->prev->data->format:s->input.format) != in.format){
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
279 // Create format filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
280 if(NULL == (new = af_prepend(s,af,"format")))
e8832e66babd New features:
anders
parents: 8073
diff changeset
281 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
282 // Set output bits per sample
14335
8380694ba14f af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents: 14326
diff changeset
283 in.format |= af_bits2fmt(in.bps*8);
8380694ba14f af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents: 14326
diff changeset
284 if(AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT_FMT,&in.format)))
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
285 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
286 // Initialize format filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
287 if(!new->prev)
e8832e66babd New features:
anders
parents: 8073
diff changeset
288 memcpy(&in,&(s->input),sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
289 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
290 memcpy(&in,new->prev->data,sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
291 if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
292 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
293 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
294 if(!new){ // Should _never_ happen
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
295 af_msg(AF_MSG_ERROR,"[libaf] Unable to correct audio format. "
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
296 "This error should never uccur, please send bugreport.\n");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
297 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
298 }
15191
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
299 af=new->next;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
300 }
16072
456246827b88 Avoid hang with -af-adv force=3
reimar
parents: 15811
diff changeset
301 else {
456246827b88 Avoid hang with -af-adv force=3
reimar
parents: 15811
diff changeset
302 af_msg(AF_MSG_ERROR, "[libaf] Automatic filter insertion disabled "
456246827b88 Avoid hang with -af-adv force=3
reimar
parents: 15811
diff changeset
303 "but formats do not match. Giving up.\n");
456246827b88 Avoid hang with -af-adv force=3
reimar
parents: 15811
diff changeset
304 return AF_ERROR;
456246827b88 Avoid hang with -af-adv force=3
reimar
parents: 15811
diff changeset
305 }
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
306 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
307 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
308 case AF_DETACH:{ // Filter is redundant and wants to be unloaded
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
309 // Do auto remove only if force is not specified
e8832e66babd New features:
anders
parents: 8073
diff changeset
310 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
e8832e66babd New features:
anders
parents: 8073
diff changeset
311 af_instance_t* aft=af->prev;
e8832e66babd New features:
anders
parents: 8073
diff changeset
312 af_remove(s,af);
e8832e66babd New features:
anders
parents: 8073
diff changeset
313 if(aft)
15191
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
314 af=aft->next;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
315 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
316 af=s->first; // Restart configuration
e8832e66babd New features:
anders
parents: 8073
diff changeset
317 }
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
318 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
319 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
320 default:
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
321 af_msg(AF_MSG_ERROR,"[libaf] Reinitialization did not work, audio"
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
322 " filter '%s' returned error code %i\n",af->info->name,rv);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
323 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
324 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
325 }while(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
326 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
327 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
328
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
329 // Uninit and remove all filters
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
330 void af_uninit(af_stream_t* s)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
331 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
332 while(s->first)
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
333 af_remove(s,s->first);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
334 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
335
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
336 /* Initialize the stream "s". This function creates a new filter list
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
337 if necessary according to the values set in input and output. Input
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
338 and output should contain the format of the current movie and the
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
339 formate of the preferred output respectively. The function is
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
340 reentrant i.e. if called with an already initialized stream the
15811
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
341 stream will be reinitialized.
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
342 If one of the prefered output parameters is 0 the one that needs
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
343 no conversion is used (i.e. the output format in the last filter).
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
344 The return value is 0 if success and -1 if failure */
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
345 int af_init(af_stream_t* s)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
346 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
347 int i=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
348
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
349 // Sanity check
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
350 if(!s) return -1;
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
351
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
352 // Precaution in case caller is misbehaving
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
353 s->input.audio = s->output.audio = NULL;
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
354 s->input.len = s->output.len = 0;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
355
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
356 // Figure out how fast the machine is
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
357 if(AF_INIT_AUTO == (AF_INIT_TYPE_MASK & s->cfg.force))
e8832e66babd New features:
anders
parents: 8073
diff changeset
358 s->cfg.force = (s->cfg.force & ~AF_INIT_TYPE_MASK) | AF_INIT_TYPE;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
359
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
360 // Check if this is the first call
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
361 if(!s->first){
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
362 // Add all filters in the list (if there are any)
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
363 if(!s->cfg.list){ // To make automatic format conversion work
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
364 if(!af_append(s,s->first,"dummy"))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
365 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
366 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
367 else{
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
368 while(s->cfg.list[i]){
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
369 if(!af_append(s,s->last,s->cfg.list[i++]))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
370 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
371 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
372 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
373 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
374
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
375 // Init filters
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
376 if(AF_OK != af_reinit(s,s->first))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
377 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
378
15312
0313ef8b0730 Prevent segfault when filter chain is empty (e.g. because all
reimar
parents: 15191
diff changeset
379 // make sure the chain is not empty and valid (e.g. because of AF_DETACH)
0313ef8b0730 Prevent segfault when filter chain is empty (e.g. because all
reimar
parents: 15191
diff changeset
380 if (!s->first)
0313ef8b0730 Prevent segfault when filter chain is empty (e.g. because all
reimar
parents: 15191
diff changeset
381 if (!af_append(s,s->first,"dummy") || AF_OK != af_reinit(s,s->first))
0313ef8b0730 Prevent segfault when filter chain is empty (e.g. because all
reimar
parents: 15191
diff changeset
382 return -1;
0313ef8b0730 Prevent segfault when filter chain is empty (e.g. because all
reimar
parents: 15191
diff changeset
383
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
384 // Check output format
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
385 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
386 af_instance_t* af = NULL; // New filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
387 // Check output frequency if not OK fix with resample
15811
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
388 if(s->output.rate && s->last->data->rate!=s->output.rate){
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
389 // try to find a filter that can change samplrate
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
390 af = af_control_any_rev(s, AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
391 &(s->output.rate));
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
392 if (!af) {
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
393 char *resampler = "resample";
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
394 #ifdef USE_LIBAVCODEC
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
395 if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW)
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
396 resampler = "lavcresample";
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
397 #endif
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
398 if((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW){
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
399 if(!strcmp(s->first->info->name,"format"))
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
400 af = af_append(s,s->first,resampler);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
401 else
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
402 af = af_prepend(s,s->first,resampler);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
403 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
404 else{
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
405 if(!strcmp(s->last->info->name,"format"))
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
406 af = af_prepend(s,s->last,resampler);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
407 else
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
408 af = af_append(s,s->last,resampler);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
409 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
410 // Init the new filter
15191
7eab9c86ae19 change list traversal so the loop begins at the first filter after removing
henry
parents: 14818
diff changeset
411 if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
412 &(s->output.rate))))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
413 return -1;
11859
b8bee4f4b8bb if the user wants fast, use fast code! otherwise the user has to put
rfelker
parents: 10908
diff changeset
414 // Use lin int if the user wants fast
b8bee4f4b8bb if the user wants fast, use fast code! otherwise the user has to put
rfelker
parents: 10908
diff changeset
415 if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_FAST) {
b8bee4f4b8bb if the user wants fast, use fast code! otherwise the user has to put
rfelker
parents: 10908
diff changeset
416 char args[32];
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
417 sprintf(args, "%d", s->output.rate);
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
418 #ifdef USE_LIBAVCODEC
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
419 if (strcmp(resampler, "lavcresample") == 0)
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
420 strcat(args, ":1");
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
421 else
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
422 #endif
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
423 strcat(args, ":0:0");
11859
b8bee4f4b8bb if the user wants fast, use fast code! otherwise the user has to put
rfelker
parents: 10908
diff changeset
424 af->control(af, AF_CONTROL_COMMAND_LINE, args);
b8bee4f4b8bb if the user wants fast, use fast code! otherwise the user has to put
rfelker
parents: 10908
diff changeset
425 }
14326
9261d7dcf5e7 Use lavcresample only when libavcodec is compiled in.
reimar
parents: 14292
diff changeset
426 }
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
427 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
428 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
429 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
430
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
431 // Check number of output channels fix if not OK
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
432 // If needed always inserted last -> easy to screw up other filters
15811
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
433 if(s->output.nch && s->last->data->nch!=s->output.nch){
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
434 if(!strcmp(s->last->info->name,"format"))
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
435 af = af_prepend(s,s->last,"channels");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
436 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
437 af = af_append(s,s->last,"channels");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
438 // Init the new filter
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
439 if(!af || (AF_OK != af->control(af,AF_CONTROL_CHANNELS,&(s->output.nch))))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
440 return -1;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
441 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
442 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
443 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
444
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
445 // Check output format fix if not OK
15811
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
446 if(s->output.format && s->last->data->format != s->output.format){
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
447 if(strcmp(s->last->info->name,"format"))
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
448 af = af_append(s,s->last,"format");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
449 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
450 af = s->last;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
451 // Init the new filter
14335
8380694ba14f af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents: 14326
diff changeset
452 s->output.format |= af_bits2fmt(s->output.bps*8);
8380694ba14f af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents: 14326
diff changeset
453 if(!af || (AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT,&(s->output.format))))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
454 return -1;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
455 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
456 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
457 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
458
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
459 // Re init again just in case
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
460 if(AF_OK != af_reinit(s,s->first))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
461 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
462
15811
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
463 if (!s->output.format) s->output.format = s->last->data->format;
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
464 if (!s->output.nch) s->output.nch = s->last->data->nch;
9b4bbb6098f6 make -srate work again, unify audio filter init and preinit.
reimar
parents: 15791
diff changeset
465 if (!s->output.rate) s->output.rate = s->last->data->rate;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
466 if((s->last->data->format != s->output.format) ||
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
467 (s->last->data->nch != s->output.nch) ||
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
468 (s->last->data->rate != s->output.rate)) {
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
469 // Something is stuffed audio out will not work
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
470 af_msg(AF_MSG_ERROR,"[libaf] Unable to setup filter system can not"
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
471 " meet sound-card demands, please send bugreport. \n");
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
472 af_uninit(s);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
473 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
474 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
475 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
476 return 0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
477 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
478
7649
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
479 /* Add filter during execution. This function adds the filter "name"
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
480 to the stream s. The filter will be inserted somewhere nice in the
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
481 list of filters. The return value is a pointer to the new filter,
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
482 If the filter couldn't be added the return value is NULL. */
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
483 af_instance_t* af_add(af_stream_t* s, char* name){
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
484 af_instance_t* new;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
485 // Sanity check
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
486 if(!s || !s->first || !name)
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
487 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
488 // Insert the filter somwhere nice
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
489 if(!strcmp(s->first->info->name,"format"))
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
490 new = af_append(s, s->first, name);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
491 else
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
492 new = af_prepend(s, s->first, name);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
493 if(!new)
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
494 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
495
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
496 // Reinitalize the filter list
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
497 if(AF_OK != af_reinit(s, s->first)){
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
498 free(new);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
499 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
500 }
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
501 return new;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
502 }
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
503
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
504 // Filter data chunk through the filters in the list
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
505 af_data_t* af_play(af_stream_t* s, af_data_t* data)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
506 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
507 af_instance_t* af=s->first;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
508 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
509 do{
16815
78c84594247b semi-hack: avoid passing 0-length blocks to audio filters.
reimar
parents: 16627
diff changeset
510 if (data->len <= 0) break;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
511 data=af->play(af,data);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
512 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
513 }while(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
514 return data;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
515 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
516
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
517 /* Helper function used to calculate the exact buffer length needed
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
518 when buffers are resized. The returned length is >= than what is
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
519 needed */
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
520 inline int af_lencalc(frac_t mul, af_data_t* d){
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
521 register int t = d->bps*d->nch;
7590
0cba73469341 Fixing the fix buffer overrun should work now
anders
parents: 7589
diff changeset
522 return t*(((d->len/t)*mul.n)/mul.d + 1);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
523 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
524
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
525 /* Calculate how long the output from the filters will be given the
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
526 input length "len". The calculated length is >= the actual
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
527 length. */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
528 int af_outputlen(af_stream_t* s, int len)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
529 {
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
530 int t = s->input.bps*s->input.nch;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
531 af_instance_t* af=s->first;
14569
408dfb63ff95 Make this file compile with gcc-4.0.0:
gpoirier
parents: 14433
diff changeset
532 frac_t mul = {1,1};
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
533 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
534 do{
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
535 af_frac_mul(&mul, &af->mul);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
536 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
537 }while(af);
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
538 return t * (((len/t)*mul.n + 1)/mul.d);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
539 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
540
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
541 /* Calculate how long the input to the filters should be to produce a
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
542 certain output length, i.e. the return value of this function is
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
543 the input length required to produce the output length "len". The
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
544 calculated length is <= the actual length */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
545 int af_inputlen(af_stream_t* s, int len)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
546 {
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
547 int t = s->input.bps*s->input.nch;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
548 af_instance_t* af=s->first;
14569
408dfb63ff95 Make this file compile with gcc-4.0.0:
gpoirier
parents: 14433
diff changeset
549 frac_t mul = {1,1};
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
550 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
551 do{
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
552 af_frac_mul(&mul, &af->mul);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
553 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
554 }while(af);
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
555 return t * (((len/t) * mul.d - 1)/mul.n);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
556 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
557
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
558 /* Calculate how long the input IN to the filters should be to produce
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
559 a certain output length OUT but with the following three constraints:
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
560 1. IN <= max_insize, where max_insize is the maximum possible input
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
561 block length
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
562 2. OUT <= max_outsize, where max_outsize is the maximum possible
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
563 output block length
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
564 3. If possible OUT >= len.
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
565 Return -1 in case of error */
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
566 int af_calc_insize_constrained(af_stream_t* s, int len,
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
567 int max_outsize,int max_insize)
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
568 {
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
569 int t = s->input.bps*s->input.nch;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
570 int in = 0;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
571 int out = 0;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
572 af_instance_t* af=s->first;
14569
408dfb63ff95 Make this file compile with gcc-4.0.0:
gpoirier
parents: 14433
diff changeset
573 frac_t mul = {1,1};
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
574 // Iterate through all filters and calculate total multiplication factor
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
575 do{
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
576 af_frac_mul(&mul, &af->mul);
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
577 af=af->next;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
578 }while(af);
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
579 // Sanity check
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
580 if(!mul.n || !mul.d)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
581 return -1;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
582
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
583 in = t * (((len/t) * mul.d - 1)/mul.n);
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
584
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
585 if(in>max_insize) in=t*(max_insize/t);
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
586
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
587 // Try to meet constraint nr 3.
7612
arpi
parents: 7603
diff changeset
588 while((out=t * (((in/t+1)*mul.n - 1)/mul.d)) <= max_outsize && in<=max_insize){
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
589 if( (t * (((in/t)*mul.n))/mul.d) >= len) return in;
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
590 in+=t;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
591 }
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
592
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
593 // Could no meet constraint nr 3.
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
594 while(out > max_outsize || in > max_insize){
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
595 in-=t;
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
596 if(in<t) return -1; // Input parameters are probably incorrect
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
597 out = t * (((in/t)*mul.n + 1)/mul.d);
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
598 }
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
599 return in;
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
600 }
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
601
7665
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
602 /* Calculate the total delay [ms] caused by the filters */
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
603 double af_calc_delay(af_stream_t* s)
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
604 {
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
605 af_instance_t* af=s->first;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
606 register double delay = 0.0;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
607 // Iterate through all filters
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
608 while(af){
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
609 delay += af->delay;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
610 af=af->next;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
611 }
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
612 return delay;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
613 }
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
614
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
615 /* Helper function called by the macro with the same name this
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
616 function should not be called directly */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
617 inline int af_resize_local_buffer(af_instance_t* af, af_data_t* data)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
618 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
619 // Calculate new length
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
620 register int len = af_lencalc(af->mul,data);
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
621 af_msg(AF_MSG_VERBOSE,"[libaf] Reallocating memory in module %s, "
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
622 "old len = %i, new len = %i\n",af->info->name,af->data->len,len);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
623 // If there is a buffer free it
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
624 if(af->data->audio)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
625 free(af->data->audio);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
626 // Create new buffer and check that it is OK
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
627 af->data->audio = malloc(len);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
628 if(!af->data->audio){
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
629 af_msg(AF_MSG_FATAL,"[libaf] Could not allocate memory \n");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
630 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
631 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
632 af->data->len=len;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
633 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
634 }
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
635
16627
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
636 // documentation in af.h
14292
12239a0d5408 Make af_control_any_rev return the matching filter
reimar
parents: 14243
diff changeset
637 af_instance_t *af_control_any_rev (af_stream_t* s, int cmd, void* arg) {
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
638 int res = AF_UNKNOWN;
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
639 af_instance_t* filt = s->last;
14292
12239a0d5408 Make af_control_any_rev return the matching filter
reimar
parents: 14243
diff changeset
640 while (filt) {
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
641 res = filt->control(filt, cmd, arg);
14292
12239a0d5408 Make af_control_any_rev return the matching filter
reimar
parents: 14243
diff changeset
642 if (res == AF_OK)
12239a0d5408 Make af_control_any_rev return the matching filter
reimar
parents: 14243
diff changeset
643 return filt;
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
644 filt = filt->prev;
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
645 }
14292
12239a0d5408 Make af_control_any_rev return the matching filter
reimar
parents: 14243
diff changeset
646 return NULL;
12668
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
647 }
ce6ab8cb8597 Send a command throught the filter chain until some item returns AF_OK. Patch by Reimar Doeffinger
alex
parents: 11859
diff changeset
648
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
649 /**
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
650 * \brief calculate greatest common divisior of a and b.
16627
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
651 * \ingroup af_filter
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
652 *
19883
4e43ba6844d8 Fix stupid use of multiplication to check signs which fails because of
uau
parents: 18967
diff changeset
653 * If both are 0 the result is 1.
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
654 */
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
655 int af_gcd(register int a, register int b) {
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
656 while (b != 0) {
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
657 a %= b;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
658 if (a == 0)
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
659 break;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
660 b %= a;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
661 }
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
662 // the result is either in a or b. As the other one is 0 just add them.
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
663 a += b;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
664 if (!a)
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
665 return 1;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
666 return a;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
667 }
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
668
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
669 /**
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
670 * \brief cancel down a fraction f
16627
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
671 * \param f fraction to cancel down
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
672 * \ingroup af_filter
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
673 */
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
674 void af_frac_cancel(frac_t *f) {
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
675 int gcd = af_gcd(f->n, f->d);
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
676 f->n /= gcd;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
677 f->d /= gcd;
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
678 }
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
679
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
680 /**
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
681 * \brief multiply out by in and store result in out.
16627
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
682 * \param out [inout] fraction to multiply by in
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
683 * \param in [in] fraction to multiply out by
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
684 * \ingroup af_filter
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
685 *
584bd8980d57 documentation-only patch: make doxygen compatible and create
reimar
parents: 16072
diff changeset
686 * the resulting fraction will be cancelled down
14433
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
687 * if in and out were.
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
688 */
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
689 void af_frac_mul(frac_t *out, const frac_t *in) {
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
690 int gcd1 = af_gcd(out->n, in->d);
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
691 int gcd2 = af_gcd(in->n, out->d);
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
692 out->n = (out->n / gcd1) * (in->n / gcd2);
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
693 out->d = (out->d / gcd2) * (in->d / gcd1);
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
694 }
95bb94a930a3 always cancel down fractions (frac_t) to avoid overflows and playback
reimar
parents: 14335
diff changeset
695
13269
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
696 void af_help (void) {
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
697 int i = 0;
13566
2cfb32a737aa make af_help conform better to the the afm/vfm/etc equivalents
alex
parents: 13550
diff changeset
698 af_msg(AF_MSG_INFO, "Available audio filters:\n");
13269
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
699 while (filter_list[i]) {
13566
2cfb32a737aa make af_help conform better to the the afm/vfm/etc equivalents
alex
parents: 13550
diff changeset
700 if (filter_list[i]->comment && filter_list[i]->comment[0])
2cfb32a737aa make af_help conform better to the the afm/vfm/etc equivalents
alex
parents: 13550
diff changeset
701 af_msg(AF_MSG_INFO, " %-15s: %s (%s)\n", filter_list[i]->name, filter_list[i]->info, filter_list[i]->comment);
2cfb32a737aa make af_help conform better to the the afm/vfm/etc equivalents
alex
parents: 13550
diff changeset
702 else
2cfb32a737aa make af_help conform better to the the afm/vfm/etc equivalents
alex
parents: 13550
diff changeset
703 af_msg(AF_MSG_INFO, " %-15s: %s\n", filter_list[i]->name, filter_list[i]->info);
13269
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
704 i++;
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
705 }
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
706 }
aa13937da8a0 mplayer -af help now lists all available audio filters.
ivo
parents: 12668
diff changeset
707
14818
663c1ea5f595 finally remove the refences to bps outside libaf. also simplification of some messages and removed redundants
alex
parents: 14750
diff changeset
708 void af_fix_parameters(af_data_t *data)
663c1ea5f595 finally remove the refences to bps outside libaf. also simplification of some messages and removed redundants
alex
parents: 14750
diff changeset
709 {
663c1ea5f595 finally remove the refences to bps outside libaf. also simplification of some messages and removed redundants
alex
parents: 14750
diff changeset
710 data->bps = af_fmt2bits(data->format)/8;
663c1ea5f595 finally remove the refences to bps outside libaf. also simplification of some messages and removed redundants
alex
parents: 14750
diff changeset
711 }