annotate libaf/af.c @ 8167:e8832e66babd

New features: -- Support for runtime cpu detection -- Stand alone compile of libaf -- Unlimited number of channels (compiletime switch) -- Sample format defined by bit-fields -- New formats: float, A-Law and mu-law -- Format conversion set in human readable format i.e. format=4:us_be to set 32 bit unsigned big endian output -- Format reporting in human readable format -- Volume control has only one parameter for setting the volume i.e. volume=-10.0:1:0:1 to set atenuation = -10dB
author anders
date Tue, 12 Nov 2002 12:33:56 +0000
parents c0e556f9986b
children d6f40a06867b
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;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
19
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
20 static af_info_t* filter_list[]={ \
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
21 &af_info_dummy,\
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
22 &af_info_delay,\
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
23 &af_info_channels,\
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
24 &af_info_format,\
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
25 &af_info_resample,\
7974
db1f16543379 enable volume filter and fix nonsense default volume (still not usable
rfelker
parents: 7745
diff changeset
26 &af_info_volume,\
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents: 7998
diff changeset
27 &af_info_equalizer,\
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
28 NULL \
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
29 };
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
30
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
31 // Message printing
e8832e66babd New features:
anders
parents: 8073
diff changeset
32 af_msg_cfg_t af_msg_cfg={0,NULL,NULL};
e8832e66babd New features:
anders
parents: 8073
diff changeset
33
e8832e66babd New features:
anders
parents: 8073
diff changeset
34 // CPU speed
e8832e66babd New features:
anders
parents: 8073
diff changeset
35 int* af_cpu_speed = NULL;
e8832e66babd New features:
anders
parents: 8073
diff changeset
36
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
37 /* 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
38 function is used internally */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
39 af_info_t* af_find(char*name)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
40 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
41 int i=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
42 while(filter_list[i]){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
43 if(!strcmp(filter_list[i]->name,name))
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
44 return filter_list[i];
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
45 i++;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
46 }
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
47 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
48 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
49 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
50
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
51 /* 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
52 function is used for finding already initialized filters */
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
53 af_instance_t* af_get(af_stream_t* s, char* name)
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
54 {
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
55 af_instance_t* af=s->first;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
56 // Find the filter
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
57 while(af != NULL){
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
58 if(!strcmp(af->info->name,name))
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
59 return af;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
60 af=af->next;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
61 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
62 return NULL;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
63 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
64
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
65 /*/ 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
66 contain the commandline parameters for the filter */
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
67 af_instance_t* af_create(af_stream_t* s, char* name)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
68 {
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
69 char* cmdline = name;
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
70 char* delim = "=";
7998
d48a06d07afb Adding commandline options for filters and fixing stupid bug in cfg
anders
parents: 7993
diff changeset
71
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
72 // Allocate space for the new filter and reset all pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
73 af_instance_t* new=malloc(sizeof(af_instance_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
74 if(!new){
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
75 af_msg(AF_MSG_ERROR,"Could not allocate memory\n");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
76 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
77 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
78 memset(new,0,sizeof(af_instance_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
79
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
80 // Check for commandline parameters
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
81 strsep(&cmdline, delim);
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
82
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
83 // Find filter from name
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
84 if(NULL == (new->info=af_find(name)))
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
85 return NULL;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
86
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
87 /* 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
88 non-reentrant */
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
89 if(new->info->flags & AF_FLAGS_NOT_REENTRANT){
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
90 if(af_get(s,name)){
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
91 af_msg(AF_MSG_ERROR,"There can only be one instance of the filter '%s' in each stream\n",name);
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
92 free(new);
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
93 return NULL;
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
94 }
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
95 }
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
96
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
97 af_msg(AF_MSG_VERBOSE,"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
98
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
99 // Initialize the new filter
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
100 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
101 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
102 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
103 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
104 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
105 }
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
106 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
107 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
108 }
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
109
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
110 free(new);
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
111 af_msg(AF_MSG_ERROR,"Couldn't create or open audio filter '%s'\n",name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
112 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
113 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
114
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
115 /* 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
116 argument. This function can be called during runtime, the return
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
117 value is the new filter */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
118 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
119 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
120 // Create the new filter and make sure it is OK
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
121 af_instance_t* new=af_create(s,name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
122 if(!new)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
123 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
124 // Update pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
125 new->next=af;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
126 if(af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
127 new->prev=af->prev;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
128 af->prev=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
129 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
130 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
131 s->last=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
132 if(new->prev)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
133 new->prev->next=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
134 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
135 s->first=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
136 return new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
137 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
138
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
139 /* 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
140 argument. This function can be called during runtime, the return
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
141 value is the new filter */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
142 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
143 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
144 // Create the new filter and make sure it is OK
7615
c67328dd459a Adding Support for non-reentrant audio filters
anders
parents: 7612
diff changeset
145 af_instance_t* new=af_create(s,name);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
146 if(!new)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
147 return NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
148 // Update pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
149 new->prev=af;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
150 if(af){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
151 new->next=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
152 af->next=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
153 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
154 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
155 s->first=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
156 if(new->next)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
157 new->next->prev=new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
158 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
159 s->last=new;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
160 return new;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
161 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
162
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
163 // 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
164 void af_remove(af_stream_t* s, af_instance_t* af)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
165 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
166 if(!af) return;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
167
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
168 // Notify filter before changing anything
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
169 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
170
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
171 // Detach pointers
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
172 if(af->prev)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
173 af->prev->next=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
174 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
175 s->first=af->next;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
176 if(af->next)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
177 af->next->prev=af->prev;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
178 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
179 s->last=af->prev;
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 // Uninitialize af and free memory
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
182 af->uninit(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
183 free(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
184 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
185
7649
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
186 /* Reinitializes all filters downstream from the filter given in the
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
187 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
188 failure */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
189 int af_reinit(af_stream_t* s, af_instance_t* af)
7568
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 if(!af)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
192 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
193
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
194 do{
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
195 af_data_t in; // Format of the input to current filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
196 int rv=0; // Return value
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
197
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
198 // Check if this is the first filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
199 if(!af->prev)
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
200 memcpy(&in,&(s->input),sizeof(af_data_t));
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
201 else
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
202 memcpy(&in,af->prev->data,sizeof(af_data_t));
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
203 // Reset just in case...
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
204 in.audio=NULL;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
205 in.len=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
206
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
207 rv = af->control(af,AF_CONTROL_REINIT,&in);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
208 switch(rv){
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
209 case AF_OK:
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
210 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
211 case AF_FALSE:{ // Configuration filter is needed
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
212 // Do auto insertion only if force is not specified
e8832e66babd New features:
anders
parents: 8073
diff changeset
213 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
e8832e66babd New features:
anders
parents: 8073
diff changeset
214 af_instance_t* new = NULL;
e8832e66babd New features:
anders
parents: 8073
diff changeset
215 // Insert channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
216 if((af->prev?af->prev->data->nch:s->input.nch) != in.nch){
e8832e66babd New features:
anders
parents: 8073
diff changeset
217 // Create channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
218 if(NULL == (new = af_prepend(s,af,"channels")))
e8832e66babd New features:
anders
parents: 8073
diff changeset
219 return AF_ERROR;
e8832e66babd New features:
anders
parents: 8073
diff changeset
220 // Set number of output channels
e8832e66babd New features:
anders
parents: 8073
diff changeset
221 if(AF_OK != (rv = new->control(new,AF_CONTROL_CHANNELS,&in.nch)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
222 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
223 // Initialize channels filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
224 if(!new->prev)
e8832e66babd New features:
anders
parents: 8073
diff changeset
225 memcpy(&in,&(s->input),sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
226 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
227 memcpy(&in,new->prev->data,sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
228 if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
229 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
230 }
e8832e66babd New features:
anders
parents: 8073
diff changeset
231 // Insert format filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
232 if(((af->prev?af->prev->data->format:s->input.format) != in.format) ||
e8832e66babd New features:
anders
parents: 8073
diff changeset
233 ((af->prev?af->prev->data->bps:s->input.bps) != in.bps)){
e8832e66babd New features:
anders
parents: 8073
diff changeset
234 // Create format filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
235 if(NULL == (new = af_prepend(s,af,"format")))
e8832e66babd New features:
anders
parents: 8073
diff changeset
236 return AF_ERROR;
e8832e66babd New features:
anders
parents: 8073
diff changeset
237 // Set output format
e8832e66babd New features:
anders
parents: 8073
diff changeset
238 if(AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT,&in)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
239 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
240 // Initialize format filter
e8832e66babd New features:
anders
parents: 8073
diff changeset
241 if(!new->prev)
e8832e66babd New features:
anders
parents: 8073
diff changeset
242 memcpy(&in,&(s->input),sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
243 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
244 memcpy(&in,new->prev->data,sizeof(af_data_t));
e8832e66babd New features:
anders
parents: 8073
diff changeset
245 if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
e8832e66babd New features:
anders
parents: 8073
diff changeset
246 return rv;
e8832e66babd New features:
anders
parents: 8073
diff changeset
247 }
e8832e66babd New features:
anders
parents: 8073
diff changeset
248 if(!new) // Should _never_ happen
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
249 return AF_ERROR;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
250 af=new;
7568
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 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
253 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
254 case AF_DETACH:{ // Filter is redundant and wants to be unloaded
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
255 // Do auto remove only if force is not specified
e8832e66babd New features:
anders
parents: 8073
diff changeset
256 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
e8832e66babd New features:
anders
parents: 8073
diff changeset
257 af_instance_t* aft=af->prev;
e8832e66babd New features:
anders
parents: 8073
diff changeset
258 af_remove(s,af);
e8832e66babd New features:
anders
parents: 8073
diff changeset
259 if(aft)
e8832e66babd New features:
anders
parents: 8073
diff changeset
260 af=aft;
e8832e66babd New features:
anders
parents: 8073
diff changeset
261 else
e8832e66babd New features:
anders
parents: 8073
diff changeset
262 af=s->first; // Restart configuration
e8832e66babd New features:
anders
parents: 8073
diff changeset
263 }
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
264 break;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
265 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
266 default:
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
267 af_msg(AF_MSG_ERROR,"Reinitialization did not work, audio filter '%s' returned error code %i\n",af->info->name,rv);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
268 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
269 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
270 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
271 }while(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
272 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
273 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
274
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
275 // 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
276 void af_uninit(af_stream_t* s)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
277 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
278 while(s->first)
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
279 af_remove(s,s->first);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
280 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
281
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
282 /* 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
283 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
284 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
285 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
286 reentrant i.e. if called with an already initialized stream the
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
287 stream will be reinitialized. The return value is 0 if success and
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
288 -1 if failure */
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
289 int af_init(af_stream_t* s)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
290 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
291 int i=0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
292
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
293 // Sanity check
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
294 if(!s) return -1;
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
295
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
296 // 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
297 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
298 s->input.len = s->output.len = 0;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
299
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
300 // Figure out how fast the machine is
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
301 if(AF_INIT_AUTO == (AF_INIT_TYPE_MASK & s->cfg.force))
e8832e66babd New features:
anders
parents: 8073
diff changeset
302 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
303
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
304 // 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
305 if(!s->first){
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
306 // 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
307 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
308 if(!af_append(s,s->first,"dummy"))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
309 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
310 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
311 else{
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
312 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
313 if(!af_append(s,s->last,s->cfg.list[i++]))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
314 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
315 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
316 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
317 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
318
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
319 // Init filters
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
320 if(AF_OK != af_reinit(s,s->first))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
321 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
322
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
323 // Check output format
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
324 if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
325 af_instance_t* af = NULL; // New filter
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
326 // Check output frequency if not OK fix with resample
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
327 if(s->last->data->rate!=s->output.rate){
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
328 if(NULL==(af=af_get(s,"resample"))){
7745
1d3a3dc1f488 Adding volume control and moving control() call parameters to a seperate file
anders
parents: 7665
diff changeset
329 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
330 if(!strcmp(s->first->info->name,"format"))
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
331 af = af_append(s,s->first,"resample");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
332 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
333 af = af_prepend(s,s->first,"resample");
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 else{
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
336 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
337 af = af_prepend(s,s->last,"resample");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
338 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
339 af = af_append(s,s->last,"resample");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
340 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
341 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
342 // 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
343 if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE,&(s->output.rate))))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
344 return -1;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
345 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
346 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
347 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
348
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
349 // Check number of output channels fix if not OK
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
350 // If needed always inserted last -> easy to screw up other filters
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
351 if(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
352 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
353 af = af_prepend(s,s->last,"channels");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
354 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
355 af = af_append(s,s->last,"channels");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
356 // 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
357 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
358 return -1;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
359 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
360 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
361 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
362
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
363 // Check output format fix if not OK
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
364 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
365 (s->last->data->bps != s->output.bps)){
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
366 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
367 af = af_append(s,s->last,"format");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
368 else
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
369 af = s->last;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
370 // 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
371 if(!af ||(AF_OK != af->control(af,AF_CONTROL_FORMAT,&(s->output))))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
372 return -1;
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
373 if(AF_OK != af_reinit(s,af))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
374 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
375 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
376
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
377 // 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
378 if(AF_OK != af_reinit(s,s->first))
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
379 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
380
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
381 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
382 (s->last->data->bps != s->output.bps) ||
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
383 (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
384 (s->last->data->rate != s->output.rate)) {
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
385 // Something is stuffed audio out will not work
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
386 af_msg(AF_MSG_ERROR,"Unable to setup filter system can not meet sound-card demands, please report this error on MPlayer development mailing list. \n");
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
387 af_uninit(s);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
388 return -1;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
389 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
390 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
391 return 0;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
392 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
393
7649
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
394 /* Add filter during execution. This function adds the filter "name"
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
395 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
396 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
397 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
398 af_instance_t* af_add(af_stream_t* s, char* name){
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
399 af_instance_t* new;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
400 // Sanity check
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
401 if(!s || !s->first || !name)
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
402 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
403 // Insert the filter somwhere nice
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
404 if(!strcmp(s->first->info->name,"format"))
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
405 new = af_append(s, s->first, name);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
406 else
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
407 new = af_prepend(s, s->first, name);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
408 if(!new)
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
409 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
410
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
411 // Reinitalize the filter list
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
412 if(AF_OK != af_reinit(s, s->first)){
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
413 free(new);
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
414 return NULL;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
415 }
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
416 return new;
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
417 }
90e16aa8ae5f Adding functionality for adding filters during execution
anders
parents: 7617
diff changeset
418
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
419 // 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
420 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
421 {
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
422 af_instance_t* af=s->first;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
423 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
424 do{
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
425 data=af->play(af,data);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
426 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
427 }while(af);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
428 return data;
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 /* Helper function used to calculate the exact buffer length needed
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
432 when buffers are resized. The returned length is >= than what is
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
433 needed */
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
434 inline int af_lencalc(frac_t mul, af_data_t* d){
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
435 register int t = d->bps*d->nch;
7590
0cba73469341 Fixing the fix buffer overrun should work now
anders
parents: 7589
diff changeset
436 return t*(((d->len/t)*mul.n)/mul.d + 1);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
437 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
438
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
439 /* Calculate how long the output from the filters will be given the
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
440 input length "len". The calculated length is >= the actual
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
441 length. */
7571
8819fdf88b5d Adding support for multiple audio streams and removing annoying message from resample and format
anders
parents: 7568
diff changeset
442 int af_outputlen(af_stream_t* s, int len)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
443 {
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
444 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
445 af_instance_t* af=s->first;
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
446 register frac_t mul = {1,1};
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
447 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
448 do{
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
449 mul.n *= af->mul.n;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
450 mul.d *= af->mul.d;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
451 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
452 }while(af);
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
453 return t * (((len/t)*mul.n + 1)/mul.d);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
454 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
455
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
456 /* 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
457 certain output length, i.e. the return value of this function is
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
458 the input length required to produce the output length "len". The
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
459 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
460 int af_inputlen(af_stream_t* s, int len)
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
461 {
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
462 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
463 af_instance_t* af=s->first;
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
464 register frac_t mul = {1,1};
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
465 // Iterate through all filters
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
466 do{
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
467 mul.n *= af->mul.n;
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
468 mul.d *= af->mul.d;
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
469 af=af->next;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
470 }while(af);
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
471 return t * (((len/t) * mul.d - 1)/mul.n);
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
472 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
473
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
474 /* 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
475 a certain output length OUT but with the following three constraints:
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
476 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
477 block length
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
478 2. OUT <= max_outsize, where max_outsize is the maximum possible
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
479 output block length
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
480 3. If possible OUT >= len.
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
481 Return -1 in case of error */
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
482 int af_calc_insize_constrained(af_stream_t* s, int len,
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
483 int max_outsize,int max_insize)
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
484 {
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
485 int t = s->input.bps*s->input.nch;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
486 int in = 0;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
487 int out = 0;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
488 af_instance_t* af=s->first;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
489 register frac_t mul = {1,1};
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
490 // Iterate through all filters and calculate total multiplication factor
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
491 do{
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
492 mul.n *= af->mul.n;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
493 mul.d *= af->mul.d;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
494 af=af->next;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
495 }while(af);
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
496 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
497
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
498 if(in>max_insize) in=t*(max_insize/t);
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
499
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
500 // Try to meet constraint nr 3.
7612
arpi
parents: 7603
diff changeset
501 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
502 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
503 in+=t;
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
504 }
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
505
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
506 // 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
507 while(out > max_outsize || in > max_insize){
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
508 in-=t;
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
509 if(in<t) return -1; // Input parameters are probably incorrect
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
510 out = t * (((in/t)*mul.n + 1)/mul.d);
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
511 }
7603
c89106306f5a af_calc_insize_constrained() rounding changes, works better for me this way
arpi
parents: 7599
diff changeset
512 return in;
7598
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
513 }
48f8c731efb5 Adding function for estimating required buffer length
anders
parents: 7590
diff changeset
514
7665
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
515 /* 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
516 double af_calc_delay(af_stream_t* s)
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
517 {
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
518 af_instance_t* af=s->first;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
519 register double delay = 0.0;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
520 // Iterate through all filters
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
521 while(af){
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
522 delay += af->delay;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
523 af=af->next;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
524 }
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
525 return delay;
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
526 }
fbd5445cc853 Adding function for calculating the delay caused by the filters
anders
parents: 7649
diff changeset
527
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
528 /* Helper function called by the macro with the same name this
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
529 function should not be called directly */
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
530 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
531 {
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
532 // Calculate new length
7589
443b440798a5 Redesign of buffer length calculation
anders
parents: 7581
diff changeset
533 register int len = af_lencalc(af->mul,data);
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
534 af_msg(AF_MSG_VERBOSE,"Reallocating memory in module %s, 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
535 // If there is a buffer free it
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
536 if(af->data->audio)
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
537 free(af->data->audio);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
538 // Create new buffer and check that it is OK
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
539 af->data->audio = malloc(len);
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
540 if(!af->data->audio){
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
541 af_msg(AF_MSG_FATAL,"Could not allocate memory \n");
7568
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
542 return AF_ERROR;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
543 }
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
544 af->data->len=len;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
545 return AF_OK;
d08513b9fed6 Adding new audio output filter layer libaf
anders
parents:
diff changeset
546 }