summaryrefslogtreecommitdiff
path: root/src/lib/ecore_audio
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-01 14:37:10 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-01 14:41:15 +0900
commitd27f5fcab78cabe880e9b3f2a62ac633d97ce381 (patch)
treee603f922930b672291110cc8637183af15abda57 /src/lib/ecore_audio
parente077e923722be0e4a674f0ac3dc07814b3c96003 (diff)
ecore_audio - save 232k of real RAM by dlopening depednecies
so libpuls and libsndfile suck in dependencies. they suck in so much that by the time linking is done we've written to about 230kb of PRIVATE MEMORY as dirty pages in symbol tablesm global veriables etc. etc. - this is just horrible. especially if an app never makes any sound... it's just wasted memory. this stuff is invisible to normal memory debug tools. so this begins to address things. please see T4227. my numbers now put me at: 1780Kb total dirty writable mapped from library file pages. down from 2012Kb. This fixes some memory bloat reported in the above ticket, but there is more to fix for sure. @fix
Diffstat (limited to 'src/lib/ecore_audio')
-rw-r--r--src/lib/ecore_audio/ecore_audio.c175
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c19
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_pulse.c50
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c16
-rw-r--r--src/lib/ecore_audio/ecore_audio_private.h70
5 files changed, 290 insertions, 40 deletions
diff --git a/src/lib/ecore_audio/ecore_audio.c b/src/lib/ecore_audio/ecore_audio.c
index 4d38c13ada..d09d656008 100644
--- a/src/lib/ecore_audio/ecore_audio.c
+++ b/src/lib/ecore_audio/ecore_audio.c
@@ -18,6 +18,12 @@ int _ecore_audio_log_dom = -1;
18static int _ecore_audio_init_count = 0; 18static int _ecore_audio_init_count = 0;
19Eina_List *ecore_audio_modules; 19Eina_List *ecore_audio_modules;
20 20
21#ifdef HAVE_PULSE
22Ecore_Audio_Lib_Pulse *ecore_audio_pulse_lib = NULL;
23#endif /* HAVE_PULSE */
24#ifdef HAVE_SNDFILE
25Ecore_Audio_Lib_Sndfile *ecore_audio_sndfile_lib = NULL;
26#endif /* HAVE_SNDFILE */
21 27
22/* externally accessible functions */ 28/* externally accessible functions */
23 29
@@ -61,6 +67,13 @@ ecore_audio_shutdown(void)
61 if (--_ecore_audio_init_count != 0) 67 if (--_ecore_audio_init_count != 0)
62 return _ecore_audio_init_count; 68 return _ecore_audio_init_count;
63 69
70#ifdef HAVE_SNDFILE
71 ecore_audio_sndfile_lib_unload();
72#endif /* HAVE_SNDFILE */
73#ifdef HAVE_PULSE
74 ecore_audio_pulse_lib_unload();
75#endif /* HAVE_PULSE */
76
64 /* FIXME: Shutdown all the inputs and outputs first */ 77 /* FIXME: Shutdown all the inputs and outputs first */
65 eina_log_timing(_ecore_audio_log_dom, 78 eina_log_timing(_ecore_audio_log_dom,
66 EINA_LOG_STATE_START, 79 EINA_LOG_STATE_START,
@@ -78,6 +91,168 @@ ecore_audio_shutdown(void)
78 return _ecore_audio_init_count; 91 return _ecore_audio_init_count;
79} 92}
80 93
94#ifdef HAVE_PULSE
95Eina_Bool
96ecore_audio_pulse_lib_load(void)
97{
98 if (ecore_audio_pulse_lib)
99 {
100 if (!ecore_audio_pulse_lib->mod)
101 {
102 ERR("Cannot find libpulse!");
103 return EINA_FALSE;
104 }
105 return EINA_TRUE;
106 }
107
108 ecore_audio_pulse_lib = calloc(1, sizeof(Ecore_Audio_Lib_Pulse));
109 if (!ecore_audio_pulse_lib) return EINA_FALSE;
110# define LOAD(x) \
111 if (!ecore_audio_pulse_lib->mod) { \
112 if ((ecore_audio_pulse_lib->mod = eina_module_new(x))) { \
113 if (!eina_module_load(ecore_audio_pulse_lib->mod)) { \
114 eina_module_free(ecore_audio_pulse_lib->mod); \
115 ecore_audio_pulse_lib->mod = NULL; \
116 } \
117 } \
118 }
119# if defined(_WIN32) || defined(__CYGWIN__)
120 LOAD("libpulse-0.dll");
121 LOAD("libpulse.dll");
122 LOAD("pulse.dll");
123# elif defined(__APPLE__) && defined(__MACH__)
124 LOAD("libpulse.0.dylib");
125 LOAD("libpulse.0.so");
126 LOAD("libpulse.so.0");
127# else
128 LOAD("libpulse.so.0");
129# endif
130# undef LOAD
131 if (!ecore_audio_pulse_lib->mod) return EINA_FALSE;
132
133#define SYM(x) \
134 if (!(ecore_audio_pulse_lib->x = eina_module_symbol_get(ecore_audio_pulse_lib->mod, #x))) { \
135 ERR("libpulse - cannot find %s", #x); \
136 goto err; \
137 }
138 SYM(pa_context_new);
139 SYM(pa_context_connect);
140 SYM(pa_context_set_sink_input_volume);
141 SYM(pa_context_get_state);
142 SYM(pa_context_set_state_callback);
143 SYM(pa_operation_unref);
144 SYM(pa_cvolume_set);
145 SYM(pa_stream_new);
146 SYM(pa_stream_unref);
147 SYM(pa_stream_connect_playback);
148 SYM(pa_stream_disconnect);
149 SYM(pa_stream_drain);
150 SYM(pa_stream_cork);
151 SYM(pa_stream_write);
152 SYM(pa_stream_begin_write);
153 SYM(pa_stream_set_write_callback);
154 SYM(pa_stream_trigger);
155 SYM(pa_stream_update_sample_rate);
156 SYM(pa_stream_get_index);
157#undef SYM
158 return EINA_TRUE;
159err:
160 if (ecore_audio_pulse_lib->mod)
161 {
162 eina_module_free(ecore_audio_pulse_lib->mod);
163 ecore_audio_pulse_lib->mod = NULL;
164 }
165 return EINA_FALSE;
166}
167
168void
169ecore_audio_pulse_lib_unload(void)
170{
171 if (ecore_audio_pulse_lib)
172 {
173 if (ecore_audio_pulse_lib->mod)
174 eina_module_free(ecore_audio_pulse_lib->mod);
175 free(ecore_audio_pulse_lib);
176 ecore_audio_pulse_lib = NULL;
177 }
178}
179#endif /* HAVE_PULSE */
180
181#ifdef HAVE_SNDFILE
182Eina_Bool
183ecore_audio_sndfile_lib_load(void)
184{
185 if (ecore_audio_sndfile_lib)
186 {
187 if (!ecore_audio_sndfile_lib->mod)
188 {
189 ERR("Cannot find libsndfile!");
190 return EINA_FALSE;
191 }
192 return EINA_TRUE;
193 }
194
195 ecore_audio_sndfile_lib = calloc(1, sizeof(Ecore_Audio_Lib_Sndfile));
196 if (!ecore_audio_sndfile_lib) return EINA_FALSE;
197# define LOAD(x) \
198 if (!ecore_audio_sndfile_lib->mod) { \
199 if ((ecore_audio_sndfile_lib->mod = eina_module_new(x))) { \
200 if (!eina_module_load(ecore_audio_sndfile_lib->mod)) { \
201 eina_module_free(ecore_audio_sndfile_lib->mod); \
202 ecore_audio_sndfile_lib->mod = NULL; \
203 } \
204 } \
205 }
206# if defined(_WIN32) || defined(__CYGWIN__)
207 LOAD("libsndfile-1.dll");
208 LOAD("libsndfile.dll");
209 LOAD("sndfile.dll");
210# elif defined(__APPLE__) && defined(__MACH__)
211 LOAD("libsndfile.1.dylib");
212 LOAD("libsndfile.1.so");
213 LOAD("libsndfile.so.1");
214# else
215 LOAD("libsndfile.so.1");
216# endif
217# undef LOAD
218 if (!ecore_audio_sndfile_lib->mod) return EINA_FALSE;
219
220#define SYM(x) \
221 if (!(ecore_audio_sndfile_lib->x = eina_module_symbol_get(ecore_audio_sndfile_lib->mod, #x))) { \
222 ERR("libsndfile - cannot find %s", #x); \
223 goto err; \
224 }
225 SYM(sf_open);
226 SYM(sf_open_virtual);
227 SYM(sf_close);
228 SYM(sf_read_float);
229 SYM(sf_write_float);
230 SYM(sf_write_sync);
231 SYM(sf_seek);
232 SYM(sf_strerror);
233#undef SYM
234 return EINA_TRUE;
235err:
236 if (ecore_audio_sndfile_lib->mod)
237 {
238 eina_module_free(ecore_audio_sndfile_lib->mod);
239 ecore_audio_sndfile_lib->mod = NULL;
240 }
241 return EINA_FALSE;
242}
243
244void
245ecore_audio_sndfile_lib_unload(void)
246{
247 if (ecore_audio_sndfile_lib)
248 {
249 if (ecore_audio_sndfile_lib->mod)
250 eina_module_free(ecore_audio_sndfile_lib->mod);
251 free(ecore_audio_sndfile_lib);
252 ecore_audio_sndfile_lib = NULL;
253 }
254}
255#endif /* HAVE_SNDFILE */
81 256
82/** 257/**
83 * @} 258 * @}
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
index cefe28b021..1117a65f14 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c
@@ -30,7 +30,8 @@ typedef struct _Ecore_Audio_In_Sndfile_Data Ecore_Audio_In_Sndfile_Data;
30EOLIAN static ssize_t 30EOLIAN static ssize_t
31_ecore_audio_in_sndfile_ecore_audio_in_read_internal(Eo *eo_obj EINA_UNUSED, Ecore_Audio_In_Sndfile_Data *obj, void *data, size_t len) 31_ecore_audio_in_sndfile_ecore_audio_in_read_internal(Eo *eo_obj EINA_UNUSED, Ecore_Audio_In_Sndfile_Data *obj, void *data, size_t len)
32{ 32{
33 return sf_read_float(obj->handle, data, len/4)*4; 33 if (!ESF_LOAD()) return 0;
34 return ESF_CALL(sf_read_float)(obj->handle, data, len/4)*4;
34} 35}
35 36
36EOLIAN static double 37EOLIAN static double
@@ -38,8 +39,9 @@ _ecore_audio_in_sndfile_ecore_audio_in_seek(Eo *eo_obj EINA_UNUSED, Ecore_Audio_
38{ 39{
39 sf_count_t count, pos; 40 sf_count_t count, pos;
40 41
42 if (!ESF_LOAD()) return 0.0;
41 count = offs * obj->sfinfo.samplerate; 43 count = offs * obj->sfinfo.samplerate;
42 pos = sf_seek(obj->handle, count, mode); 44 pos = ESF_CALL(sf_seek)(obj->handle, count, mode);
43 45
44 return (double)pos / obj->sfinfo.samplerate; 46 return (double)pos / obj->sfinfo.samplerate;
45} 47}
@@ -50,8 +52,9 @@ _ecore_audio_in_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_In_Sndfil
50 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS); 52 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
51 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS); 53 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
52 54
55 if (!ESF_LOAD()) return EINA_FALSE;
53 if (obj->handle) { 56 if (obj->handle) {
54 sf_close(obj->handle); 57 ESF_CALL(sf_close)(obj->handle);
55 obj->handle = NULL; 58 obj->handle = NULL;
56 } 59 }
57 60
@@ -60,7 +63,7 @@ _ecore_audio_in_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_In_Sndfil
60 if (!ea_obj->source) 63 if (!ea_obj->source)
61 return EINA_FALSE; 64 return EINA_FALSE;
62 65
63 obj->handle = sf_open(ea_obj->source, SFM_READ, &obj->sfinfo); 66 obj->handle = ESF_CALL(sf_open)(ea_obj->source, SFM_READ, &obj->sfinfo);
64 67
65 if (!obj->handle) { 68 if (!obj->handle) {
66 eina_stringshare_del(ea_obj->source); 69 eina_stringshare_del(ea_obj->source);
@@ -147,8 +150,9 @@ _ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_D
147 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS); 150 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
148 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS); 151 Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
149 152
153 if (!ESF_LOAD()) return;
150 if (obj->handle) { 154 if (obj->handle) {
151 sf_close(obj->handle); 155 ESF_CALL(sf_close)(obj->handle);
152 obj->handle = NULL; 156 obj->handle = NULL;
153 } 157 }
154 158
@@ -170,7 +174,7 @@ _ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_D
170 ea_obj->vio->free_func = free_func; 174 ea_obj->vio->free_func = free_func;
171 in_obj->seekable = (vio->seek != NULL); 175 in_obj->seekable = (vio->seek != NULL);
172 176
173 obj->handle = sf_open_virtual(&vio_wrapper, SFM_READ, &obj->sfinfo, eo_obj); 177 obj->handle = ESF_CALL(sf_open_virtual)(&vio_wrapper, SFM_READ, &obj->sfinfo, eo_obj);
174 178
175 if (!obj->handle) { 179 if (!obj->handle) {
176 eina_stringshare_del(ea_obj->source); 180 eina_stringshare_del(ea_obj->source);
@@ -199,8 +203,9 @@ _ecore_audio_in_sndfile_eo_base_destructor(Eo *eo_obj, Ecore_Audio_In_Sndfile_Da
199{ 203{
200 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS); 204 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
201 205
206 if (!ESF_LOAD()) return;
202 if (obj->handle) 207 if (obj->handle)
203 sf_close(obj->handle); 208 ESF_CALL(sf_close)(obj->handle);
204 209
205 if (ea_obj->vio) 210 if (ea_obj->vio)
206 _free_vio(ea_obj); 211 _free_vio(ea_obj);
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
index 7c6db021a7..e665df7da0 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
@@ -54,19 +54,19 @@ _ecore_audio_out_pulse_ecore_audio_volume_set(Eo *eo_obj, Ecore_Audio_Out_Pulse_
54 pa_cvolume pa_volume; 54 pa_cvolume pa_volume;
55 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); 55 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
56 56
57 if (!EPA_LOAD()) return;
57 if (volume < 0) 58 if (volume < 0)
58 volume = 0; 59 volume = 0;
59 60
60 pa_cvolume_set(&pa_volume, 2, volume * PA_VOLUME_NORM); 61 EPA_CALL(pa_cvolume_set)(&pa_volume, 2, volume * PA_VOLUME_NORM);
61 62
62 ecore_audio_obj_volume_set(eo_super(eo_obj, MY_CLASS), volume); 63 ecore_audio_obj_volume_set(eo_super(eo_obj, MY_CLASS), volume);
63 64
64 EINA_LIST_FOREACH(out_obj->inputs, input, in) { 65 EINA_LIST_FOREACH(out_obj->inputs, input, in) {
65 stream = eo_key_data_get(in, "pulse_data"); 66 stream = eo_key_data_get(in, "pulse_data");
66 idx = pa_stream_get_index(stream); 67 idx = EPA_CALL(pa_stream_get_index)(stream);
67 pa_operation_unref(pa_context_set_sink_input_volume(class_vars.context, idx, &pa_volume, NULL, NULL)); 68 EPA_CALL(pa_operation_unref)(EPA_CALL(pa_context_set_sink_input_volume)(class_vars.context, idx, &pa_volume, NULL, NULL));
68 } 69 }
69
70} 70}
71 71
72static void _write_cb(pa_stream *stream, size_t len, void *data) 72static void _write_cb(pa_stream *stream, size_t len, void *data)
@@ -77,14 +77,15 @@ static void _write_cb(pa_stream *stream, size_t len, void *data)
77 ssize_t bread = 0; 77 ssize_t bread = 0;
78 size_t wlen = len; 78 size_t wlen = len;
79 79
80 pa_stream_begin_write(stream, &buf, &wlen); 80 if (!EPA_LOAD()) return;
81 EPA_CALL(pa_stream_begin_write)(stream, &buf, &wlen);
81 82
82 bread = ecore_audio_obj_in_read(in, buf, wlen); 83 bread = ecore_audio_obj_in_read(in, buf, wlen);
83 84
84 pa_stream_write(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE); 85 EPA_CALL(pa_stream_write)(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE);
85 if (bread < (int)len) 86 if (bread < (int)len)
86 { 87 {
87 pa_operation_unref(pa_stream_trigger(stream, NULL, NULL)); 88 EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_trigger)(stream, NULL, NULL));
88 } 89 }
89} 90}
90 91
@@ -99,7 +100,7 @@ static void _update_samplerate_cb(void *data EINA_UNUSED, const Eo_Event *event)
99 100
100 stream = eo_key_data_get(event->object, "pulse_data"); 101 stream = eo_key_data_get(event->object, "pulse_data");
101 102
102 pa_operation_unref(pa_stream_update_sample_rate(stream, samplerate * speed, NULL, NULL)); 103 EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_update_sample_rate)(stream, samplerate * speed, NULL, NULL));
103} 104}
104 105
105static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in) 106static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
@@ -111,6 +112,7 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
111 Eina_Bool ret = EINA_FALSE; 112 Eina_Bool ret = EINA_FALSE;
112 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS); 113 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
113 114
115 if (!EPA_LOAD()) return EINA_FALSE;
114 ret = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in); 116 ret = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
115 if (!ret) 117 if (!ret)
116 return EINA_FALSE; 118 return EINA_FALSE;
@@ -123,7 +125,7 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
123 125
124 ss.rate = ss.rate * speed; 126 ss.rate = ss.rate * speed;
125 127
126 stream = pa_stream_new(class_vars.context, name, &ss, NULL); 128 stream = EPA_CALL(pa_stream_new)(class_vars.context, name, &ss, NULL);
127 if (!stream) { 129 if (!stream) {
128 ERR("Could not create stream"); 130 ERR("Could not create stream");
129 ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in); 131 ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
@@ -135,11 +137,11 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
135 eo_key_data_set(in, "pulse_data", stream); 137 eo_key_data_set(in, "pulse_data", stream);
136 138
137 139
138 pa_stream_set_write_callback(stream, _write_cb, in); 140 EPA_CALL(pa_stream_set_write_callback)(stream, _write_cb, in);
139 pa_stream_connect_playback(stream, NULL, NULL, PA_STREAM_VARIABLE_RATE, NULL, NULL); 141 EPA_CALL(pa_stream_connect_playback)(stream, NULL, NULL, PA_STREAM_VARIABLE_RATE, NULL, NULL);
140 142
141 if (ea_obj->paused) 143 if (ea_obj->paused)
142 pa_operation_unref(pa_stream_cork(stream, 1, NULL, NULL)); 144 EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_cork)(stream, 1, NULL, NULL));
143 145
144 return ret; 146 return ret;
145} 147}
@@ -169,8 +171,9 @@ _ecore_audio_out_pulse_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Out_
169 171
170static void _drain_cb(pa_stream *stream, int success EINA_UNUSED, void *data EINA_UNUSED) 172static void _drain_cb(pa_stream *stream, int success EINA_UNUSED, void *data EINA_UNUSED)
171{ 173{
172 pa_stream_disconnect(stream); 174 if (!EPA_LOAD()) return;
173 pa_stream_unref(stream); 175 EPA_CALL(pa_stream_disconnect)(stream);
176 EPA_CALL(pa_stream_unref)(stream);
174} 177}
175 178
176EOLIAN static Eina_Bool 179EOLIAN static Eina_Bool
@@ -180,21 +183,22 @@ _ecore_audio_out_pulse_ecore_audio_out_input_detach(Eo *eo_obj, Ecore_Audio_Out_
180 Eina_Bool ret2 = EINA_FALSE; 183 Eina_Bool ret2 = EINA_FALSE;
181 pa_operation *op; 184 pa_operation *op;
182 185
186 if (!EPA_LOAD()) return EINA_FALSE;
183 ret2 = ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in); 187 ret2 = ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
184 if (!ret2) 188 if (!ret2)
185 return EINA_FALSE; 189 return EINA_FALSE;
186 190
187 stream = eo_key_data_get(in, "pulse_data"); 191 stream = eo_key_data_get(in, "pulse_data");
188 192
189 pa_stream_set_write_callback(stream, NULL, NULL); 193 EPA_CALL(pa_stream_set_write_callback)(stream, NULL, NULL);
190 op = pa_stream_drain(stream, _drain_cb, NULL); 194 op = EPA_CALL(pa_stream_drain) (stream, _drain_cb, NULL);
191 if (!op) 195 if (!op)
192 { 196 {
193 ERR("Failed to drain PulseAudio stream."); 197 ERR("Failed to drain PulseAudio stream.");
194 return EINA_FALSE; 198 return EINA_FALSE;
195 } 199 }
196 200
197 pa_operation_unref(op); 201 EPA_CALL(pa_operation_unref)(op);
198 return EINA_TRUE; 202 return EINA_TRUE;
199} 203}
200 204
@@ -204,7 +208,8 @@ static void _state_cb(pa_context *context, void *data EINA_UNUSED)
204 Eo *eo_obj; 208 Eo *eo_obj;
205 pa_context_state_t state; 209 pa_context_state_t state;
206 210
207 state = pa_context_get_state(context); 211 if (!EPA_LOAD()) return;
212 state = EPA_CALL(pa_context_get_state)(context);
208 class_vars.state = state; 213 class_vars.state = state;
209 214
210 //ref everything in the list to be sure... 215 //ref everything in the list to be sure...
@@ -263,6 +268,7 @@ _ecore_audio_out_pulse_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Dat
263 char **argv; 268 char **argv;
264 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); 269 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
265 270
271 if (!EPA_LOAD()) return NULL;
266 eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS)); 272 eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS));
267 273
268 out_obj->need_writer = EINA_FALSE; 274 out_obj->need_writer = EINA_FALSE;
@@ -271,12 +277,12 @@ _ecore_audio_out_pulse_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Dat
271 ecore_app_args_get(&argc, &argv); 277 ecore_app_args_get(&argc, &argv);
272 if (!argc) { 278 if (!argc) {
273 DBG("Could not get program name, pulse outputs will be named ecore_audio"); 279 DBG("Could not get program name, pulse outputs will be named ecore_audio");
274 class_vars.context = pa_context_new(class_vars.api, "ecore_audio"); 280 class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, "ecore_audio");
275 } else { 281 } else {
276 class_vars.context = pa_context_new(class_vars.api, basename(argv[0])); 282 class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, basename(argv[0]));
277 } 283 }
278 pa_context_set_state_callback(class_vars.context, _state_cb, NULL); 284 EPA_CALL(pa_context_set_state_callback)(class_vars.context, _state_cb, NULL);
279 pa_context_connect(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL); 285 EPA_CALL(pa_context_connect)(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL);
280 } 286 }
281 287
282 class_vars.outputs = eina_list_append(class_vars.outputs, eo_obj); 288 class_vars.outputs = eina_list_append(class_vars.outputs, eo_obj);
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c b/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
index e24cfeb0f7..6143b4b02d 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_sndfile.c
@@ -40,21 +40,22 @@ static Eina_Bool _write_cb(void *data)
40 ssize_t written, bread = 0; 40 ssize_t written, bread = 0;
41 float buf[1024]; 41 float buf[1024];
42 42
43 if (!ESF_LOAD()) return EINA_FALSE;
43 /* TODO: Support mixing of multiple inputs */ 44 /* TODO: Support mixing of multiple inputs */
44 in = eina_list_data_get(out_obj->inputs); 45 in = eina_list_data_get(out_obj->inputs);
45 46
46 bread = ecore_audio_obj_in_read(in, buf, 4*1024); 47 bread = ecore_audio_obj_in_read(in, buf, 4*1024);
47 48
48 if (bread == 0) { 49 if (bread == 0) {
49 sf_write_sync(obj->handle); 50 ESF_CALL(sf_write_sync)(obj->handle);
50 ea_obj->paused = EINA_TRUE; 51 ea_obj->paused = EINA_TRUE;
51 out_obj->write_idler = NULL; 52 out_obj->write_idler = NULL;
52 return EINA_FALSE; 53 return EINA_FALSE;
53 } 54 }
54 written = sf_write_float(obj->handle, buf, bread/4)*4; 55 written = ESF_CALL(sf_write_float)(obj->handle, buf, bread/4)*4;
55 56
56 if (written != bread) 57 if (written != bread)
57 ERR("Short write! (%s)\n", sf_strerror(obj->handle)); 58 ERR("Short write! (%s)\n", ESF_CALL(sf_strerror)(obj->handle));
58 59
59 return EINA_TRUE; 60 return EINA_TRUE;
60} 61}
@@ -66,6 +67,7 @@ _ecore_audio_out_sndfile_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Ou
66 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); 67 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
67 Eina_Bool ret2 = EINA_FALSE; 68 Eina_Bool ret2 = EINA_FALSE;
68 69
70 if (!ESF_LOAD()) return EINA_FALSE;
69 ret2 = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in); 71 ret2 = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
70 if (!ret2) 72 if (!ret2)
71 return EINA_FALSE; 73 return EINA_FALSE;
@@ -73,7 +75,7 @@ _ecore_audio_out_sndfile_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Ou
73 obj->sfinfo.samplerate = ecore_audio_obj_in_samplerate_get(in); 75 obj->sfinfo.samplerate = ecore_audio_obj_in_samplerate_get(in);
74 obj->sfinfo.channels = ecore_audio_obj_in_channels_get(in); 76 obj->sfinfo.channels = ecore_audio_obj_in_channels_get(in);
75 77
76 obj->handle = sf_open(ea_obj->source, SFM_WRITE, &obj->sfinfo); 78 obj->handle = ESF_CALL(sf_open)(ea_obj->source, SFM_WRITE, &obj->sfinfo);
77 79
78 if (!obj->handle) { 80 if (!obj->handle) {
79 eina_stringshare_del(ea_obj->source); 81 eina_stringshare_del(ea_obj->source);
@@ -97,8 +99,9 @@ _ecore_audio_out_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_Out_Sndf
97{ 99{
98 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS); 100 Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
99 101
102 if (!ESF_LOAD()) return EINA_FALSE;
100 if (obj->handle) { 103 if (obj->handle) {
101 sf_close(obj->handle); 104 ESF_CALL(sf_close)(obj->handle);
102 obj->handle = NULL; 105 obj->handle = NULL;
103 } 106 }
104 107
@@ -177,8 +180,9 @@ _ecore_audio_out_sndfile_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Out_Sndfile_
177{ 180{
178 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); 181 Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
179 182
183 if (!ESF_LOAD()) return;
180 if (obj->handle) 184 if (obj->handle)
181 sf_close(obj->handle); 185 ESF_CALL(sf_close)(obj->handle);
182 if (out_obj->write_idler) 186 if (out_obj->write_idler)
183 ecore_idler_del(out_obj->write_idler); 187 ecore_idler_del(out_obj->write_idler);
184 188
diff --git a/src/lib/ecore_audio/ecore_audio_private.h b/src/lib/ecore_audio/ecore_audio_private.h
index 13a7b6ae4c..6cf19a7921 100644
--- a/src/lib/ecore_audio/ecore_audio_private.h
+++ b/src/lib/ecore_audio/ecore_audio_private.h
@@ -144,6 +144,7 @@ struct _Ecore_Audio_Input
144 144
145extern Eina_List *ecore_audio_modules; 145extern Eina_List *ecore_audio_modules;
146 146
147//////////////////////////////////////////////////////////////////////////
147#ifdef HAVE_ALSA 148#ifdef HAVE_ALSA
148/* ecore_audio_alsa */ 149/* ecore_audio_alsa */
149struct _Ecore_Audio_Alsa 150struct _Ecore_Audio_Alsa
@@ -158,26 +159,85 @@ Ecore_Audio_Module *ecore_audio_alsa_init(void);
158void ecore_audio_alsa_shutdown(void); 159void ecore_audio_alsa_shutdown(void);
159#endif /* HAVE_ALSA */ 160#endif /* HAVE_ALSA */
160 161
162//////////////////////////////////////////////////////////////////////////
161#ifdef HAVE_PULSE 163#ifdef HAVE_PULSE
164typedef struct _Ecore_Audio_Lib_Pulse Ecore_Audio_Lib_Pulse;
165
166struct _Ecore_Audio_Lib_Pulse
167{
168 Eina_Module *mod;
169
170 pa_context *(*pa_context_new) (pa_mainloop_api *mainloop, const char *name);
171 int (*pa_context_connect) (pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
172 pa_operation *(*pa_context_set_sink_input_volume) (pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
173 pa_context_state_t (*pa_context_get_state) (pa_context *c);
174 void (*pa_context_set_state_callback) (pa_context *c, pa_context_notify_cb_t cb, void *userdata);
175 void (*pa_operation_unref) (pa_operation *o);
176 pa_cvolume *(*pa_cvolume_set) (pa_cvolume *a, unsigned channels, pa_volume_t v);
177 pa_stream *(*pa_stream_new) (pa_context *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map);
178 void (*pa_stream_unref) (pa_stream *s);
179 int (*pa_stream_connect_playback) (pa_stream *s, const char *dev, const pa_buffer_attr *attr, pa_stream_flags_t flags, const pa_cvolume *volume, pa_stream *sync_stream);
180 int (*pa_stream_disconnect) (pa_stream *s);
181 pa_operation *(*pa_stream_drain) (pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
182 pa_operation *(*pa_stream_cork) (pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
183 int (*pa_stream_write) (pa_stream *p, const void *data, size_t nbytes, pa_free_cb_t free_cb, int64_t offset, pa_seek_mode_t seek);
184 int (*pa_stream_begin_write) (pa_stream *p, void **data, size_t *nbytes);
185 void (*pa_stream_set_write_callback) (pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
186 pa_operation *(*pa_stream_trigger) (pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
187 pa_operation *(*pa_stream_update_sample_rate) (pa_stream *s, uint32_t rate, pa_stream_success_cb_t cb, void *userdata);
188 uint32_t (*pa_stream_get_index) (pa_stream *s);
189};
190
191#define EPA_CALL(x) ecore_audio_pulse_lib->x
192#define EPA_LOAD() ecore_audio_pulse_lib_load()
193
194extern Ecore_Audio_Lib_Pulse *ecore_audio_pulse_lib;
195
196Eina_Bool ecore_audio_pulse_lib_load(void);
197void ecore_audio_pulse_lib_unload(void);
198
199/* These are unused from ecore_audio_pulse.c which isn't used
162Ecore_Audio_Module *ecore_audio_pulse_init(void); 200Ecore_Audio_Module *ecore_audio_pulse_init(void);
163void ecore_audio_pulse_shutdown(void); 201void ecore_audio_pulse_shutdown(void);
202 */
164#endif /* HAVE_PULSE */ 203#endif /* HAVE_PULSE */
165 204
205//////////////////////////////////////////////////////////////////////////
166#ifdef HAVE_SNDFILE 206#ifdef HAVE_SNDFILE
167/* ecore_audio_sndfile */ 207/* ecore_audio_sndfile */
168Ecore_Audio_Module *ecore_audio_sndfile_init(void); 208typedef struct _Ecore_Audio_Lib_Sndfile Ecore_Audio_Lib_Sndfile;
169void ecore_audio_sndfile_shutdown(void); 209
210struct _Ecore_Audio_Lib_Sndfile
211{
212 Eina_Module *mod;
213
214 SNDFILE *(*sf_open) (const char *path, int mode, SF_INFO *sfinfo);
215 SNDFILE *(*sf_open_virtual) (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data);
216 int (*sf_close) (SNDFILE *sndfile);
217 sf_count_t (*sf_read_float) (SNDFILE *sndfile, float *ptr, sf_count_t items);
218 sf_count_t (*sf_write_float) (SNDFILE *sndfile, const float *ptr, sf_count_t items);
219 void (*sf_write_sync) (SNDFILE *sndfile);
220 sf_count_t (*sf_seek) (SNDFILE *sndfile, sf_count_t frames, int whence);
221 const char *(*sf_strerror) (SNDFILE *sndfile);
222};
223
224#define ESF_CALL(x) ecore_audio_sndfile_lib->x
225#define ESF_LOAD() ecore_audio_sndfile_lib_load()
226
227extern Ecore_Audio_Lib_Sndfile *ecore_audio_sndfile_lib;
228
229Eina_Bool ecore_audio_sndfile_lib_load(void);
230void ecore_audio_sndfile_lib_unload(void);
170#endif /* HAVE_SNDFILE */ 231#endif /* HAVE_SNDFILE */
171 232
233//////////////////////////////////////////////////////////////////////////
172#ifdef HAVE_COREAUDIO 234#ifdef HAVE_COREAUDIO
173/* ecore_audio_core_audio */ 235/* ecore_audio_core_audio */
174Ecore_Audio_Module *ecore_audio_core_audio_init(void); 236Ecore_Audio_Module *ecore_audio_core_audio_init(void);
175void ecore_audio_core_audio_shutdown(void); 237void ecore_audio_core_audio_shutdown(void);
176#endif /* HAVE_COREAUDIO */ 238#endif /* HAVE_COREAUDIO */
177 239
178Ecore_Audio_Module *ecore_audio_tone_init(void); 240//////////////////////////////////////////////////////////////////////////
179void ecore_audio_tone_shutdown(void);
180
181Ecore_Audio_Module *ecore_audio_custom_init(void); 241Ecore_Audio_Module *ecore_audio_custom_init(void);
182void ecore_audio_custom_shutdown(void); 242void ecore_audio_custom_shutdown(void);
183 243