1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "offload_effect_api"
18 //#define LOG_NDEBUG 0
19 
20 #include <stdio.h>
21 #include <errno.h>
22 #include <stdbool.h>
23 
24 #include <cutils/log.h>
25 #include <tinyalsa/asoundlib.h>
26 #include <sound/audio_effects.h>
27 
28 #include "effect_api.h"
29 
30 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
31 
32 #define OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL 19
33 const int map_eq_opensl_preset_2_offload_preset[] = {
34     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL,   /* Normal Preset */
35     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+1, /* Classical Preset */
36     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+2, /* Dance Preset */
37     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+3, /* Flat Preset */
38     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+4, /* Folk Preset */
39     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+5, /* Heavy Metal Preset */
40     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+6, /* Hip Hop Preset */
41     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+7, /* Jazz Preset */
42     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+8, /* Pop Preset */
43     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+9, /* Rock Preset */
44     OFFLOAD_PRESET_START_OFFSET_FOR_OPENSL+10 /* FX Booster */
45 };
46 
47 const int map_reverb_opensl_preset_2_offload_preset
48                   [NUM_OSL_REVERB_PRESETS_SUPPORTED][2] = {
49     {1, 15},
50     {2, 16},
51     {3, 17},
52     {4, 18},
53     {5, 3},
54     {6, 20}
55 };
56 
offload_update_mixer_and_effects_ctl(int card,int device_id,struct mixer * mixer,struct mixer_ctl * ctl)57 int offload_update_mixer_and_effects_ctl(int card, int device_id,
58                                          struct mixer *mixer,
59                                          struct mixer_ctl *ctl)
60 {
61     char mixer_string[128];
62 
63     snprintf(mixer_string, sizeof(mixer_string),
64              "%s %d", "Audio Effects Config", device_id);
65     ALOGV("%s: mixer_string: %s", __func__, mixer_string);
66     mixer = mixer_open(card);
67     if (!mixer) {
68         ALOGE("Failed to open mixer");
69         ctl = NULL;
70         return -EINVAL;
71     } else {
72         ctl = mixer_get_ctl_by_name(mixer, mixer_string);
73         if (!ctl) {
74             ALOGE("mixer_get_ctl_by_name failed");
75             mixer_close(mixer);
76             mixer = NULL;
77             return -EINVAL;
78         }
79     }
80     ALOGV("mixer: %p, ctl: %p", mixer, ctl);
81     return 0;
82 }
83 
offload_close_mixer(struct mixer * mixer)84 void offload_close_mixer(struct mixer *mixer)
85 {
86     mixer_close(mixer);
87 }
88 
offload_bassboost_set_device(struct bass_boost_params * bassboost,uint32_t device)89 void offload_bassboost_set_device(struct bass_boost_params *bassboost,
90                                   uint32_t device)
91 {
92     ALOGV("%s", __func__);
93     bassboost->device = device;
94 }
95 
offload_bassboost_set_enable_flag(struct bass_boost_params * bassboost,bool enable)96 void offload_bassboost_set_enable_flag(struct bass_boost_params *bassboost,
97                                        bool enable)
98 {
99     ALOGV("%s", __func__);
100     bassboost->enable_flag = enable;
101 }
102 
offload_bassboost_get_enable_flag(struct bass_boost_params * bassboost)103 int offload_bassboost_get_enable_flag(struct bass_boost_params *bassboost)
104 {
105     ALOGV("%s", __func__);
106     return bassboost->enable_flag;
107 }
108 
offload_bassboost_set_strength(struct bass_boost_params * bassboost,int strength)109 void offload_bassboost_set_strength(struct bass_boost_params *bassboost,
110                                     int strength)
111 {
112     ALOGV("%s", __func__);
113     bassboost->strength = strength;
114 }
115 
offload_bassboost_set_mode(struct bass_boost_params * bassboost,int mode)116 void offload_bassboost_set_mode(struct bass_boost_params *bassboost,
117                                 int mode)
118 {
119     ALOGV("%s", __func__);
120     bassboost->mode = mode;
121 }
122 
offload_bassboost_send_params(struct mixer_ctl * ctl,struct bass_boost_params * bassboost,unsigned param_send_flags)123 int offload_bassboost_send_params(struct mixer_ctl *ctl,
124                                   struct bass_boost_params *bassboost,
125                                   unsigned param_send_flags)
126 {
127     int param_values[128] = {0};
128     int *p_param_values = param_values;
129 
130     ALOGV("%s", __func__);
131     *p_param_values++ = BASS_BOOST_MODULE;
132     *p_param_values++ = bassboost->device;
133     *p_param_values++ = 0; /* num of commands*/
134     if (param_send_flags & OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG) {
135         *p_param_values++ = BASS_BOOST_ENABLE;
136         *p_param_values++ = CONFIG_SET;
137         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
138         *p_param_values++ = BASS_BOOST_ENABLE_PARAM_LEN;
139         *p_param_values++ = bassboost->enable_flag;
140         param_values[2] += 1;
141     }
142     if (param_send_flags & OFFLOAD_SEND_BASSBOOST_STRENGTH) {
143         *p_param_values++ = BASS_BOOST_STRENGTH;
144         *p_param_values++ = CONFIG_SET;
145         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
146         *p_param_values++ = BASS_BOOST_STRENGTH_PARAM_LEN;
147         *p_param_values++ = bassboost->strength;
148         param_values[2] += 1;
149     }
150     if (param_send_flags & OFFLOAD_SEND_BASSBOOST_MODE) {
151         *p_param_values++ = BASS_BOOST_MODE;
152         *p_param_values++ = CONFIG_SET;
153         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
154         *p_param_values++ = BASS_BOOST_MODE_PARAM_LEN;
155         *p_param_values++ = bassboost->mode;
156         param_values[2] += 1;
157     }
158 
159     if (param_values[2] && ctl)
160         mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
161 
162     return 0;
163 }
164 
offload_virtualizer_set_device(struct virtualizer_params * virtualizer,uint32_t device)165 void offload_virtualizer_set_device(struct virtualizer_params *virtualizer,
166                                     uint32_t device)
167 {
168     ALOGV("%s", __func__);
169     virtualizer->device = device;
170 }
171 
offload_virtualizer_set_enable_flag(struct virtualizer_params * virtualizer,bool enable)172 void offload_virtualizer_set_enable_flag(struct virtualizer_params *virtualizer,
173                                          bool enable)
174 {
175     ALOGV("%s", __func__);
176     virtualizer->enable_flag = enable;
177 }
178 
offload_virtualizer_get_enable_flag(struct virtualizer_params * virtualizer)179 int offload_virtualizer_get_enable_flag(struct virtualizer_params *virtualizer)
180 {
181     ALOGV("%s", __func__);
182     return virtualizer->enable_flag;
183 }
184 
offload_virtualizer_set_strength(struct virtualizer_params * virtualizer,int strength)185 void offload_virtualizer_set_strength(struct virtualizer_params *virtualizer,
186                                       int strength)
187 {
188     ALOGV("%s", __func__);
189     virtualizer->strength = strength;
190 }
191 
offload_virtualizer_set_out_type(struct virtualizer_params * virtualizer,int out_type)192 void offload_virtualizer_set_out_type(struct virtualizer_params *virtualizer,
193                                       int out_type)
194 {
195     ALOGV("%s", __func__);
196     virtualizer->out_type = out_type;
197 }
198 
offload_virtualizer_set_gain_adjust(struct virtualizer_params * virtualizer,int gain_adjust)199 void offload_virtualizer_set_gain_adjust(struct virtualizer_params *virtualizer,
200                                          int gain_adjust)
201 {
202     ALOGV("%s", __func__);
203     virtualizer->gain_adjust = gain_adjust;
204 }
205 
offload_virtualizer_send_params(struct mixer_ctl * ctl,struct virtualizer_params * virtualizer,unsigned param_send_flags)206 int offload_virtualizer_send_params(struct mixer_ctl *ctl,
207                                     struct virtualizer_params *virtualizer,
208                                     unsigned param_send_flags)
209 {
210     int param_values[128] = {0};
211     int *p_param_values = param_values;
212 
213     ALOGV("%s", __func__);
214     *p_param_values++ = VIRTUALIZER_MODULE;
215     *p_param_values++ = virtualizer->device;
216     *p_param_values++ = 0; /* num of commands*/
217     if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG) {
218         *p_param_values++ = VIRTUALIZER_ENABLE;
219         *p_param_values++ = CONFIG_SET;
220         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
221         *p_param_values++ = VIRTUALIZER_ENABLE_PARAM_LEN;
222         *p_param_values++ = virtualizer->enable_flag;
223         param_values[2] += 1;
224     }
225     if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_STRENGTH) {
226         *p_param_values++ = VIRTUALIZER_STRENGTH;
227         *p_param_values++ = CONFIG_SET;
228         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
229         *p_param_values++ = VIRTUALIZER_STRENGTH_PARAM_LEN;
230         *p_param_values++ = virtualizer->strength;
231         param_values[2] += 1;
232     }
233     if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_OUT_TYPE) {
234         *p_param_values++ = VIRTUALIZER_OUT_TYPE;
235         *p_param_values++ = CONFIG_SET;
236         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
237         *p_param_values++ = VIRTUALIZER_OUT_TYPE_PARAM_LEN;
238         *p_param_values++ = virtualizer->out_type;
239         param_values[2] += 1;
240     }
241     if (param_send_flags & OFFLOAD_SEND_VIRTUALIZER_GAIN_ADJUST) {
242         *p_param_values++ = VIRTUALIZER_GAIN_ADJUST;
243         *p_param_values++ = CONFIG_SET;
244         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
245         *p_param_values++ = VIRTUALIZER_GAIN_ADJUST_PARAM_LEN;
246         *p_param_values++ = virtualizer->gain_adjust;
247         param_values[2] += 1;
248     }
249 
250     if (param_values[2] && ctl)
251         mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
252 
253     return 0;
254 }
255 
offload_eq_set_device(struct eq_params * eq,uint32_t device)256 void offload_eq_set_device(struct eq_params *eq, uint32_t device)
257 {
258     ALOGV("%s", __func__);
259     eq->device = device;
260 }
261 
offload_eq_set_enable_flag(struct eq_params * eq,bool enable)262 void offload_eq_set_enable_flag(struct eq_params *eq, bool enable)
263 {
264     ALOGV("%s", __func__);
265     eq->enable_flag = enable;
266 }
267 
offload_eq_get_enable_flag(struct eq_params * eq)268 int offload_eq_get_enable_flag(struct eq_params *eq)
269 {
270     ALOGV("%s", __func__);
271     return eq->enable_flag;
272 }
273 
offload_eq_set_preset(struct eq_params * eq,int preset)274 void offload_eq_set_preset(struct eq_params *eq, int preset)
275 {
276     ALOGV("%s", __func__);
277     eq->config.preset_id = preset;
278     eq->config.eq_pregain = Q27_UNITY;
279 }
280 
offload_eq_set_bands_level(struct eq_params * eq,int num_bands,const uint16_t * band_freq_list,int * band_gain_list)281 void offload_eq_set_bands_level(struct eq_params *eq, int num_bands,
282                                 const uint16_t *band_freq_list,
283                                 int *band_gain_list)
284 {
285     int i;
286     ALOGV("%s", __func__);
287     eq->config.num_bands = num_bands;
288     for (i=0; i<num_bands; i++) {
289         eq->per_band_cfg[i].band_idx = i;
290         eq->per_band_cfg[i].filter_type = EQ_BAND_BOOST;
291         eq->per_band_cfg[i].freq_millihertz = band_freq_list[i] * 1000;
292         eq->per_band_cfg[i].gain_millibels = band_gain_list[i] * 100;
293         eq->per_band_cfg[i].quality_factor = Q8_UNITY;
294     }
295 }
296 
offload_eq_send_params(struct mixer_ctl * ctl,struct eq_params * eq,unsigned param_send_flags)297 int offload_eq_send_params(struct mixer_ctl *ctl, struct eq_params *eq,
298                            unsigned param_send_flags)
299 {
300     int param_values[128] = {0};
301     int *p_param_values = param_values;
302     uint32_t i;
303 
304     ALOGV("%s", __func__);
305     if (eq->config.preset_id < -1 ) {
306         ALOGV("No Valid preset to set");
307         return 0;
308     }
309     *p_param_values++ = EQ_MODULE;
310     *p_param_values++ = eq->device;
311     *p_param_values++ = 0; /* num of commands*/
312     if (param_send_flags & OFFLOAD_SEND_EQ_ENABLE_FLAG) {
313         *p_param_values++ = EQ_ENABLE;
314         *p_param_values++ = CONFIG_SET;
315         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
316         *p_param_values++ = EQ_ENABLE_PARAM_LEN;
317         *p_param_values++ = eq->enable_flag;
318         param_values[2] += 1;
319     }
320     if (param_send_flags & OFFLOAD_SEND_EQ_PRESET) {
321         *p_param_values++ = EQ_CONFIG;
322         *p_param_values++ = CONFIG_SET;
323         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
324         *p_param_values++ = EQ_CONFIG_PARAM_LEN;
325         *p_param_values++ = eq->config.eq_pregain;
326         *p_param_values++ =
327                      map_eq_opensl_preset_2_offload_preset[eq->config.preset_id];
328         *p_param_values++ = 0;
329         param_values[2] += 1;
330     }
331     if (param_send_flags & OFFLOAD_SEND_EQ_BANDS_LEVEL) {
332         *p_param_values++ = EQ_CONFIG;
333         *p_param_values++ = CONFIG_SET;
334         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
335         *p_param_values++ = EQ_CONFIG_PARAM_LEN +
336                             eq->config.num_bands * EQ_CONFIG_PER_BAND_PARAM_LEN;
337         *p_param_values++ = eq->config.eq_pregain;
338         *p_param_values++ = CUSTOM_OPENSL_PRESET;
339         *p_param_values++ = eq->config.num_bands;
340         for (i=0; i<eq->config.num_bands; i++) {
341             *p_param_values++ = eq->per_band_cfg[i].band_idx;
342             *p_param_values++ = eq->per_band_cfg[i].filter_type;
343 	    *p_param_values++ = eq->per_band_cfg[i].freq_millihertz;
344             *p_param_values++ = eq->per_band_cfg[i].gain_millibels;
345             *p_param_values++ = eq->per_band_cfg[i].quality_factor;
346         }
347         param_values[2] += 1;
348     }
349 
350     if (param_values[2] && ctl)
351         mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
352 
353     return 0;
354 }
355 
offload_reverb_set_device(struct reverb_params * reverb,uint32_t device)356 void offload_reverb_set_device(struct reverb_params *reverb, uint32_t device)
357 {
358     ALOGV("%s", __func__);
359     reverb->device = device;
360 }
361 
offload_reverb_set_enable_flag(struct reverb_params * reverb,bool enable)362 void offload_reverb_set_enable_flag(struct reverb_params *reverb, bool enable)
363 {
364     ALOGV("%s", __func__);
365     reverb->enable_flag = enable;
366 }
367 
offload_reverb_get_enable_flag(struct reverb_params * reverb)368 int offload_reverb_get_enable_flag(struct reverb_params *reverb)
369 {
370     ALOGV("%s", __func__);
371     return reverb->enable_flag;
372 }
373 
offload_reverb_set_mode(struct reverb_params * reverb,int mode)374 void offload_reverb_set_mode(struct reverb_params *reverb, int mode)
375 {
376     ALOGV("%s", __func__);
377     reverb->mode = mode;
378 }
379 
offload_reverb_set_preset(struct reverb_params * reverb,int preset)380 void offload_reverb_set_preset(struct reverb_params *reverb, int preset)
381 {
382     ALOGV("%s", __func__);
383     if (preset && (preset <= NUM_OSL_REVERB_PRESETS_SUPPORTED))
384         reverb->preset = map_reverb_opensl_preset_2_offload_preset[preset-1][1];
385 }
386 
offload_reverb_set_wet_mix(struct reverb_params * reverb,int wet_mix)387 void offload_reverb_set_wet_mix(struct reverb_params *reverb, int wet_mix)
388 {
389     ALOGV("%s", __func__);
390     reverb->wet_mix = wet_mix;
391 }
392 
offload_reverb_set_gain_adjust(struct reverb_params * reverb,int gain_adjust)393 void offload_reverb_set_gain_adjust(struct reverb_params *reverb,
394                                     int gain_adjust)
395 {
396     ALOGV("%s", __func__);
397     reverb->gain_adjust = gain_adjust;
398 }
399 
offload_reverb_set_room_level(struct reverb_params * reverb,int room_level)400 void offload_reverb_set_room_level(struct reverb_params *reverb, int room_level)
401 {
402     ALOGV("%s", __func__);
403     reverb->room_level = room_level;
404 }
405 
offload_reverb_set_room_hf_level(struct reverb_params * reverb,int room_hf_level)406 void offload_reverb_set_room_hf_level(struct reverb_params *reverb,
407                                       int room_hf_level)
408 {
409     ALOGV("%s", __func__);
410     reverb->room_hf_level = room_hf_level;
411 }
412 
offload_reverb_set_decay_time(struct reverb_params * reverb,int decay_time)413 void offload_reverb_set_decay_time(struct reverb_params *reverb, int decay_time)
414 {
415     ALOGV("%s", __func__);
416     reverb->decay_time = decay_time;
417 }
418 
offload_reverb_set_decay_hf_ratio(struct reverb_params * reverb,int decay_hf_ratio)419 void offload_reverb_set_decay_hf_ratio(struct reverb_params *reverb,
420                                        int decay_hf_ratio)
421 {
422     ALOGV("%s", __func__);
423     reverb->decay_hf_ratio = decay_hf_ratio;
424 }
425 
offload_reverb_set_reflections_level(struct reverb_params * reverb,int reflections_level)426 void offload_reverb_set_reflections_level(struct reverb_params *reverb,
427                                           int reflections_level)
428 {
429     ALOGV("%s", __func__);
430     reverb->reflections_level = reflections_level;
431 }
432 
offload_reverb_set_reflections_delay(struct reverb_params * reverb,int reflections_delay)433 void offload_reverb_set_reflections_delay(struct reverb_params *reverb,
434                                           int reflections_delay)
435 {
436     ALOGV("%s", __func__);
437     reverb->reflections_delay = reflections_delay;
438 }
439 
offload_reverb_set_reverb_level(struct reverb_params * reverb,int reverb_level)440 void offload_reverb_set_reverb_level(struct reverb_params *reverb,
441                                      int reverb_level)
442 {
443     ALOGV("%s", __func__);
444     reverb->level = reverb_level;
445 }
446 
offload_reverb_set_delay(struct reverb_params * reverb,int delay)447 void offload_reverb_set_delay(struct reverb_params *reverb, int delay)
448 {
449     ALOGV("%s", __func__);
450     reverb->delay = delay;
451 }
452 
offload_reverb_set_diffusion(struct reverb_params * reverb,int diffusion)453 void offload_reverb_set_diffusion(struct reverb_params *reverb, int diffusion)
454 {
455     ALOGV("%s", __func__);
456     reverb->diffusion = diffusion;
457 }
458 
offload_reverb_set_density(struct reverb_params * reverb,int density)459 void offload_reverb_set_density(struct reverb_params *reverb, int density)
460 {
461     ALOGV("%s", __func__);
462     reverb->density = density;
463 }
464 
offload_reverb_send_params(struct mixer_ctl * ctl,struct reverb_params * reverb,unsigned param_send_flags)465 int offload_reverb_send_params(struct mixer_ctl *ctl,
466                                struct reverb_params *reverb,
467                                unsigned param_send_flags)
468 {
469     int param_values[128] = {0};
470     int *p_param_values = param_values;
471 
472     ALOGV("%s", __func__);
473     *p_param_values++ = REVERB_MODULE;
474     *p_param_values++ = reverb->device;
475     *p_param_values++ = 0; /* num of commands*/
476 
477     if (param_send_flags & OFFLOAD_SEND_REVERB_ENABLE_FLAG) {
478         *p_param_values++ = REVERB_ENABLE;
479         *p_param_values++ = CONFIG_SET;
480         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
481         *p_param_values++ = REVERB_ENABLE_PARAM_LEN;
482         *p_param_values++ = reverb->enable_flag;
483         param_values[2] += 1;
484     }
485     if (param_send_flags & OFFLOAD_SEND_REVERB_MODE) {
486         *p_param_values++ = REVERB_MODE;
487         *p_param_values++ = CONFIG_SET;
488         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
489         *p_param_values++ = REVERB_MODE_PARAM_LEN;
490         *p_param_values++ = reverb->mode;
491         param_values[2] += 1;
492     }
493     if (param_send_flags & OFFLOAD_SEND_REVERB_PRESET) {
494         *p_param_values++ = REVERB_PRESET;
495         *p_param_values++ = CONFIG_SET;
496         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
497         *p_param_values++ = REVERB_PRESET_PARAM_LEN;
498         *p_param_values++ = reverb->preset;
499         param_values[2] += 1;
500     }
501     if (param_send_flags & OFFLOAD_SEND_REVERB_WET_MIX) {
502         *p_param_values++ = REVERB_WET_MIX;
503         *p_param_values++ = CONFIG_SET;
504         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
505         *p_param_values++ = REVERB_WET_MIX_PARAM_LEN;
506         *p_param_values++ = reverb->wet_mix;
507         param_values[2] += 1;
508     }
509     if (param_send_flags & OFFLOAD_SEND_REVERB_GAIN_ADJUST) {
510         *p_param_values++ = REVERB_GAIN_ADJUST;
511         *p_param_values++ = CONFIG_SET;
512         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
513         *p_param_values++ = REVERB_GAIN_ADJUST_PARAM_LEN;
514         *p_param_values++ = reverb->gain_adjust;
515         param_values[2] += 1;
516     }
517     if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_LEVEL) {
518         *p_param_values++ = REVERB_ROOM_LEVEL;
519         *p_param_values++ = CONFIG_SET;
520         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
521         *p_param_values++ = REVERB_ROOM_LEVEL_PARAM_LEN;
522         *p_param_values++ = reverb->room_level;
523         param_values[2] += 1;
524     }
525     if (param_send_flags & OFFLOAD_SEND_REVERB_ROOM_HF_LEVEL) {
526         *p_param_values++ = REVERB_ROOM_HF_LEVEL;
527         *p_param_values++ = CONFIG_SET;
528         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
529         *p_param_values++ = REVERB_ROOM_HF_LEVEL_PARAM_LEN;
530         *p_param_values++ = reverb->room_hf_level;
531         param_values[2] += 1;
532     }
533     if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_TIME) {
534         *p_param_values++ = REVERB_DECAY_TIME;
535         *p_param_values++ = CONFIG_SET;
536         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
537         *p_param_values++ = REVERB_DECAY_TIME_PARAM_LEN;
538         *p_param_values++ = reverb->decay_time;
539         param_values[2] += 1;
540     }
541     if (param_send_flags & OFFLOAD_SEND_REVERB_DECAY_HF_RATIO) {
542         *p_param_values++ = REVERB_DECAY_HF_RATIO;
543         *p_param_values++ = CONFIG_SET;
544         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
545         *p_param_values++ = REVERB_DECAY_HF_RATIO_PARAM_LEN;
546         *p_param_values++ = reverb->decay_hf_ratio;
547         param_values[2] += 1;
548     }
549     if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL) {
550         *p_param_values++ = REVERB_REFLECTIONS_LEVEL;
551         *p_param_values++ = CONFIG_SET;
552         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
553         *p_param_values++ = REVERB_REFLECTIONS_LEVEL_PARAM_LEN;
554         *p_param_values++ = reverb->reflections_level;
555         param_values[2] += 1;
556     }
557     if (param_send_flags & OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY) {
558         *p_param_values++ = REVERB_REFLECTIONS_DELAY;
559         *p_param_values++ = CONFIG_SET;
560         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
561         *p_param_values++ = REVERB_REFLECTIONS_DELAY_PARAM_LEN;
562         *p_param_values++ = reverb->reflections_delay;
563         param_values[2] += 1;
564     }
565     if (param_send_flags & OFFLOAD_SEND_REVERB_LEVEL) {
566         *p_param_values++ = REVERB_LEVEL;
567         *p_param_values++ = CONFIG_SET;
568         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
569         *p_param_values++ = REVERB_LEVEL_PARAM_LEN;
570         *p_param_values++ = reverb->level;
571         param_values[2] += 1;
572     }
573     if (param_send_flags & OFFLOAD_SEND_REVERB_DELAY) {
574         *p_param_values++ = REVERB_DELAY;
575         *p_param_values++ = CONFIG_SET;
576         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
577         *p_param_values++ = REVERB_DELAY_PARAM_LEN;
578         *p_param_values++ = reverb->delay;
579         param_values[2] += 1;
580     }
581     if (param_send_flags & OFFLOAD_SEND_REVERB_DIFFUSION) {
582         *p_param_values++ = REVERB_DIFFUSION;
583         *p_param_values++ = CONFIG_SET;
584         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
585         *p_param_values++ = REVERB_DIFFUSION_PARAM_LEN;
586         *p_param_values++ = reverb->diffusion;
587         param_values[2] += 1;
588     }
589     if (param_send_flags & OFFLOAD_SEND_REVERB_DENSITY) {
590         *p_param_values++ = REVERB_DENSITY;
591         *p_param_values++ = CONFIG_SET;
592         *p_param_values++ = 0; /* start offset if param size if greater than 128  */
593         *p_param_values++ = REVERB_DENSITY_PARAM_LEN;
594         *p_param_values++ = reverb->density;
595         param_values[2] += 1;
596     }
597 
598     if (param_values[2] && ctl)
599         mixer_ctl_set_array(ctl, param_values, ARRAY_SIZE(param_values));
600 
601     return 0;
602 }
603